summaryrefslogtreecommitdiff
path: root/src/logic
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2024-03-10 15:27:44 +0000
committermidipix <writeonce@midipix.org>2024-03-10 20:35:00 +0000
commita07095d89f48e4612aea2b6edd0c3a62ab209892 (patch)
treee6ce840a6cbaded73a6c456315b91c41a78343ef /src/logic
parent9a3246173ce1d855beebe83f44849e2aa0cf2e4a (diff)
downloadslibtool-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.c13
-rw-r--r--src/logic/slbt_exec_ctx.c63
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) */