From c6d4dc08937e72b8f2626c47686b4ef93fb526a2 Mon Sep 17 00:00:00 2001 From: midipix Date: Wed, 20 Dec 2017 08:48:52 -0500 Subject: 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. --- src/logic/slbt_exec_link.c | 171 ++++++++++++++++++++------------------------- 1 file 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; parglout[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 */ -- cgit v1.2.3