summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-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 */