summaryrefslogtreecommitdiff
path: root/src/logic/slbt_exec_link.c
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2024-02-10 03:49:05 +0000
committermidipix <writeonce@midipix.org>2024-02-10 04:33:07 +0000
commit3d55672811ed7f35d226ab714a5bd812729eb48b (patch)
tree53adb8e73066ae63c2a0a0b1259f239ae44eb283 /src/logic/slbt_exec_link.c
parentb080541d62820dd8bf73b37355d52b06095cc617 (diff)
downloadslibtool-3d55672811ed7f35d226ab714a5bd812729eb48b.tar.bz2
slibtool-3d55672811ed7f35d226ab714a5bd812729eb48b.tar.xz
link mode: move the argument vector logic to its own translation unit.
Diffstat (limited to 'src/logic/slbt_exec_link.c')
-rw-r--r--src/logic/slbt_exec_link.c695
1 files changed, 0 insertions, 695 deletions
diff --git a/src/logic/slbt_exec_link.c b/src/logic/slbt_exec_link.c
index cacbe44..c21af58 100644
--- a/src/logic/slbt_exec_link.c
+++ b/src/logic/slbt_exec_link.c
@@ -77,234 +77,6 @@ static int slbt_exec_link_exit(
return ret;
}
-static bool slbt_adjust_object_argument(
- char * arg,
- bool fpic,
- bool fany,
- int fdcwd)
-{
- char * slash;
- char * dot;
- char base[PATH_MAX];
-
- if (*arg == '-')
- return false;
-
- /* object argument: foo.lo or foo.o */
- if (!(dot = strrchr(arg,'.')))
- return false;
-
- if ((dot[1]=='l') && (dot[2]=='o') && !dot[3]) {
- dot[1] = 'o';
- dot[2] = 0;
-
- } else if ((dot[1]=='o') && !dot[2]) {
- (void)0;
-
- } else {
- return false;
- }
-
- /* foo.o requested and is present? */
- if (!fpic && !faccessat(fdcwd,arg,0,0))
- return true;
-
- /* .libs/foo.o */
- if ((slash = strrchr(arg,'/')))
- slash++;
- else
- slash = arg;
-
- if (slbt_snprintf(base,sizeof(base),
- "%s",slash) < 0)
- return false;
-
- sprintf(slash,".libs/%s",base);
-
- if (!faccessat(fdcwd,arg,0,0))
- return true;
-
- /* foo.o requested and neither is present? */
- if (!fpic) {
- strcpy(slash,base);
- return true;
- }
-
- /* .libs/foo.o explicitly requested and is not present? */
- if (!fany)
- return true;
-
- /* use foo.o in place of .libs/foo.o */
- strcpy(slash,base);
-
- if (faccessat(fdcwd,arg,0,0))
- sprintf(slash,".libs/%s",base);
-
- return true;
-}
-
-static bool slbt_adjust_wrapper_argument(
- char * arg,
- bool fpic)
-{
- char * slash;
- char * dot;
- char base[PATH_MAX];
-
- if (*arg == '-')
- return false;
-
- if (!(dot = strrchr(arg,'.')))
- return false;
-
- if (strcmp(dot,".la"))
- return false;
-
- if (fpic) {
- if ((slash = strrchr(arg,'/')))
- slash++;
- else
- slash = arg;
-
- if (slbt_snprintf(base,sizeof(base),
- "%s",slash) < 0)
- return false;
-
- sprintf(slash,".libs/%s",base);
- dot = strrchr(arg,'.');
- }
-
- strcpy(dot,".a");
- return true;
-}
-
-static int slbt_adjust_linker_argument(
- const struct slbt_driver_ctx * dctx,
- char * arg,
- char ** xarg,
- bool fpic,
- const char * dsosuffix,
- const char * arsuffix,
- struct slbt_deps_meta * depsmeta)
-{
- int fdcwd;
- int fdlib;
- char * slash;
- char * dot;
- char base[PATH_MAX];
-
- if (*arg == '-')
- return 0;
-
- if (!(dot = strrchr(arg,'.')))
- return 0;
-
- if (!(strcmp(dot,arsuffix))) {
- *xarg = arg;
- return slbt_get_deps_meta(dctx,arg,1,depsmeta);
- }
-
- if (!(strcmp(dot,dsosuffix)))
- return slbt_get_deps_meta(dctx,arg,1,depsmeta);
-
- if (strcmp(dot,".la"))
- return 0;
-
- if (fpic) {
- if ((slash = strrchr(arg,'/')))
- slash++;
- else
- slash = arg;
-
- if (slbt_snprintf(base,sizeof(base),
- "%s",slash) < 0)
- return 0;
-
- sprintf(slash,".libs/%s",base);
- dot = strrchr(arg,'.');
- }
-
- /* fdcwd */
- fdcwd = slbt_driver_fdcwd(dctx);
-
- /* shared library dependency? */
- if (fpic) {
- sprintf(dot,"%s",dsosuffix);
-
- if (slbt_symlink_is_a_placeholder(fdcwd,arg))
- sprintf(dot,"%s",arsuffix);
- else if ((fdlib = openat(fdcwd,arg,O_RDONLY)) >= 0)
- close(fdlib);
- else
- sprintf(dot,"%s",arsuffix);
-
- return slbt_get_deps_meta(dctx,arg,0,depsmeta);
- }
-
- /* input archive */
- sprintf(dot,"%s",arsuffix);
- return slbt_get_deps_meta(dctx,arg,0,depsmeta);
-}
-
-static int slbt_emit_fdwrap_amend_dl_path(
- const struct slbt_driver_ctx * dctx,
- struct slbt_exec_ctx * ectx,
- struct slbt_deps_meta * depsmeta,
- const char * fmt,
- ...)
-{
- va_list ap;
- char * buf;
- int cnt;
- char dlpathbuf[2048];
- int fdwrap;
- const char * fdwrap_fmt;
- int size;
-
- va_start(ap,fmt);
-
- size = sizeof(dlpathbuf);
-
- buf = ((cnt = vsnprintf(dlpathbuf,size,fmt,ap)) < size)
- ? dlpathbuf : malloc((size = cnt + 1));
-
- va_end(ap);
-
- if (buf == dlpathbuf) {
- (void)0;
-
- } else if (buf) {
- va_start(ap,fmt);
- vsprintf(buf,fmt,ap);
- va_end(ap);
-
- } else {
- return slbt_exec_link_exit(
- depsmeta,
- SLBT_SYSTEM_ERROR(dctx,0));
- }
-
- if ((fdwrap = slbt_exec_get_fdwrapper(ectx)) >= 0) {
- if (buf[0] == '/') {
- fdwrap_fmt =
- "DL_PATH=\"${DL_PATH}${COLON}%s\"\n"
- "COLON=':'\n\n";
- } else {
- fdwrap_fmt =
- "DL_PATH=\"${DL_PATH}${COLON}${DL_PATH_FIXUP}%s\"\n"
- "COLON=':'\n\n";
- }
-
- if (slbt_dprintf(fdwrap,fdwrap_fmt,buf) < 0) {
- return slbt_exec_link_exit(
- depsmeta,
- SLBT_SYSTEM_ERROR(dctx,0));
- }
- }
-
- return 0;
-}
-
static void slbt_emit_fdwrap_dl_path_fixup(
char * cwd,
char * dpfixup,
@@ -337,473 +109,6 @@ static void slbt_emit_fdwrap_dl_path_fixup(
strncat(dpfixup,"/",dpfixup_size-1);
}
-static int slbt_exec_link_adjust_argument_vector(
- const struct slbt_driver_ctx * dctx,
- struct slbt_exec_ctx * ectx,
- struct slbt_deps_meta * depsmeta,
- const char * cwd,
- bool flibrary)
-{
- int fd;
- int fdcwd;
- char ** carg;
- char ** aarg;
- char * ldir;
- char * slash;
- char * mark;
- char * darg;
- char * dot;
- char * base;
- char * dpath;
- int argc;
- char arg[PATH_MAX];
- char lib[PATH_MAX];
- char depdir [PATH_MAX];
- char rpathdir[PATH_MAX];
- char rpathlnk[PATH_MAX];
- struct stat st;
- size_t size;
- size_t dlen;
- struct slbt_map_info * mapinfo;
- bool fwholearchive = false;
- int ret;
-
- for (argc=0,carg=ectx->cargv; *carg; carg++)
- argc++;
-
- if (!(depsmeta->args = calloc(1,depsmeta->infolen)))
- return SLBT_SYSTEM_ERROR(dctx,0);
-
- argc *= 3;
- argc += depsmeta->depscnt;
-
- if (!(depsmeta->altv = calloc(argc,sizeof(char *))))
- return slbt_exec_link_exit(
- depsmeta,
- SLBT_SYSTEM_ERROR(dctx,0));
-
- fdcwd = slbt_driver_fdcwd(dctx);
-
- carg = ectx->cargv;
- aarg = depsmeta->altv;
- darg = depsmeta->args;
- size = depsmeta->infolen;
-
- for (; *carg; ) {
- dpath = 0;
-
- if (!strcmp(*carg,"-Wl,--whole-archive"))
- fwholearchive = true;
- else if (!strcmp(*carg,"-Wl,--no-whole-archive"))
- fwholearchive = false;
-
-
-
- /* output annotation */
- if (carg == ectx->lout[0]) {
- ectx->mout[0] = &aarg[0];
- ectx->mout[1] = &aarg[1];
- }
-
- /* argument translation */
- mark = *carg;
-
- if ((mark[0] == '-') && (mark[1] == 'L')) {
- if (mark[2]) {
- ldir = &mark[2];
- } else {
- *aarg++ = *carg++;
- ldir = *carg;
- }
-
- mark = ldir + strlen(ldir);
-
- if (mark[-1] == '/')
- strcpy(mark,".libs");
- else
- strcpy(mark,"/.libs");
-
- if ((fd = openat(fdcwd,ldir,O_DIRECTORY,0)) < 0)
- *mark = 0;
- else {
- close(fd);
-
- if ((ret = slbt_emit_fdwrap_amend_dl_path(
- dctx,ectx,depsmeta,
- "%s",ldir)) < 0)
- return ret;
- }
-
- *aarg++ = *carg++;
-
- } else if (**carg == '-') {
- *aarg++ = *carg++;
-
- } else if (!(dot = strrchr(*carg,'.'))) {
- *aarg++ = *carg++;
-
- } else if (ectx->xargv[carg - ectx->cargv]) {
- *aarg++ = *carg++;
-
- } else if (!(strcmp(dot,".a"))) {
- if (flibrary && !fwholearchive)
- *aarg++ = "-Wl,--whole-archive";
-
- dpath = lib;
- sprintf(lib,"%s.slibtool.deps",*carg);
- *aarg++ = *carg++;
-
- if (flibrary && !fwholearchive)
- *aarg++ = "-Wl,--no-whole-archive";
-
- } else if (strcmp(dot,dctx->cctx->settings.dsosuffix)) {
- *aarg++ = *carg++;
-
- } else if (carg == ectx->lout[1]) {
- /* ^^^hoppla^^^ */
- *aarg++ = *carg++;
- } else {
- /* -rpath */
- sprintf(rpathlnk,"%s.slibtool.rpath",*carg);
-
- if (!fstatat(fdcwd,rpathlnk,&st,AT_SYMLINK_NOFOLLOW)) {
- if (slbt_readlinkat(
- fdcwd,
- rpathlnk,
- rpathdir,
- sizeof(rpathdir)))
- return slbt_exec_link_exit(
- depsmeta,
- SLBT_SYSTEM_ERROR(dctx,rpathlnk));
-
- sprintf(darg,"-Wl,%s",rpathdir);
- *aarg++ = "-Wl,-rpath";
- *aarg++ = darg;
- darg += strlen(darg);
- darg++;
- }
-
- dpath = lib;
- sprintf(lib,"%s.slibtool.deps",*carg);
-
- /* account for {'-','L','-','l'} */
- if (slbt_snprintf(arg,
- sizeof(arg) - 4,
- "%s",*carg) < 0)
- return slbt_exec_link_exit(
- depsmeta,
- SLBT_BUFFER_ERROR(dctx));
-
- if ((slash = strrchr(arg,'/'))) {
- sprintf(*carg,"-L%s",arg);
-
- mark = strrchr(*carg,'/');
- *mark = 0;
- *slash = 0;
-
- if ((ret = slbt_emit_fdwrap_amend_dl_path(
- dctx,ectx,depsmeta,
- "%s%s%s",
- ((arg[0] == '/') ? "" : cwd),
- ((arg[0] == '/') ? "" : "/"),
- arg)) < 0) {
- return ret;
- }
-
- dlen = strlen(dctx->cctx->settings.dsoprefix);
-
- /* -module? (todo: non-portable usage, display warning) */
- if (strncmp(++slash,dctx->cctx->settings.dsoprefix,dlen)) {
- *--slash = '/';
- strcpy(*carg,arg);
- *aarg++ = *carg++;
- } else {
- *aarg++ = *carg++;
- *aarg++ = ++mark;
-
- slash += dlen;
-
- sprintf(mark,"-l%s",slash);
- dot = strrchr(mark,'.');
- *dot = 0;
- }
- } else {
- *aarg++ = *carg++;
- }
- }
-
- if (dpath && !fstatat(fdcwd,dpath,&st,0)) {
- if (!(mapinfo = slbt_map_file(
- fdcwd,dpath,
- SLBT_MAP_INPUT)))
- return slbt_exec_link_exit(
- depsmeta,
- SLBT_SYSTEM_ERROR(dctx,dpath));
-
- if (!(strncmp(lib,".libs/",6))) {
- *aarg++ = "-L.libs";
- lib[1] = 0;
- } else if ((base = strrchr(lib,'/'))) {
- if (base - lib == 5) {
- if (!(strncmp(&base[-5],".libs/",6)))
- base -= 4;
-
- } else if (base - lib >= 6) {
- if (!(strncmp(&base[-6],"/.libs/",7)))
- base -= 6;
- }
-
- *base = 0;
- } else {
- lib[0] = '.';
- lib[1] = 0;
- }
-
- while (mapinfo->mark < mapinfo->cap) {
- if (slbt_mapped_readline(dctx,mapinfo,darg,size))
- return slbt_exec_link_exit(
- depsmeta,
- SLBT_NESTED_ERROR(dctx));
-
- *aarg++ = darg;
- mark = darg;
-
- dlen = strlen(darg);
- size -= dlen;
- darg += dlen;
- darg[-1] = 0;
-
- /* handle -L... as needed */
- if ((mark[0] == '-')
- && (mark[1] == 'L')
- && (mark[2] != '/')) {
- if (strlen(mark) >= sizeof(depdir) - 1)
- return slbt_exec_link_exit(
- depsmeta,
- SLBT_BUFFER_ERROR(dctx));
-
- darg = mark;
- strcpy(depdir,&mark[2]);
- sprintf(darg,"-L%s/%s",lib,depdir);
-
- darg += strlen(darg);
- darg++;
-
- if ((ret = slbt_emit_fdwrap_amend_dl_path(
- dctx,ectx,depsmeta,
- "%s/%s",lib,depdir)) < 0)
- return ret;
-
- } else if ((mark[0] == '-') && (mark[1] == 'L')) {
- if ((ret = slbt_emit_fdwrap_amend_dl_path(
- dctx,ectx,depsmeta,
- "%s",&mark[2])) < 0)
- return ret;
- }
- }
- }
- }
-
- if (dctx->cctx->drvflags & SLBT_DRIVER_EXPORT_DYNAMIC)
- *aarg++ = "-Wl,--export-dynamic";
-
- return 0;
-}
-
-static int slbt_exec_link_finalize_argument_vector(
- const struct slbt_driver_ctx * dctx,
- struct slbt_exec_ctx * ectx)
-{
- char * sargv[1024];
- char ** sargvbuf;
- char ** base;
- char ** parg;
- char ** aarg;
- char ** oarg;
- char ** larg;
- char ** darg;
- char ** earg;
- char ** rarg;
- char ** aargv;
- char ** oargv;
- char ** cap;
- char ** src;
- char ** dst;
- char * arg;
- char * dot;
- char * ccwrap;
- const char * arsuffix;
-
- /* vector size */
- base = ectx->argv;
- arsuffix = dctx->cctx->settings.arsuffix;
-
- for (parg=base; *parg; parg++)
- (void)0;
-
- /* buffer */
- if (parg - base < 512) {
- aargv = &sargv[0];
- oargv = &sargv[512];
- aarg = aargv;
- oarg = oargv;
- sargvbuf = 0;
-
- } else if (!(sargvbuf = calloc(2*(parg-base+1),sizeof(char *)))) {
- return SLBT_SYSTEM_ERROR(dctx,0);
-
- } else {
- aargv = &sargvbuf[0];
- oargv = &sargvbuf[parg-base+1];
- aarg = aargv;
- oarg = oargv;
- }
-
- /* (program name) */
- parg = &base[1];
-
- /* split object args from all other args, record output */
- /* annotation, and remove redundant -l arguments */
- for (; *parg; ) {
- if (ectx->lout[0] == parg) {
- ectx->lout[0] = &aarg[0];
- ectx->lout[1] = &aarg[1];
- }
-
- if (ectx->mout[0] == parg) {
- ectx->mout[0] = &aarg[0];
- ectx->mout[1] = &aarg[1];
- }
-
- arg = *parg;
- dot = strrchr(arg,'.');
-
- /* object input argument? */
- if (dot && (!strcmp(dot,".o") || !strcmp(dot,".lo"))) {
- *oarg++ = *parg++;
-
- /* --whole-archive input argument? */
- } 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++;
-
- /* local archive input argument? */
- } else if (dot && !strcmp(dot,arsuffix)) {
- *oarg++ = *parg++;
-
- /* -l argument? */
- } else if ((parg[0][0] == '-') && (parg[0][1] == 'l')) {
- /* find the previous occurence of this -l argument */
- for (rarg=0, larg=&aarg[-1]; !rarg && (larg>=aargv); larg--)
- if (!strcmp(*larg,*parg))
- rarg = larg;
-
- /* first occurence of this specific -l argument? */
- if (!rarg) {
- *aarg++ = *parg++;
-
- } else {
- larg = rarg;
-
- /* if all -l arguments following the previous */
- /* occurence had already appeared before the */
- /* previous argument, then the current */
- /* occurence is redundant. */
-
- for (darg=&larg[1]; rarg && darg<aarg; darg++) {
- /* only test -l arguments */
- if ((darg[0][0] == '-') && (darg[0][1] == 'l')) {
- for (rarg=0, earg=aargv; !rarg && earg<larg; earg++)
- if (!strcmp(*earg,*darg))
- rarg = darg;
- }
- }
-
- /* final verdict: repeated -l argument? */
- if (rarg) {
- parg++;
-
- } else {
- *aarg++ = *parg++;
- }
- }
-
- /* -L argument? */
- } else if ((parg[0][0] == '-') && (parg[0][1] == 'L')) {
- /* find a previous occurence of this -L argument */
- for (rarg=0, larg=aargv; !rarg && (larg<aarg); larg++)
- if (!strcmp(*larg,*parg))
- rarg = larg;
-
- /* repeated -L argument? */
- if (rarg) {
- parg++;
- } else {
- *aarg++ = *parg++;
- }
-
- /* placeholder argument? */
- } else if (!strncmp(*parg,"-USLIBTOOL_PLACEHOLDER_",23)) {
- parg++;
-
- /* all other arguments */
- } else {
- *aarg++ = *parg++;
- }
- }
-
- /* program name, ccwrap */
- if ((ccwrap = (char *)dctx->cctx->ccwrap)) {
- base[1] = base[0];
- base[0] = ccwrap;
- base++;
- }
-
- /* join object args */
- src = oargv;
- cap = oarg;
- dst = &base[1];
-
- for (; src<cap; )
- *dst++ = *src++;
-
- /* join all other args */
- src = aargv;
- cap = aarg;
-
- for (; src<cap; )
- *dst++ = *src++;
-
- /* properly null-terminate argv, accounting for redundant -l arguments */
- *dst = 0;
-
- /* output annotation */
- 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]) {
- ectx->mout[0] = &base[1] + (oarg - oargv) + (ectx->mout[0] - aargv);
- ectx->mout[1] = ectx->mout[0] + 1;
- }
-
- /* all done */
- if (sargvbuf)
- free(sargvbuf);
-
- return 0;
-}
-
static int slbt_exec_link_remove_file(
const struct slbt_driver_ctx * dctx,
struct slbt_exec_ctx * ectx,