diff options
author | midipix <writeonce@midipix.org> | 2017-12-20 08:48:52 -0500 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2017-12-20 08:48:52 -0500 |
commit | c6d4dc08937e72b8f2626c47686b4ef93fb526a2 (patch) | |
tree | 0b06cebe2fbae253d1dfdc2a7ecaf2d7fcc7ca67 /src/logic/slbt_exec_link.c | |
parent | 1cecd7cc09807fadf3c6dc1af4d1e67fa9844f77 (diff) | |
download | slibtool-c6d4dc08937e72b8f2626c47686b4ef93fb526a2.tar.bz2 slibtool-c6d4dc08937e72b8f2626c47686b4ef93fb526a2.tar.xz |
link mode: re-implemented slbt_exec_link_finalize_argument_vector().
The above internal interface is now doing the right thing, namely to
split the argument vector between object arguments and all other arguments,
then rejoin the arguments by placing object arguments first, and all other
arguments last.
Diffstat (limited to 'src/logic/slbt_exec_link.c')
-rw-r--r-- | src/logic/slbt_exec_link.c | 171 |
1 files changed, 77 insertions, 94 deletions
diff --git a/src/logic/slbt_exec_link.c b/src/logic/slbt_exec_link.c index 2c7beb1..9839622 100644 --- a/src/logic/slbt_exec_link.c +++ b/src/logic/slbt_exec_link.c @@ -490,125 +490,108 @@ static int slbt_exec_link_finalize_argument_vector( { char * sargv[1024]; char ** sargvbuf; - char ** largv; - char ** parg; char ** base; + char ** parg; + char ** aarg; + char ** oarg; + char ** aargv; + char ** oargv; + char ** cap; + char ** src; + char ** dst; char * arg; char * dot; - char ** dst; - char ** mark; - char ** cap; - int flast; - int fwhole; - size_t argc; - size_t first; - size_t last; - size_t objidx; - - base = ectx->argv; - first = 0; - last = 0; - objidx = 0; - - for (parg=ectx->argv; *parg; parg++) { - arg = *parg; - flast = false; - fwhole = false; - - if ((arg[0] == '-') && (arg[1] == 'l')) - flast = true; - - else if ((arg[0] == '-') && (arg[1] == 'L')) - flast = true; - - else if ((dot = strrchr(arg,'.'))) - flast = !strcmp(dot,dctx->cctx->settings.arsuffix) - || !strcmp(dot,dctx->cctx->settings.dsosuffix) - || !strcmp(dot,dctx->cctx->settings.impsuffix); - - else if ((arg[0] == '-') - && (arg[1] == 'W') - && (arg[2] == 'l') - && (arg[3] == ',')) - fwhole = (!strcmp(&arg[4],"--whole-archive")) - && parg[1] && parg[2] - && !strcmp(parg[2],"-Wl,--no-whole-archive") - && (dot = strrchr(parg[1],'.')) - && !strcmp(dot,dctx->cctx->settings.arsuffix); - - - if (fwhole) { - parg = &parg[2]; - flast = true; - objidx = parg - base; - } - - - if (flast) { - last = parg - base; - first = first ? first : last; - - } else if (objidx) { - (void)0; + const char * arsuffix; - } else if (dot && (!strcmp(dot,".o") || !strcmp(dot,".lo"))) { - objidx = parg - base; - } - } + /* vector size */ + base = ectx->argv; + arsuffix = dctx->cctx->settings.arsuffix; - /* have faith? */ - if (!first || (objidx < first)) - return 0; + for (parg=base; *parg; parg++) + (void)0; /* buffer */ - if (last - first + 1 <= 1024) { - largv = sargv; + if (parg - base < 512) { + aargv = &sargv[0]; + oargv = &sargv[512]; + aarg = aargv; + oarg = oargv; sargvbuf = 0; - } else if (!(sargvbuf = calloc(1,(last - first) * sizeof(char *)))) { + } else if (!(sargvbuf = calloc(2*(parg-base+1),sizeof(char *)))) { return SLBT_SYSTEM_ERROR(dctx); } else { - largv = sargvbuf; + aargv = &sargvbuf[0]; + oargv = &sargvbuf[parg-base+1]; + aarg = aargv; + oarg = oargv; } - /* bulk-move dependency arguments to the end */ - if ((base[last][1] == 'l') && !base[last][2]) - last++; + /* (program name) */ + parg = &base[1]; + + /* split object args from all other args, record output annotation */ + for (; *parg; ) { + if (ectx->lout[0] == parg) { + ectx->lout[0] = &aarg[0]; + ectx->lout[1] = &aarg[1]; + } + + if (ectx->mout[0] == parg) { + ectx->lout[0] = &aarg[0]; + ectx->lout[1] = &aarg[1]; + } + + arg = *parg; + dot = strrchr(arg,'.'); - else if ((base[last][1] == 'L') && !base[last][2]) - last++; + if (dot && (!strcmp(dot,".o") || !strcmp(dot,".lo"))) { + *oarg++ = *parg++; - argc = parg - base; - mark = &base[first]; - cap = &base[last + 1]; + } else if ((arg[0] == '-') + && (arg[1] == 'W') + && (arg[2] == 'l') + && (arg[3] == ',') + && !strcmp(&arg[4],"--whole-archive") + && parg[1] && parg[2] + && !strcmp(parg[2],"-Wl,--no-whole-archive") + && (dot = strrchr(parg[1],'.')) + && !strcmp(dot,arsuffix)) { + *oarg++ = *parg++; + *oarg++ = *parg++; + *oarg++ = *parg++; + } else { + *aarg++ = *parg++; + } + } - for (parg=mark, dst=largv; parg<cap; parg++, dst++) - *dst = *parg; + /* (program name) */ + dst = &base[1]; - mark = &base[last + 1]; - cap = &base[argc]; - dst = &base[first]; + /* join object args */ + src = oargv; + cap = oarg; - for (parg=mark; parg<cap; parg++, dst++) - *dst = *parg; + for (; src<cap; ) + *dst++ = *src++; - mark = largv; - cap = &largv[last - first + 1]; - dst = &base[argc - (last - first + 1)]; + /* join all other args */ + src = aargv; + cap = aarg; - for (parg=mark; parg<cap; parg++, dst++) - *dst = *parg; + for (; src<cap; ) + *dst++ = *src++; /* output annotation */ - if ((ectx->lout[0] > &base[last]) && (ectx->lout[0] < &base[argc])) { - ectx->lout[0] -= (last - first + 1); - ectx->lout[1] -= (last - first + 1); + if (ectx->lout[0]) { + ectx->lout[0] = &base[1] + (oarg - oargv) + (ectx->lout[0] - aargv); + ectx->lout[1] = ectx->lout[0] + 1; } - if ((ectx->mout[0] > &base[last]) && (ectx->lout[0] < &base[argc])) { - ectx->mout[0] -= (last - first + 1); - ectx->mout[1] -= (last - first + 1); + if (ectx->mout[0]) { + ectx->mout[0] = &base[1] + (oarg - oargv) + (ectx->mout[0] - aargv); + ectx->mout[1] = ectx->mout[0] + 1; } /* all done */ |