diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/driver/slbt_driver_ctx.c | 26 | ||||
-rw-r--r-- | src/driver/slbt_split_argv.c | 15 | ||||
-rw-r--r-- | src/skin/slbt_skin_default.c | 6 |
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, |