summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2017-12-20 08:48:52 -0500
committermidipix <writeonce@midipix.org>2017-12-20 08:48:52 -0500
commitc6d4dc08937e72b8f2626c47686b4ef93fb526a2 (patch)
tree0b06cebe2fbae253d1dfdc2a7ecaf2d7fcc7ca67
parent1cecd7cc09807fadf3c6dc1af4d1e67fa9844f77 (diff)
downloadslibtool-c6d4dc0893.tar.bz2
slibtool-c6d4dc0893.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.
-rw-r--r--src/logic/slbt_exec_link.c171
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 */