summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/slibtool/slibtool.h1
-rw-r--r--src/driver/slbt_driver_ctx.c19
-rw-r--r--src/internal/slibtool_driver_impl.h3
-rw-r--r--src/logic/linkcmd/slbt_linkcmd_argv.c13
-rw-r--r--src/logic/slbt_exec_ctx.c63
5 files changed, 82 insertions, 17 deletions
diff --git a/include/slibtool/slibtool.h b/include/slibtool/slibtool.h
index 96e3738..bf0bf32 100644
--- a/include/slibtool/slibtool.h
+++ b/include/slibtool/slibtool.h
@@ -234,6 +234,7 @@ struct slbt_exec_ctx {
char * dlunit;
char * dlopensrc;
char * dlopenobj;
+ char * dlpreopen;
char * arfilename;
char * lafilename;
diff --git a/src/driver/slbt_driver_ctx.c b/src/driver/slbt_driver_ctx.c
index 8f4f2dc..fc242c0 100644
--- a/src/driver/slbt_driver_ctx.c
+++ b/src/driver/slbt_driver_ctx.c
@@ -247,7 +247,7 @@ static struct slbt_driver_ctx_impl * slbt_driver_ctx_alloc(
}
if (ndlopen) {
- if (!(ictx->ctx.dlopenv = calloc(ndlopen+1,sizeof(char *)))) {
+ if (!(ictx->ctx.dlopenv = calloc(ndlopen+1,sizeof(*ictx->ctx.dlopenv)))) {
free(ictx);
slbt_free_argv_buffer(sargv,objlistv);
return 0;
@@ -406,7 +406,7 @@ int slbt_lib_get_driver_ctx(
const char * lconf;
uint64_t lflags;
size_t ndlopen;
- const char ** dlopenv;
+ struct argv_entry ** dlopenv;
const char * cfgmeta_host;
const char * cfgmeta_ar;
const char * cfgmeta_as;
@@ -1010,7 +1010,16 @@ int slbt_lib_get_driver_ctx(
if (entry->fopt) {
switch (entry->tag) {
case TAG_DLOPEN:
- ctx->cctx.drvflags |= SLBT_DRIVER_DLOPEN_FORCE;
+ if (!strcmp(entry->arg,"self")) {
+ ctx->cctx.drvflags |= SLBT_DRIVER_DLOPEN_FORCE;
+
+ } else if (!strcmp(entry->arg,"force")) {
+ ctx->cctx.drvflags |= SLBT_DRIVER_DLOPEN_FORCE;
+
+ } else {
+ *dlopenv++ = entry;
+ }
+
break;
case TAG_DLPREOPEN:
@@ -1021,9 +1030,11 @@ int slbt_lib_get_driver_ctx(
ctx->cctx.drvflags |= SLBT_DRIVER_DLPREOPEN_FORCE;
} else {
- *dlopenv++ = entry->arg;
+ *dlopenv++ = entry;
}
+ break;
+
default:
break;
}
diff --git a/src/internal/slibtool_driver_impl.h b/src/internal/slibtool_driver_impl.h
index e6e21ea..ef734fd 100644
--- a/src/internal/slibtool_driver_impl.h
+++ b/src/internal/slibtool_driver_impl.h
@@ -150,7 +150,7 @@ struct slbt_driver_ctx_impl {
struct slbt_txtfile_ctx * lconfctx;
struct slbt_obj_list * objlistv;
- const char ** dlopenv;
+ struct argv_entry ** dlopenv;
size_t ndlopen;
const struct slbt_archive_ctx * arctx;
@@ -179,6 +179,7 @@ struct slbt_exec_ctx_impl {
struct slbt_symlist_ctx * sctx;
struct slbt_exec_ctx ctx;
struct slbt_archive_ctx ** dlactxv;
+ struct slbt_archive_ctx * dlpreopen;
char ** dlargv;
int argc;
char * args;
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) */