summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/driver/slbt_driver_ctx.c26
-rw-r--r--src/driver/slbt_split_argv.c15
-rw-r--r--src/skin/slbt_skin_default.c6
3 files changed, 41 insertions, 6 deletions
diff --git a/src/driver/slbt_driver_ctx.c b/src/driver/slbt_driver_ctx.c
index 5fed282..0e4ebda 100644
--- a/src/driver/slbt_driver_ctx.c
+++ b/src/driver/slbt_driver_ctx.c
@@ -1012,7 +1012,15 @@ int slbt_lib_get_driver_ctx(
if (entry->fopt) {
switch (entry->tag) {
case TAG_DLPREOPEN:
- *dlopenv++ = entry->arg;
+ if (!strcmp(entry->arg,"self")) {
+ ctx->cctx.drvflags |= SLBT_DRIVER_DLPREOPEN_SELF;
+
+ } else if (!strcmp(entry->arg,"force")) {
+ ctx->cctx.drvflags |= SLBT_DRIVER_DLPREOPEN_FORCE;
+
+ } else {
+ *dlopenv++ = entry->arg;
+ }
default:
break;
@@ -1021,6 +1029,22 @@ int slbt_lib_get_driver_ctx(
}
}
+ /* -dlopen & -dlpreopen semantic validation */
+ uint64_t fmask;
+
+ fmask = SLBT_DRIVER_DLOPEN_SELF | SLBT_DRIVER_DLPREOPEN_SELF;
+ fmask |= SLBT_DRIVER_DLOPEN_FORCE | SLBT_DRIVER_DLPREOPEN_FORCE;
+
+ if (ctx->cctx.libname && (cctx.drvflags & fmask)) {
+ slbt_dprintf(ctx->fdctx.fderr,
+ "%s: error: -dlopen/-dlpreopen: "
+ "the special 'self' and 'force' arguments "
+ "may only be used when linking a program.\n",
+ ctx->ctx.program);
+
+ return slbt_lib_get_driver_ctx_fail(&ctx->ctx,0);
+ }
+
/* all ready */
*pctx = &ctx->ctx;
diff --git a/src/driver/slbt_split_argv.c b/src/driver/slbt_split_argv.c
index bdde474..df0db37 100644
--- a/src/driver/slbt_split_argv.c
+++ b/src/driver/slbt_split_argv.c
@@ -503,12 +503,19 @@ slbt_hidden int slbt_split_argv(
*targv++ = argv[i];
} else if (!(strcmp("dlpreopen",&argv[i][1]))) {
- *cargv++ = argv[i];
- *targv++ = argv[i++];
+ if (!argv[i+1])
+ return -1;
- *cargv++ = argv[i];
- *targv++ = argv[i];
+ if (strcmp(argv[i+1],"self") && strcmp(argv[i+1],"force")) {
+ *cargv++ = argv[i];
+ *targv++ = argv[i++];
+ *cargv++ = argv[i];
+ *targv++ = argv[i];
+ } else {
+ *targv++ = argv[i++];
+ *targv++ = argv[i];
+ }
} else {
for (popt=optout; popt[0] && popt[0]->long_name; popt++)
if (!(strcmp(popt[0]->long_name,&argv[i][1])))
diff --git a/src/skin/slbt_skin_default.c b/src/skin/slbt_skin_default.c
index d01d236..d258def 100644
--- a/src/skin/slbt_skin_default.c
+++ b/src/skin/slbt_skin_default.c
@@ -211,7 +211,11 @@ const slbt_hidden struct argv_option slbt_default_options[] = {
"Link the specified %s into the generated library "
"or executable, and make it available to the compiled "
"shared library, dynamic module, or executable program "
- "via a backward-compatible dlsymas vtable."},
+ "via a backward-compatible dlsymas vtable. The special "
+ "arguments 'self' and 'force' can be used to request "
+ "that symbols from the executable program be added "
+ "to the vtable, and that a vtable always be created, "
+ "respectively."},
{"export-dynamic", 0,TAG_EXPORT_DYNAMIC,ARGV_OPTARG_NONE,
ARGV_OPTION_HYBRID_ONLY,0,0,