diff options
author | midipix <writeonce@midipix.org> | 2024-03-10 15:27:44 +0000 |
---|---|---|
committer | midipix <writeonce@midipix.org> | 2024-03-10 20:35:00 +0000 |
commit | a07095d89f48e4612aea2b6edd0c3a62ab209892 (patch) | |
tree | e6ce840a6cbaded73a6c456315b91c41a78343ef /src/logic | |
parent | 9a3246173ce1d855beebe83f44849e2aa0cf2e4a (diff) | |
download | slibtool-a07095d89f48e4612aea2b6edd0c3a62ab209892.tar.bz2 slibtool-a07095d89f48e4612aea2b6edd0c3a62ab209892.tar.xz |
link mode: treat dlopen of static-only dependency libs as (also fixed) dlpreopen
Diffstat (limited to 'src/logic')
-rw-r--r-- | src/logic/linkcmd/slbt_linkcmd_argv.c | 13 | ||||
-rw-r--r-- | src/logic/slbt_exec_ctx.c | 63 |
2 files changed, 64 insertions, 12 deletions
diff --git a/src/logic/linkcmd/slbt_linkcmd_argv.c b/src/logic/linkcmd/slbt_linkcmd_argv.c index 5cfbddb..a7c0777 100644 --- a/src/logic/linkcmd/slbt_linkcmd_argv.c +++ b/src/logic/linkcmd/slbt_linkcmd_argv.c @@ -23,6 +23,7 @@ #include "slibtool_symlink_impl.h" #include "slibtool_readlink_impl.h" #include "slibtool_visibility_impl.h" +#include "slibtool_ar_impl.h" static const char * slbt_ar_self_dlunit = "@PROGRAM@"; @@ -940,7 +941,7 @@ slbt_hidden int slbt_exec_link_finalize_argument_vector( /* add or repalce the archive context */ for (; !arctx && *arctxv; ) - if (!strcmp(*arctxv[0]->path,ectx->mapfilename)) + if (!strcmp(*arctxv[0]->path,slbt_ar_self_dlunit)) arctx = *arctxv; else arctxv++; @@ -955,7 +956,11 @@ slbt_hidden int slbt_exec_link_finalize_argument_vector( if (slbt_ar_get_archive_ctx(dctx,arname,arctxv) < 0) return SLBT_NESTED_ERROR(dctx); - arctxv[0]->path = &slbt_ar_self_dlunit; + arctx = *arctxv; + arctx->path = &slbt_ar_self_dlunit; + + if (slbt_ar_update_syminfo(arctx,ectx) < 0) + return SLBT_NESTED_ERROR(dctx); /* regenerate the dlsyms vtable source */ if (slbt_ar_create_dlsyms( @@ -981,6 +986,10 @@ slbt_hidden int slbt_exec_link_finalize_argument_vector( for (; src<cap; ) *dst++ = *src++; + /* dlpreopen */ + if (ectx->dlpreopen) + *dst++ = ectx->dlpreopen; + /* join all other args, eliminate no-op linker path args */ src = aargv; cap = aarg; diff --git a/src/logic/slbt_exec_ctx.c b/src/logic/slbt_exec_ctx.c index b1177db..af45a93 100644 --- a/src/logic/slbt_exec_ctx.c +++ b/src/logic/slbt_exec_ctx.c @@ -16,7 +16,7 @@ #include "slibtool_errinfo_impl.h" #include "slibtool_ar_impl.h" -#define SLBT_ECTX_LIB_EXTRAS 24 +#define SLBT_ECTX_LIB_EXTRAS 26 #define SLBT_ECTX_SPARE_PTRS 16 static int slbt_ectx_free_exec_ctx_impl( @@ -217,7 +217,9 @@ int slbt_ectx_get_exec_ctx( char * slash; char * arname; struct slbt_archive_ctx ** dlactxv; - const char ** dlopenv; + struct argv_entry * dlentry; + struct argv_entry ** dlopenv; + bool fpreopen; const char * arprefix; const char * dsoprefix; const char * impprefix; @@ -548,7 +550,7 @@ int slbt_ectx_get_exec_ctx( } /* dlopensrc, dlopenobj */ - if (idctx->ndlopen) { + if (idctx->dlopenv) { ictx->ctx.dlopensrc = ch; ch += sprintf(ch,"%s%s%s.dlopen.c", ictx->ctx.ldirname, @@ -565,6 +567,14 @@ int slbt_ectx_get_exec_ctx( ch++; + ictx->ctx.dlpreopen = ch; + ch += sprintf(ch,"%s%s%s.dlpreopen.a", + ictx->ctx.ldirname, + dsoprefix, + dctx->cctx->libname); + + ch++; + ictx->ctx.dlunit = ch; ch += sprintf(ch,"%s%s", dsoprefix, @@ -600,6 +610,12 @@ int slbt_ectx_get_exec_ctx( ch++; + ictx->ctx.dlpreopen = ch; + ch += sprintf(ch,"%s.dlpreopen.a", + ictx->ctx.exefilename); + + ch++; + ictx->ctx.dlunit = ch; ch += sprintf(ch,"%s", "@PROGRAM@"); @@ -617,6 +633,7 @@ int slbt_ectx_get_exec_ctx( /* dlopen, dlpreopen */ if ((dlopenv = idctx->dlopenv), (dlactxv = ictx->dlactxv)) { fmask = SLBT_DRIVER_DLPREOPEN_FORCE; + fmask |= SLBT_DRIVER_DLPREOPEN_SELF; fmask |= SLBT_DRIVER_DLOPEN_FORCE; if (dctx->cctx->drvflags & fmask) { @@ -634,8 +651,11 @@ int slbt_ectx_get_exec_ctx( } for (; *dlopenv; ) { + dlentry = *dlopenv; + fpreopen = (dlentry->tag == TAG_DLPREOPEN); + arname = ictx->sbuf; - strcpy(arname,*dlopenv); + strcpy(arname,dlentry->arg); slbt_adjust_wrapper_argument( arname,true, @@ -644,7 +664,12 @@ int slbt_ectx_get_exec_ctx( errinfp = idctx->errinfp; if (slbt_ar_get_archive_ctx(dctx,arname,dlactxv) < 0) { - strcpy(arname,*dlopenv); + if ((*errinfp)->esyscode != ENOENT) + return slbt_ectx_free_exec_ctx_impl( + ictx, + SLBT_NESTED_ERROR(dctx)); + + strcpy(arname,dlentry->arg); slbt_adjust_wrapper_argument( arname,true, @@ -659,15 +684,23 @@ int slbt_ectx_get_exec_ctx( for (; *errinfp; ) *errinfp++ = 0; + + fpreopen = true; } - if (slbt_ar_update_syminfo(*dlactxv,&ictx->ctx) < 0) - return slbt_ectx_free_exec_ctx_impl( - ictx, - SLBT_NESTED_ERROR(dctx)); + if (fpreopen) { + if (slbt_ar_update_syminfo(*dlactxv,&ictx->ctx) < 0) + return slbt_ectx_free_exec_ctx_impl( + ictx, + SLBT_NESTED_ERROR(dctx)); + + dlactxv++; + } else { + slbt_ar_free_archive_ctx(*dlactxv); + *dlactxv = 0; + } dlopenv++; - dlactxv++; } if (slbt_mkdir(dctx,ictx->ctx.ldirname) < 0) @@ -685,6 +718,16 @@ int slbt_ectx_get_exec_ctx( return slbt_ectx_free_exec_ctx_impl( ictx, SLBT_NESTED_ERROR(dctx)); + + if (slbt_ar_merge_archives(ictx->dlactxv,&ictx->dlpreopen) < 0) + return slbt_ectx_free_exec_ctx_impl( + ictx, + SLBT_NESTED_ERROR(dctx)); + + if (slbt_ar_store_archive(ictx->dlpreopen,ictx->ctx.dlpreopen,0644) < 0) + return slbt_ectx_free_exec_ctx_impl( + ictx, + SLBT_NESTED_ERROR(dctx)); } /* vector of exported symbols (raw input via -export-symbols) */ |