summaryrefslogtreecommitdiff
path: root/src/driver/slbt_driver_ctx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/driver/slbt_driver_ctx.c')
-rw-r--r--src/driver/slbt_driver_ctx.c1787
1 files changed, 532 insertions, 1255 deletions
diff --git a/src/driver/slbt_driver_ctx.c b/src/driver/slbt_driver_ctx.c
index 773e3b6..76c7c4a 100644
--- a/src/driver/slbt_driver_ctx.c
+++ b/src/driver/slbt_driver_ctx.c
@@ -1,6 +1,6 @@
/*******************************************************************/
-/* slibtool: a skinny libtool implementation, written in C */
-/* Copyright (C) 2016--2021 Z. Gilboa */
+/* slibtool: a strong libtool implementation, written in C */
+/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */
/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
/*******************************************************************/
@@ -11,6 +11,7 @@
#include <stdbool.h>
#include <fcntl.h>
#include <spawn.h>
+#include <sys/mman.h>
#include <sys/wait.h>
#define ARGV_DRIVER
@@ -18,12 +19,22 @@
#include <slibtool/slibtool.h>
#include "slibtool_version.h"
#include "slibtool_driver_impl.h"
+#include "slibtool_objlist_impl.h"
#include "slibtool_errinfo_impl.h"
#include "slibtool_lconf_impl.h"
+#include "slibtool_mkvars_impl.h"
+#include "slibtool_txtline_impl.h"
+#include "slibtool_stoolie_impl.h"
+#include "slibtool_ar_impl.h"
#include "argv/argv.h"
extern char ** environ;
+/* annotation strings */
+static const char cfgexplicit[] = "command-line argument";
+static const char cfglconf[] = "derived from <libtool>";
+static const char cfgmkvars[] = "derived from <makefile>";
+
/* package info */
static const struct slbt_source_version slbt_src_version = {
SLBT_TAG_VER_MAJOR,
@@ -42,91 +53,24 @@ static const struct slbt_fd_ctx slbt_default_fdctx = {
.fdlog = (-1),
};
-/* flavor settings */
-#define SLBT_FLAVOR_SETTINGS(flavor, \
- bfmt,pic, \
- arp,ars,dsop,dsos,osds,osdf, \
- exep,exes,impp,imps, \
- ldenv) \
- static const struct slbt_flavor_settings flavor = { \
- bfmt,arp,ars,dsop,dsos,osds,osdf, \
- exep,exes,impp,imps, \
- ldenv,pic}
-
-SLBT_FLAVOR_SETTINGS(host_flavor_default, \
- "elf","-fPIC", \
- "lib",".a","lib",".so",".so","", \
- "","","","", \
- "LD_LIBRARY_PATH");
-
-SLBT_FLAVOR_SETTINGS(host_flavor_midipix, \
- "pe","-fPIC", \
- "lib",".a","lib",".so",".so","", \
- "","","lib",".lib.a", \
- "LD_LIBRARY_PATH");
-
-SLBT_FLAVOR_SETTINGS(host_flavor_mingw, \
- "pe",0, \
- "lib",".a","lib",".dll","",".dll", \
- "",".exe","lib",".dll.a", \
- "PATH");
-
-SLBT_FLAVOR_SETTINGS(host_flavor_cygwin, \
- "pe",0, \
- "lib",".a","lib",".dll","",".dll", \
- "",".exe","lib",".dll.a", \
- "PATH");
-
-SLBT_FLAVOR_SETTINGS(host_flavor_darwin, \
- "macho","-fPIC", \
- "lib",".a","lib",".dylib","",".dylib", \
- "","","","", \
- "DYLD_LIBRARY_PATH");
-
+static const char aclr_reset [] = "\x1b[0m";
+static const char aclr_bold [] = "\x1b[1m";
+static const char aclr_red [] = "\x1b[31m";
+static const char aclr_green [] = "\x1b[32m";
+static const char aclr_yellow [] = "\x1b[33m";
+static const char aclr_blue [] = "\x1b[34m";
+static const char aclr_magenta [] = "\x1b[35m";
+static const char aclr_cyan [] = "\x1b[36m";
+static const char aclr_white [] = "\x1b[37m";
-/* annotation strings */
-static const char cfgexplicit[] = "command-line argument";
-static const char cfghost[] = "derived from <host>";
-static const char cfgtarget[] = "derived from <target>";
-static const char cfgcompiler[] = "derived from <compiler>";
-static const char cfgnmachine[] = "native (cached in ccenv/host.mk)";
-static const char cfgxmachine[] = "foreign (derived from -dumpmachine)";
-static const char cfgnative[] = "native";
-
-
-/* default compiler argv */
-static char * slbt_default_cargv[] = {"cc",0};
-
-/* elf rpath */
-static const char*ldrpath_elf[] = {
- "/lib",
- "/lib/64",
- "/usr/lib",
- "/usr/lib64",
- "/usr/local/lib",
- "/usr/local/lib64",
- 0};
-
-static const char aclr_reset [] = "\x1b[0m";
-static const char aclr_bold [] = "\x1b[1m";
-static const char aclr_red [] = "\x1b[31m";
-static const char aclr_green [] = "\x1b[32m";
-static const char aclr_yellow[] = "\x1b[33m";
-static const char aclr_blue [] = "\x1b[34m";
-static const char aclr_cyan [] = "\x1b[36m";
-static const char aclr_white [] = "\x1b[37m";
-
-struct slbt_driver_ctx_alloc {
- struct argv_meta * meta;
- struct slbt_driver_ctx_impl ctx;
- uint64_t guard;
-};
static void slbt_output_raw_vector(int fderr, char ** argv, char ** envp, bool fcolor)
{
char ** parg;
char * dot;
const char * color;
+ const char * prev;
+ const char * prog;
(void)envp;
@@ -135,19 +79,68 @@ static void slbt_output_raw_vector(int fderr, char ** argv, char ** envp, bool f
slbt_dprintf(fderr,"\n\n\n%s",argv[0]);
- for (parg=&argv[1]; *parg; parg++) {
- if (!fcolor)
+ for (prev=0,prog=0,parg=&argv[1]; *parg; parg++) {
+ dot = strrchr(*parg,'.');
+
+ if (!fcolor) {
color = "";
- else if (*parg[0] == '-')
- color = aclr_blue;
- else if (!(dot = strrchr(*parg,'.')))
+
+ } else if (!prog && (parg[0][0] != '-')) {
+ color = aclr_magenta;
+ prog = *parg;
+ prev = 0;
+
+ } else if (!strcmp(parg[0],"-o")) {
+ color = aclr_white;
+ prev = color;
+
+ } else if (!strcmp(parg[0],"-c")) {
color = aclr_green;
- else if (!(strcmp(dot,".lo")))
+ prev = color;
+
+ } else if (!strncmp(parg[0],"-Wl,",4)) {
+ color = aclr_magenta;
+ prev = 0;
+
+ } else if (prev == aclr_white) {
+ color = prev;
+ prev = 0;
+
+ } else if (dot && !strcmp(dot,".o")) {
+ color = aclr_cyan;
+ prev = 0;
+
+ } else if (dot && !strcmp(dot,".lo")) {
color = aclr_cyan;
- else if (!(strcmp(dot,".la")))
+ prev = 0;
+
+ } else if (dot && !strcmp(dot,".la")) {
color = aclr_yellow;
- else
- color = aclr_white;
+ prev = 0;
+
+ } else if (!strcmp(parg[0],"-dlopen")) {
+ color = aclr_yellow;
+ prev = color;
+
+ } else if (!strcmp(parg[0],"-dlpreopen")) {
+ color = aclr_yellow;
+ prev = color;
+
+ } else if (!strcmp(parg[0],"-objectlist")) {
+ color = aclr_yellow;
+ prev = color;
+
+ } else if (*parg[0] == '-') {
+ color = aclr_blue;
+ prev = color;
+
+ } else if (prev) {
+ color = prev;
+ prev = 0;
+
+ } else {
+ color = aclr_yellow;
+ }
slbt_dprintf(fderr," %s%s",color,*parg);
}
@@ -155,7 +148,67 @@ static void slbt_output_raw_vector(int fderr, char ** argv, char ** envp, bool f
slbt_dprintf(fderr,"%s\n\n",fcolor ? aclr_reset : "");
}
-static uint32_t slbt_argv_flags(uint32_t flags)
+slbt_hidden const char * slbt_program_name(const char * path)
+{
+ return argv_program_name(path);
+}
+
+
+slbt_hidden int slbt_optv_init(
+ const struct argv_option options[],
+ const struct argv_option ** optv)
+{
+ return argv_optv_init(options,optv);
+}
+
+
+slbt_hidden void slbt_argv_scan(
+ char ** argv,
+ const struct argv_option ** optv,
+ struct argv_ctx * ctx,
+ struct argv_meta * meta)
+{
+ argv_scan(argv,optv,ctx,meta);
+}
+
+
+slbt_hidden struct argv_meta * slbt_argv_get(
+ char ** argv,
+ const struct argv_option ** optv,
+ int flags,
+ int fd)
+{
+ return argv_get(argv,optv,flags,fd);
+}
+
+
+slbt_hidden void slbt_argv_free(struct argv_meta * meta)
+{
+ argv_free(meta);
+}
+
+
+slbt_hidden void slbt_argv_usage(
+ int fd,
+ const char * header,
+ const struct argv_option ** optv,
+ const char * mode)
+{
+ argv_usage(fd,header,optv,mode);
+}
+
+
+slbt_hidden void slbt_argv_usage_plain(
+ int fd,
+ const char * header,
+ const struct argv_option ** optv,
+ const char * mode)
+{
+ argv_usage_plain(fd,header,optv,mode);
+}
+
+
+slbt_hidden uint64_t slbt_argv_flags(uint64_t flags)
{
uint32_t ret = 0;
@@ -171,8 +224,12 @@ static uint32_t slbt_argv_flags(uint32_t flags)
return ret;
}
-static int slbt_free_argv_buffer(struct slbt_split_vector * sargv)
+static int slbt_free_argv_buffer(
+ struct slbt_split_vector * sargv,
+ struct slbt_obj_list * objlistv)
{
+ struct slbt_obj_list * objlistp;
+
if (sargv->dargs)
free(sargv->dargs);
@@ -182,16 +239,26 @@ static int slbt_free_argv_buffer(struct slbt_split_vector * sargv)
if (sargv->targv)
free(sargv->targv);
+ if (objlistv) {
+ for (objlistp=objlistv; objlistp->name; objlistp++) {
+ free(objlistp->objv);
+ free(objlistp->addr);
+ }
+
+ free(objlistv);
+ }
+
return -1;
}
-static int slbt_driver_usage(
+slbt_hidden int slbt_driver_usage(
int fdout,
const char * program,
const char * arg,
const struct argv_option ** optv,
struct argv_meta * meta,
struct slbt_split_vector * sargv,
+ struct slbt_obj_list * objlistv,
int noclr)
{
char header[512];
@@ -211,17 +278,18 @@ static int slbt_driver_usage(
}
argv_free(meta);
- slbt_free_argv_buffer(sargv);
+ slbt_free_argv_buffer(sargv,objlistv);
return SLBT_USAGE;
}
static struct slbt_driver_ctx_impl * slbt_driver_ctx_alloc(
- struct argv_meta * meta,
const struct slbt_fd_ctx * fdctx,
const struct slbt_common_ctx * cctx,
struct slbt_split_vector * sargv,
- char ** envp)
+ struct slbt_obj_list * objlistv,
+ char ** envp,
+ size_t ndlopen)
{
struct slbt_driver_ctx_alloc * ictx;
size_t size;
@@ -230,10 +298,20 @@ static struct slbt_driver_ctx_impl * slbt_driver_ctx_alloc(
size = sizeof(struct slbt_driver_ctx_alloc);
if (!(ictx = calloc(1,size))) {
- slbt_free_argv_buffer(sargv);
+ slbt_free_argv_buffer(sargv,objlistv);
return 0;
}
+ if (ndlopen) {
+ if (!(ictx->ctx.dlopenv = calloc(ndlopen+1,sizeof(*ictx->ctx.dlopenv)))) {
+ free(ictx);
+ slbt_free_argv_buffer(sargv,objlistv);
+ return 0;
+ }
+
+ ictx->ctx.ndlopen = ndlopen;
+ }
+
ictx->ctx.dargs = sargv->dargs;
ictx->ctx.dargv = sargv->dargv;
ictx->ctx.targv = sargv->targv;
@@ -248,18 +326,20 @@ static struct slbt_driver_ctx_impl * slbt_driver_ctx_alloc(
ictx->ctx.errinfp = &ictx->ctx.erriptr[0];
ictx->ctx.erricap = &ictx->ctx.erriptr[--elements];
- ictx->meta = meta;
- ictx->ctx.ctx.errv = ictx->ctx.errinfp;
+ ictx->ctx.objlistv = objlistv;
+
+ ictx->ctx.ctx.errv = ictx->ctx.errinfp;
+
return &ictx->ctx;
}
-static int slbt_get_driver_ctx_fail(
+static int slbt_lib_get_driver_ctx_fail(
struct slbt_driver_ctx * dctx,
struct argv_meta * meta)
{
if (dctx) {
slbt_output_error_vector(dctx);
- slbt_free_driver_ctx(dctx);
+ slbt_lib_free_driver_ctx(dctx);
} else {
argv_free(meta);
}
@@ -267,1038 +347,6 @@ static int slbt_get_driver_ctx_fail(
return -1;
}
-static int slbt_split_argv(
- char ** argv,
- uint32_t flags,
- struct slbt_split_vector * sargv,
- int fderr)
-{
- int i;
- int argc;
- const char * program;
- char * compiler;
- char * csysroot;
- char ** dargv;
- char ** targv;
- char ** cargv;
- char * dst;
- bool flast;
- bool fcopy;
- size_t size;
- const char * base;
- struct argv_meta * meta;
- struct argv_entry * entry;
- struct argv_entry * mode;
- struct argv_entry * help;
- struct argv_entry * version;
- struct argv_entry * config;
- struct argv_entry * finish;
- struct argv_entry * features;
- struct argv_entry * ccwrap;
- struct argv_entry * dumpmachine;
- const struct argv_option ** popt;
- const struct argv_option ** optout;
- const struct argv_option * optv[SLBT_OPTV_ELEMENTS];
- struct argv_ctx ctx = {ARGV_VERBOSITY_NONE,
- ARGV_MODE_SCAN,
- 0,0,0,0,0,0,0};
-
- program = argv_program_name(argv[0]);
-
- /* missing arguments? */
- argv_optv_init(slbt_default_options,optv);
-
- if (!argv[1] && (flags & SLBT_DRIVER_VERBOSITY_USAGE))
- return slbt_driver_usage(
- fderr,program,
- 0,optv,0,sargv,
- !!getenv("NO_COLOR"));
-
- /* initial argv scan: ... --mode=xxx ... <compiler> ... */
- argv_scan(argv,optv,&ctx,0);
-
- /* invalid slibtool arguments? */
- if (ctx.erridx && !ctx.unitidx) {
- if (flags & SLBT_DRIVER_VERBOSITY_ERRORS)
- argv_get(
- argv,optv,
- slbt_argv_flags(flags),
- fderr);
- return -1;
- }
-
- /* obtain slibtool's own arguments */
- if (ctx.unitidx) {
- compiler = argv[ctx.unitidx];
- argv[ctx.unitidx] = 0;
-
- meta = argv_get(argv,optv,ARGV_VERBOSITY_NONE,fderr);
- argv[ctx.unitidx] = compiler;
- } else {
- meta = argv_get(argv,optv,ARGV_VERBOSITY_NONE,fderr);
- }
-
- /* missing all of --mode, --help, --version, --config, --dumpmachine, --features, and --finish? */
- mode = help = version = config = finish = features = ccwrap = dumpmachine = 0;
-
- for (entry=meta->entries; entry->fopt; entry++)
- if (entry->tag == TAG_MODE)
- mode = entry;
- else if (entry->tag == TAG_HELP)
- help = entry;
- else if (entry->tag == TAG_VERSION)
- version = entry;
- else if (entry->tag == TAG_CONFIG)
- config = entry;
- else if (entry->tag == TAG_FINISH)
- finish = entry;
- else if (entry->tag == TAG_FEATURES)
- features = entry;
- else if (entry->tag == TAG_CCWRAP)
- ccwrap = entry;
- else if (entry->tag == TAG_DUMPMACHINE)
- dumpmachine = entry;
-
- argv_free(meta);
-
- if (!mode && !help && !version && !config && !finish && !features && !dumpmachine) {
- slbt_dprintf(fderr,
- "%s: error: --mode must be specified.\n",
- program);
- return -1;
- }
-
- /* missing compiler? */
- if (!ctx.unitidx && !help && !version && !finish && !features && !dumpmachine) {
- if (flags & SLBT_DRIVER_VERBOSITY_ERRORS)
- slbt_dprintf(fderr,
- "%s: error: <compiler> is missing.\n",
- program);
- return -1;
- }
-
- /* clone and normalize the argv vector (-l, --library) */
- for (argc=0,size=0,dargv=argv; *dargv; argc++,dargv++)
- size += strlen(*dargv) + 1;
-
- if (!(sargv->dargv = calloc(argc+1,sizeof(char *))))
- return -1;
-
- else if (!(sargv->dargs = calloc(1,size+1)))
- return -1;
-
- csysroot = 0;
-
- for (i=0,flast=false,dargv=sargv->dargv,dst=sargv->dargs; i<argc; i++) {
- if ((fcopy = flast)) {
- (void)0;
-
- } else if (!strcmp(argv[i],"--")) {
- flast = true;
- fcopy = true;
-
- } else if (!strcmp(argv[i],"-l")) {
- *dargv++ = dst;
- *dst++ = '-';
- *dst++ = 'l';
- strcpy(dst,argv[++i]);
- dst += strlen(dst)+1;
-
- } else if (!strncmp(argv[i],"-l",2)) {
- fcopy = true;
-
- } else if (!strcmp(argv[i],"--library")) {
- *dargv++ = dst;
- *dst++ = '-';
- *dst++ = 'l';
- strcpy(dst,argv[++i]);
- dst += strlen(dst)+1;
-
- } else if (!strncmp(argv[i],"--library=",10)) {
- *dargv++ = dst;
- *dst++ = '-';
- *dst++ = 'l';
- strcpy(dst,&argv[++i][10]);
- dst += strlen(dst)+1;
-
- } else if (!strcmp(argv[i],"-L")) {
- *dargv++ = dst;
- *dst++ = '-';
- *dst++ = 'L';
- strcpy(dst,argv[++i]);
- dst += strlen(dst)+1;
-
- } else if (!strncmp(argv[i],"-L",2)) {
- fcopy = true;
-
- } else if (!strcmp(argv[i],"-Xlinker")) {
- *dargv++ = dst;
- *dst++ = '-';
- *dst++ = 'W';
- *dst++ = 'l';
- *dst++ = ',';
- strcpy(dst,argv[++i]);
- dst += strlen(dst)+1;
-
- } else if (!strcmp(argv[i],"--library-path")) {
- *dargv++ = dst;
- *dst++ = '-';
- *dst++ = 'L';
- strcpy(dst,argv[++i]);
- dst += strlen(dst)+1;
-
- } else if (!strncmp(argv[i],"--library-path=",15)) {
- *dargv++ = dst;
- *dst++ = '-';
- *dst++ = 'L';
- strcpy(dst,&argv[i][15]);
- dst += strlen(dst)+1;
-
- } else if (!strcmp(argv[i],"--sysroot") && (i<ctx.unitidx)) {
- *dargv++ = dst;
- csysroot = dst;
- strcpy(dst,argv[i]);
- dst[9] = '=';
- strcpy(&dst[10],argv[++i]);
- dst += strlen(dst)+1;
- ctx.unitidx--;
-
- } else if (!strncmp(argv[i],"--sysroot=",10) && (i<ctx.unitidx)) {
- *dargv++ = dst;
- csysroot = dst;
- strcpy(dst,argv[i]);
- dst += strlen(dst)+1;
-
- } else {
- fcopy = true;
- }
-
- if (fcopy) {
- *dargv++ = dst;
- strcpy(dst,argv[i]);
- dst += strlen(dst)+1;
- }
- }
-
- /* update argc,argv */
- argc = dargv - sargv->dargv;
- argv = sargv->dargv;
-
- /* allocate split vectors, account for cargv's added sysroot */
- if ((sargv->targv = calloc(2*(argc+3),sizeof(char *))))
- sargv->cargv = sargv->targv + argc + 2;
- else
- return -1;
-
- /* --features and no <compiler>? */
- if (ctx.unitidx) {
- (void)0;
-
- } else if (help || version || features || dumpmachine) {
- for (i=0; i<argc; i++)
- sargv->targv[i] = argv[i];
-
- sargv->cargv = slbt_default_cargv;
-
- return 0;
- }
-
- /* split vectors: slibtool's own options */
- for (i=0; i<ctx.unitidx; i++)
- sargv->targv[i] = argv[i];
-
- /* split vector marks */
- targv = sargv->targv + i;
- cargv = sargv->cargv;
-
- /* known wrappers */
- if (ctx.unitidx && !ccwrap) {
- if ((base = strrchr(argv[i],'/')))
- base++;
- else if ((base = strrchr(argv[i],'\\')))
- base++;
- else
- base = argv[i];
-
- if (!strcmp(base,"ccache")
- || !strcmp(base,"distcc")
- || !strcmp(base,"compiler")
- || !strcmp(base,"purify")) {
- *targv++ = "--ccwrap";
- *targv++ = argv[i++];
- }
- }
-
- /* split vectors: legacy mixture */
- for (optout=optv; optout[0]->tag != TAG_OUTPUT; optout++)
- (void)0;
-
- /* compiler */
- *cargv++ = argv[i++];
-
- /* sysroot */
- if (csysroot)
- *cargv++ = csysroot;
-
- /* remaining vector */
- for (; i<argc; i++) {
- if (argv[i][0] != '-') {
- if (argv[i+1] && (argv[i+1][0] == '+')
- && (argv[i+1][1] == '=')
- && (argv[i+1][2] == 0)
- && !(strrchr(argv[i],'.')))
- /* libfoo_la_LDFLAGS += -Wl,.... */
- i++;
- else
- *cargv++ = argv[i];
-
- } else if (argv[i][1] == 'o') {
- *targv++ = argv[i];
-
- if (argv[i][2] == 0)
- *targv++ = argv[++i];
- } else if ((argv[i][1] == 'W') && (argv[i][2] == 'c')) {
- *cargv++ = argv[i];
-
- } else if (!(strcmp("Xcompiler",&argv[i][1]))) {
- *cargv++ = argv[++i];
-
- } else if (!(strcmp("XCClinker",&argv[i][1]))) {
- *cargv++ = argv[++i];
-
- } else if ((argv[i][1] == 'R') && (argv[i][2] == 0)) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (argv[i][1] == 'R') {
- *targv++ = argv[i];
-
- } else if (!(strncmp("-target=",&argv[i][1],8))) {
- *cargv++ = argv[i];
- *targv++ = argv[i];
-
- } else if (!(strcmp("-target",&argv[i][1]))) {
- *cargv++ = argv[i];
- *targv++ = argv[i++];
-
- *cargv++ = argv[i];
- *targv++ = argv[i];
-
- } else if (!(strncmp("-sysroot=",&argv[i][1],9))) {
- *cargv++ = argv[i];
- *targv++ = argv[i];
-
- } else if (!(strcmp("-sysroot",&argv[i][1]))) {
- *cargv++ = argv[i];
- *targv++ = argv[i++];
-
- *cargv++ = argv[i];
- *targv++ = argv[i];
-
- } else if (!(strcmp("bindir",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("shrext",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("rpath",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("release",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("dlopen",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("static-libtool-libs",&argv[i][1]))) {
- *targv++ = argv[i];
-
- } else if (!(strcmp("export-dynamic",&argv[i][1]))) {
- *targv++ = argv[i];
-
- } else if (!(strcmp("export-symbols",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("export-symbols-regex",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("version-info",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("version-number",&argv[i][1]))) {
- *targv++ = argv[i++];
- *targv++ = argv[i];
-
- } else if (!(strcmp("dlpreopen",&argv[i][1]))) {
- (void)0;
-
- } else {
- for (popt=optout; popt[0] && popt[0]->long_name; popt++)
- if (!(strcmp(popt[0]->long_name,&argv[i][1])))
- break;
-
- if (popt[0] && popt[0]->long_name)
- *targv++ = argv[i];
- else
- *cargv++ = argv[i];
- }
- }
-
- return 0;
-}
-
-static void slbt_get_host_quad(
- char * hostbuf,
- char ** hostquad)
-{
- char * mark;
- char * ch;
- int i;
-
- for (i=0, ch=hostbuf, mark=hostbuf; *ch && i<4; ch++) {
- if (*ch == '-') {
- *ch = 0;
- hostquad[i++] = mark;
- mark = &ch[1];
- }
- }
-
- if (i<4)
- hostquad[i] = mark;
-
- if (i==3) {
- hostquad[1] = hostquad[2];
- hostquad[2] = hostquad[3];
- hostquad[3] = 0;
- }
-}
-
-static void slbt_spawn_ar(char ** argv, int * ecode)
-{
- int estatus;
- pid_t pid;
-
- *ecode = 127;
-
- if ((pid = fork()) < 0) {
- return;
-
- } else if (pid == 0) {
- execvp(argv[0],argv);
- _exit(errno);
-
- } else {
- waitpid(pid,&estatus,0);
-
- if (WIFEXITED(estatus))
- *ecode = WEXITSTATUS(estatus);
- }
-}
-
-static int slbt_init_host_params(
- const struct slbt_driver_ctx * dctx,
- const struct slbt_common_ctx * cctx,
- struct slbt_host_strs * drvhost,
- struct slbt_host_params * host,
- struct slbt_host_params * cfgmeta)
-{
- int fdcwd;
- int arprobe;
- int arfd;
- int ecode;
- size_t toollen;
- char * dash;
- char * base;
- char * mark;
- const char * machine;
- bool ftarget = false;
- bool fhost = false;
- bool fcompiler = false;
- bool fnative = false;
- bool fdumpmachine = false;
- char buf [256];
- char hostbuf [256];
- char machinebuf [256];
- char * hostquad [4];
- char * machinequad[4];
- char * arprobeargv[4];
- char archivename[] = "/tmp/slibtool.ar.probe.XXXXXXXXXXXXXXXX";
-
- /* base */
- if ((base = strrchr(cctx->cargv[0],'/')))
- base++;
- else
- base = cctx->cargv[0];
-
- fdumpmachine = (cctx->mode == SLBT_MODE_COMPILE)
- || (cctx->mode == SLBT_MODE_LINK)
- || (cctx->mode == SLBT_MODE_INFO);
-
- fdumpmachine &= (!strcmp(base,"xgcc")
- || !strcmp(base,"xg++"));
-
- /* support the portbld <--> unknown synonym */
- if (!(drvhost->machine = strdup(SLBT_MACHINE)))
- return -1;
-
- if ((mark = strstr(drvhost->machine,"-portbld-")))
- memcpy(mark,"-unknown",8);
-
- /* host */
- if (host->host) {
- cfgmeta->host = cfgexplicit;
- fhost = true;
-
- } else if (cctx->target) {
- host->host = cctx->target;
- cfgmeta->host = cfgtarget;
- ftarget = true;
-
- } else if (strrchr(base,'-')) {
- if (!(drvhost->host = strdup(cctx->cargv[0])))
- return -1;
-
- dash = strrchr(drvhost->host,'-');
- *dash = 0;
- host->host = drvhost->host;
- cfgmeta->host = cfgcompiler;
- fcompiler = true;
-
- } else if (!fdumpmachine) {
- host->host = drvhost->machine;
- cfgmeta->host = cfgnmachine;
-
- } else if (slbt_dump_machine(cctx->cargv[0],buf,sizeof(buf)) < 0) {
- if (dctx)
- slbt_dprintf(
- slbt_driver_fderr(dctx),
- "%s: could not determine host "
- "via -dumpmachine\n",
- dctx->program);
- return -1;
-
- } else {
- if (!(drvhost->host = strdup(buf)))
- return -1;
-
- host->host = drvhost->host;
- fcompiler = true;
- fnative = !strcmp(host->host,drvhost->machine);
- cfgmeta->host = fnative ? cfgnmachine : cfgxmachine;
-
- if (!fnative) {
- strcpy(hostbuf,host->host);
- strcpy(machinebuf,drvhost->machine);
-
- slbt_get_host_quad(hostbuf,hostquad);
- slbt_get_host_quad(machinebuf,machinequad);
-
- if (hostquad[2] && machinequad[2])
- fnative = !strcmp(hostquad[0],machinequad[0])
- && !strcmp(hostquad[1],machinequad[1])
- && !strcmp(hostquad[2],machinequad[2]);
- }
- }
-
- /* flavor */
- if (host->flavor) {
- cfgmeta->flavor = cfgexplicit;
- } else {
- if (fhost) {
- machine = host->host;
- cfgmeta->flavor = cfghost;
- } else if (ftarget) {
- machine = cctx->target;
- cfgmeta->flavor = cfgtarget;
- } else if (fcompiler) {
- machine = drvhost->host;
- cfgmeta->flavor = cfgcompiler;
- } else {
- machine = drvhost->machine;
- cfgmeta->flavor = cfgnmachine;
- }
-
- dash = strrchr(machine,'-');
- cfgmeta->flavor = cfghost;
-
- if ((dash && !strcmp(dash,"-bsd")) || strstr(machine,"-bsd-"))
- host->flavor = "bsd";
- else if ((dash && !strcmp(dash,"-cygwin")) || strstr(machine,"-cygwin-"))
- host->flavor = "cygwin";
- else if ((dash && !strcmp(dash,"-darwin")) || strstr(machine,"-darwin"))
- host->flavor = "darwin";
- else if ((dash && !strcmp(dash,"-linux")) || strstr(machine,"-linux-"))
- host->flavor = "linux";
- else if ((dash && !strcmp(dash,"-midipix")) || strstr(machine,"-midipix-"))
- host->flavor = "midipix";
- else if ((dash && !strcmp(dash,"-mingw")) || strstr(machine,"-mingw-"))
- host->flavor = "mingw";
- else if ((dash && !strcmp(dash,"-mingw32")) || strstr(machine,"-mingw32-"))
- host->flavor = "mingw";
- else if ((dash && !strcmp(dash,"-mingw64")) || strstr(machine,"-mingw64-"))
- host->flavor = "mingw";
- else if ((dash && !strcmp(dash,"-windows")) || strstr(machine,"-windows-"))
- host->flavor = "mingw";
- else {
- host->flavor = "default";
- cfgmeta->flavor = "fallback, unverified";
- }
-
- if (fcompiler && !fnative)
- if ((mark = strstr(drvhost->machine,host->flavor)))
- if (mark > drvhost->machine)
- fnative = (*--mark == '-');
- }
-
- /* toollen */
- toollen = fnative ? 0 : strlen(host->host);
- toollen += strlen("-utility-name");
-
- /* ar */
- if (host->ar)
- cfgmeta->ar = cfgexplicit;
- else {
- if (!(drvhost->ar = calloc(1,toollen)))
- return -1;
-
- if (fnative) {
- strcpy(drvhost->ar,"ar");
- cfgmeta->ar = cfgnative;
- arprobe = 0;
- } else if (cctx->mode == SLBT_MODE_LINK) {
- arprobe = true;
- } else if (cctx->mode == SLBT_MODE_INFO) {
- arprobe = true;
- } else {
- arprobe = false;
- }
-
- /* arprobe */
- if (arprobe) {
- sprintf(drvhost->ar,"%s-ar",host->host);
- cfgmeta->ar = cfghost;
- ecode = 127;
-
- /* empty archive */
- if ((arfd = mkstemp(archivename)) >= 0) {
- slbt_dprintf(arfd,"!<arch>\n");
-
- arprobeargv[0] = drvhost->ar;
- arprobeargv[1] = "-t";
- arprobeargv[2] = archivename;
- arprobeargv[3] = 0;
-
- /* <target>-ar */
- slbt_spawn_ar(
- arprobeargv,
- &ecode);
- }
-
- /* <target>-<compiler>-ar */
- if (ecode && !strchr(base,'-')) {
- sprintf(drvhost->ar,"%s-%s-ar",host->host,base);
-
- slbt_spawn_ar(
- arprobeargv,
- &ecode);
- }
-
- /* <compiler>-ar */
- if (ecode && !strchr(base,'-')) {
- sprintf(drvhost->ar,"%s-ar",base);
-
- slbt_spawn_ar(
- arprobeargv,
- &ecode);
- }
-
- /* if target is the native target, fallback to native ar */
- if (ecode && !strcmp(host->host,SLBT_MACHINE)) {
- strcpy(drvhost->ar,"ar");
- cfgmeta->ar = cfgnative;
- }
-
- /* fdcwd */
- fdcwd = slbt_driver_fdcwd(dctx);
-
- /* clean up */
- if (arfd >= 0) {
- unlinkat(fdcwd,archivename,0);
- close(arfd);
- }
- }
-
- host->ar = drvhost->ar;
- }
-
- /* ranlib */
- if (host->ranlib)
- cfgmeta->ranlib = cfgexplicit;
- else {
- if (!(drvhost->ranlib = calloc(1,toollen)))
- return -1;
-
- if (fnative) {
- strcpy(drvhost->ranlib,"ranlib");
- cfgmeta->ranlib = cfgnative;
- } else {
- sprintf(drvhost->ranlib,"%s-ranlib",host->host);
- cfgmeta->ranlib = cfghost;
- }
-
- host->ranlib = drvhost->ranlib;
- }
-
- /* windres */
- if (host->windres)
- cfgmeta->windres = cfgexplicit;
-
- else if (strcmp(host->flavor,"cygwin")
- && strcmp(host->flavor,"midipix")
- && strcmp(host->flavor,"mingw")) {
- host->windres = "";
- cfgmeta->windres = "not applicable";
-
- } else {
- if (!(drvhost->windres = calloc(1,toollen)))
- return -1;
-
- if (fnative) {
- strcpy(drvhost->windres,"windres");
- cfgmeta->windres = cfgnative;
- } else {
- sprintf(drvhost->windres,"%s-windres",host->host);
- cfgmeta->windres = cfghost;
- }
-
- host->windres = drvhost->windres;
- }
-
- /* dlltool */
- if (host->dlltool)
- cfgmeta->dlltool = cfgexplicit;
-
- else if (strcmp(host->flavor,"cygwin")
- && strcmp(host->flavor,"midipix")
- && strcmp(host->flavor,"mingw")) {
- host->dlltool = "";
- cfgmeta->dlltool = "not applicable";
-
- } else {
- if (!(drvhost->dlltool = calloc(1,toollen)))
- return -1;
-
- if (fnative) {
- strcpy(drvhost->dlltool,"dlltool");
- cfgmeta->dlltool = cfgnative;
- } else {
- sprintf(drvhost->dlltool,"%s-dlltool",host->host);
- cfgmeta->dlltool = cfghost;
- }
-
- host->dlltool = drvhost->dlltool;
- }
-
- /* mdso */
- if (host->mdso)
- cfgmeta->mdso = cfgexplicit;
-
- else if (strcmp(host->flavor,"cygwin")
- && strcmp(host->flavor,"midipix")
- && strcmp(host->flavor,"mingw")) {
- host->mdso = "";
- cfgmeta->mdso = "not applicable";
-
- } else {
- if (!(drvhost->mdso = calloc(1,toollen)))
- return -1;
-
- if (fnative) {
- strcpy(drvhost->mdso,"mdso");
- cfgmeta->mdso = cfgnative;
- } else {
- sprintf(drvhost->mdso,"%s-mdso",host->host);
- cfgmeta->mdso = cfghost;
- }
-
- host->mdso = drvhost->mdso;
- }
-
- return 0;
-}
-
-static void slbt_free_host_params(struct slbt_host_strs * host)
-{
- if (host->machine)
- free(host->machine);
-
- if (host->host)
- free(host->host);
-
- if (host->flavor)
- free(host->flavor);
-
- if (host->ar)
- free(host->ar);
-
- if (host->ranlib)
- free(host->ranlib);
-
- if (host->windres)
- free(host->windres);
-
- if (host->dlltool)
- free(host->dlltool);
-
- if (host->mdso)
- free(host->mdso);
-
- memset(host,0,sizeof(*host));
-}
-
-static void slbt_init_flavor_settings(
- struct slbt_common_ctx * cctx,
- const struct slbt_host_params * ahost,
- struct slbt_flavor_settings * psettings)
-{
- const struct slbt_host_params * host;
- const struct slbt_flavor_settings * settings;
-
- host = ahost ? ahost : &cctx->host;
-
- if (!strcmp(host->flavor,"midipix"))
- settings = &host_flavor_midipix;
- else if (!strcmp(host->flavor,"mingw"))
- settings = &host_flavor_mingw;
- else if (!strcmp(host->flavor,"cygwin"))
- settings = &host_flavor_cygwin;
- else if (!strcmp(host->flavor,"darwin"))
- settings = &host_flavor_darwin;
- else
- settings = &host_flavor_default;
-
- if (!ahost) {
- if (!strcmp(settings->imagefmt,"elf"))
- cctx->drvflags |= SLBT_DRIVER_IMAGE_ELF;
- else if (!strcmp(settings->imagefmt,"pe"))
- cctx->drvflags |= SLBT_DRIVER_IMAGE_PE;
- else if (!strcmp(settings->imagefmt,"macho"))
- cctx->drvflags |= SLBT_DRIVER_IMAGE_MACHO;
- }
-
- memcpy(psettings,settings,sizeof(*settings));
-
- if (cctx->shrext)
- psettings->dsosuffix = cctx->shrext;
-}
-
-static int slbt_init_ldrpath(
- struct slbt_common_ctx * cctx,
- struct slbt_host_params * host)
-{
- char * buf;
- const char ** ldrpath;
-
- if (!cctx->rpath || !(cctx->drvflags & SLBT_DRIVER_IMAGE_ELF)) {
- host->ldrpath = 0;
- return 0;
- }
-
- /* common? */
- for (ldrpath=ldrpath_elf; *ldrpath; ldrpath ++)
- if (!(strcmp(cctx->rpath,*ldrpath))) {
- host->ldrpath = 0;
- return 0;
- }
-
- /* buf */
- if (!(buf = malloc(12 + strlen(cctx->host.host))))
- return -1;
-
- /* /usr/{host}/lib */
- sprintf(buf,"/usr/%s/lib",cctx->host.host);
-
- if (!(strcmp(cctx->rpath,buf))) {
- host->ldrpath = 0;
- free(buf);
- return 0;
- }
-
- /* /usr/{host}/lib64 */
- sprintf(buf,"/usr/%s/lib64",cctx->host.host);
-
- if (!(strcmp(cctx->rpath,buf))) {
- host->ldrpath = 0;
- free(buf);
- return 0;
- }
-
- host->ldrpath = cctx->rpath;
-
- free(buf);
- return 0;
-}
-
-static int slbt_init_version_info(
- struct slbt_driver_ctx_impl * ictx,
- struct slbt_version_info * verinfo)
-{
- int current;
- int revision;
- int age;
-
- if (!verinfo->verinfo && !verinfo->vernumber)
- return 0;
-
- if (verinfo->vernumber) {
- sscanf(verinfo->vernumber,"%d:%d:%d",
- &verinfo->major,
- &verinfo->minor,
- &verinfo->revision);
- return 0;
- }
-
- current = revision = age = 0;
-
- sscanf(verinfo->verinfo,"%d:%d:%d",
- &current,&revision,&age);
-
- if (current < age) {
- if (ictx->cctx.drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
- slbt_dprintf(ictx->fdctx.fderr,
- "%s: error: invalid version info: "
- "<current> may not be smaller than <age>.\n",
- argv_program_name(ictx->cctx.targv[0]));
- return -1;
- }
-
- verinfo->major = current - age;
- verinfo->minor = age;
- verinfo->revision = revision;
-
- return 0;
-}
-
-static int slbt_init_link_params(struct slbt_driver_ctx_impl * ctx)
-{
- const char * program;
- const char * libname;
- const char * prefix;
- const char * base;
- char * dot;
- bool fmodule;
- int fderr;
-
- fderr = ctx->fdctx.fderr;
- program = argv_program_name(ctx->cctx.targv[0]);
- libname = 0;
- prefix = 0;
- fmodule = false;
-
- /* output */
- if (!(ctx->cctx.output)) {
- if (ctx->cctx.drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
- slbt_dprintf(fderr,
- "%s: error: output file must be "
- "specified in link mode.\n",
- program);
- return -1;
- }
-
- /* executable? */
- if (!(dot = strrchr(ctx->cctx.output,'.')))
- if (!(ctx->cctx.drvflags & SLBT_DRIVER_MODULE))
- return 0;
-
- /* todo: archive? library? wrapper? inlined function, avoid repetition */
- if ((base = strrchr(ctx->cctx.output,'/')))
- base++;
- else
- base = ctx->cctx.output;
-
- /* archive? */
- if (dot && !strcmp(dot,ctx->cctx.settings.arsuffix)) {
- prefix = ctx->cctx.settings.arprefix;
-
- if (!strncmp(prefix,base,strlen(prefix)))
- libname = base;
- else {
- if (ctx->cctx.drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
- slbt_dprintf(fderr,
- "%s: error: output file prefix does "
- "not match its (archive) suffix; "
- "the expected prefix was '%s'\n",
- program,prefix);
- return -1;
- }
- }
-
- /* library? */
- else if (dot && !strcmp(dot,ctx->cctx.settings.dsosuffix)) {
- prefix = ctx->cctx.settings.dsoprefix;
-
- if (!strncmp(prefix,base,strlen(prefix))) {
- libname = base;
-
- } else if (ctx->cctx.drvflags & SLBT_DRIVER_MODULE) {
- libname = base;
- fmodule = true;
-
- } else {
- if (ctx->cctx.drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
- slbt_dprintf(fderr,
- "%s: error: output file prefix does "
- "not match its (shared library) suffix; "
- "the expected prefix was '%s'\n",
- program,prefix);
- return -1;
- }
- }
-
- /* wrapper? */
- else if (dot && !strcmp(dot,".la")) {
- prefix = ctx->cctx.settings.dsoprefix;
-
- if (!strncmp(prefix,base,strlen(prefix))) {
- libname = base;
- fmodule = !!(ctx->cctx.drvflags & SLBT_DRIVER_MODULE);
- } else if (ctx->cctx.drvflags & SLBT_DRIVER_MODULE) {
- libname = base;
- fmodule = true;
- } else {
- if (ctx->cctx.drvflags & SLBT_DRIVER_VERBOSITY_ERRORS)
- slbt_dprintf(fderr,
- "%s: error: output file prefix does "
- "not match its (libtool wrapper) suffix; "
- "the expected prefix was '%s'\n",
- program,prefix);
- return -1;
- }
- } else
- return 0;
-
- /* libname alloc */
- if (!fmodule)
- libname += strlen(prefix);
-
- if (!(ctx->libname = strdup(libname)))
- return -1;
-
- if ((dot = strrchr(ctx->libname,'.')))
- *dot = 0;
-
- ctx->cctx.libname = ctx->libname;
-
- return 0;
-}
static int slbt_driver_fail_incompatible_args(
int fderr,
@@ -1331,19 +379,28 @@ static int slbt_driver_fail_incompatible_args(
aclr_reset);
}
- return slbt_get_driver_ctx_fail(0,meta);
+ return slbt_lib_get_driver_ctx_fail(0,meta);
+}
+
+
+static int slbt_driver_parse_tool_argv(const char * tool, char *** tool_argv)
+{
+ return slbt_txtline_to_string_vector(tool,tool_argv);
}
-int slbt_get_driver_ctx(
+
+int slbt_lib_get_driver_ctx(
char ** argv,
char ** envp,
- uint32_t flags,
+ uint64_t flags,
const struct slbt_fd_ctx * fdctx,
struct slbt_driver_ctx ** pctx)
{
struct slbt_split_vector sargv;
+ struct slbt_obj_list * objlistv;
struct slbt_driver_ctx_impl * ctx;
struct slbt_common_ctx cctx;
+ struct slbt_error_info** errinfp;
const struct argv_option * optv[SLBT_OPTV_ELEMENTS];
struct argv_meta * meta;
struct argv_entry * entry;
@@ -1353,9 +410,26 @@ int slbt_get_driver_ctx(
struct argv_entry * cmdnoshared;
const char * program;
const char * lconf;
+ const char * mkvars;
uint64_t lflags;
+ size_t ndlopen;
+ struct argv_entry ** dlopenv;
+ const char * cfgmeta_host;
+ const char * cfgmeta_ar;
+ const char * cfgmeta_as;
+ const char * cfgmeta_nm;
+ const char * cfgmeta_ranlib;
+ const char * cfgmeta_dlltool;
+
+ if (flags & SLBT_DRIVER_MODE_AR) {
+ argv_optv_init(slbt_ar_options,optv);
- argv_optv_init(slbt_default_options,optv);
+ } else if (flags & SLBT_DRIVER_MODE_STOOLIE) {
+ argv_optv_init(slbt_stoolie_options,optv);
+
+ } else {
+ argv_optv_init(slbt_default_options,optv);
+ }
if (!fdctx)
fdctx = &slbt_default_fdctx;
@@ -1364,23 +438,40 @@ int slbt_get_driver_ctx(
sargv.dargv = 0;
sargv.targv = 0;
sargv.cargv = 0;
+ objlistv = 0;
+ ndlopen = 0;
+
+ switch (slbt_split_argv(argv,flags,&sargv,&objlistv,fdctx->fderr,fdctx->fdcwd)) {
+ case SLBT_OK:
+ break;
- if (slbt_split_argv(argv,flags,&sargv,fdctx->fderr))
- return slbt_free_argv_buffer(&sargv);
+ case SLBT_USAGE:
+ return SLBT_USAGE;
+
+ default:
+ return slbt_free_argv_buffer(&sargv,objlistv);
+ }
if (!(meta = argv_get(
sargv.targv,optv,
slbt_argv_flags(flags),
fdctx->fderr)))
- return slbt_free_argv_buffer(&sargv);
+ return slbt_free_argv_buffer(&sargv,objlistv);
lconf = 0;
+ mkvars = 0;
program = argv_program_name(argv[0]);
memset(&cctx,0,sizeof(cctx));
- /* shared and static objects: enable by default, disable by ~switch */
- cctx.drvflags = flags | SLBT_DRIVER_SHARED | SLBT_DRIVER_STATIC;
+ if (flags & SLBT_DRIVER_MODE_AR)
+ cctx.mode = SLBT_MODE_AR;
+
+ else if (flags & SLBT_DRIVER_MODE_STOOLIE)
+ cctx.mode = SLBT_MODE_STOOLIE;
+
+ /* default flags (set at compile time and derived from symlink) */
+ cctx.drvflags = flags;
/* full annotation when annotation is on; */
if (!(cctx.drvflags & SLBT_DRIVER_ANNOTATE_NEVER))
@@ -1392,6 +483,13 @@ int slbt_get_driver_ctx(
cmdnostatic = 0;
cmdnoshared = 0;
+ cfgmeta_host = 0;
+ cfgmeta_ar = 0;
+ cfgmeta_as = 0;
+ cfgmeta_nm = 0;
+ cfgmeta_ranlib = 0;
+ cfgmeta_dlltool = 0;
+
/* get options */
for (entry=meta->entries; entry->fopt || entry->arg; entry++) {
if (entry->fopt) {
@@ -1401,6 +499,8 @@ int slbt_get_driver_ctx(
switch (cctx.mode) {
case SLBT_MODE_INSTALL:
case SLBT_MODE_UNINSTALL:
+ case SLBT_MODE_AR:
+ case SLBT_MODE_STOOLIE:
break;
default:
@@ -1408,7 +508,7 @@ int slbt_get_driver_ctx(
? slbt_driver_usage(
fdctx->fdout,program,
entry->arg,optv,
- meta,&sargv,
+ meta,&sargv,objlistv,
(cctx.drvflags & SLBT_DRIVER_ANNOTATE_NEVER))
: SLBT_USAGE;
}
@@ -1424,6 +524,10 @@ int slbt_get_driver_ctx(
lconf = entry->arg;
break;
+ case TAG_MKVARS:
+ mkvars = entry->arg;
+ break;
+
case TAG_MODE:
if (!strcmp("clean",entry->arg))
cctx.mode = SLBT_MODE_CLEAN;
@@ -1445,6 +549,15 @@ int slbt_get_driver_ctx(
else if (!strcmp("uninstall",entry->arg))
cctx.mode = SLBT_MODE_UNINSTALL;
+
+ else if (!strcmp("ar",entry->arg))
+ cctx.mode = SLBT_MODE_AR;
+
+ else if (!strcmp("stoolie",entry->arg))
+ cctx.mode = SLBT_MODE_STOOLIE;
+
+ else if (!strcmp("slibtoolize",entry->arg))
+ cctx.mode = SLBT_MODE_STOOLIE;
break;
case TAG_FINISH:
@@ -1468,6 +581,9 @@ int slbt_get_driver_ctx(
else if (!strcmp("F77",entry->arg))
cctx.tag = SLBT_TAG_F77;
+ else if (!strcmp("ASM",entry->arg))
+ cctx.tag = SLBT_TAG_ASM;
+
else if (!strcmp("NASM",entry->arg))
cctx.tag = SLBT_TAG_NASM;
@@ -1481,14 +597,26 @@ int slbt_get_driver_ctx(
cmdnoshared = entry;
break;
+ case TAG_INFO:
+ cctx.drvflags |= SLBT_DRIVER_INFO;
+ break;
+
case TAG_CONFIG:
- cctx.drvflags |= SLBT_DRIVER_CONFIG;
+ cctx.drvflags |= SLBT_DRIVER_OUTPUT_CONFIG;
break;
case TAG_DUMPMACHINE:
cctx.drvflags |= SLBT_DRIVER_OUTPUT_MACHINE;
break;
+ case TAG_PRINT_AUX_DIR:
+ cctx.drvflags |= SLBT_DRIVER_OUTPUT_AUX_DIR;
+ break;
+
+ case TAG_PRINT_M4_DIR:
+ cctx.drvflags |= SLBT_DRIVER_OUTPUT_M4_DIR;
+ break;
+
case TAG_DEBUG:
cctx.drvflags |= SLBT_DRIVER_DEBUG;
break;
@@ -1568,6 +696,7 @@ int slbt_get_driver_ctx(
case TAG_HOST:
cctx.host.host = entry->arg;
+ cfgmeta_host = cfgexplicit;
break;
case TAG_FLAVOR:
@@ -1576,10 +705,22 @@ int slbt_get_driver_ctx(
case TAG_AR:
cctx.host.ar = entry->arg;
+ cfgmeta_ar = cfgexplicit;
+ break;
+
+ case TAG_AS:
+ cctx.host.as = entry->arg;
+ cfgmeta_as = cfgexplicit;
+ break;
+
+ case TAG_NM:
+ cctx.host.nm = entry->arg;
+ cfgmeta_nm = cfgexplicit;
break;
case TAG_RANLIB:
cctx.host.ranlib = entry->arg;
+ cfgmeta_ranlib = cfgexplicit;
break;
case TAG_WINDRES:
@@ -1588,6 +729,7 @@ int slbt_get_driver_ctx(
case TAG_DLLTOOL:
cctx.host.dlltool = entry->arg;
+ cfgmeta_dlltool = cfgexplicit;
break;
case TAG_MDSO:
@@ -1615,6 +757,8 @@ int slbt_get_driver_ctx(
break;
case TAG_DLOPEN:
+ case TAG_DLPREOPEN:
+ ndlopen++;
break;
case TAG_STATIC_LIBTOOL_LIBS:
@@ -1625,11 +769,11 @@ int slbt_get_driver_ctx(
cctx.drvflags |= SLBT_DRIVER_EXPORT_DYNAMIC;
break;
- case TAG_EXPSYM_FILE:
- cctx.symfile = entry->arg;
+ case TAG_EXPSYMS_FILE:
+ cctx.expsyms = entry->arg;
break;
- case TAG_EXPSYM_REGEX:
+ case TAG_EXPSYMS_REGEX:
cctx.regex = entry->arg;
break;
@@ -1679,15 +823,29 @@ int slbt_get_driver_ctx(
case TAG_SHARED:
cmdshared = entry;
+ cctx.drvflags |= SLBT_DRIVER_PREFER_SHARED;
break;
case TAG_STATIC:
cmdstatic = entry;
+ cctx.drvflags |= SLBT_DRIVER_PREFER_STATIC;
+ break;
+
+ case TAG_WEAK:
break;
}
}
}
+ /* enable both shared and static targets by default as appropriate */
+ if (!(cctx.drvflags & SLBT_DRIVER_HEURISTICS)) {
+ if (!cmdnoshared)
+ cctx.drvflags |= SLBT_DRIVER_SHARED;
+
+ if (!cmdnostatic)
+ cctx.drvflags |= SLBT_DRIVER_STATIC;
+ }
+
/* incompatible command-line arguments? */
if (cmdstatic && cmdshared)
return slbt_driver_fail_incompatible_args(
@@ -1721,6 +879,14 @@ int slbt_get_driver_ctx(
"--disable-static",
"--disable-shared");
+ if (lconf && mkvars)
+ return slbt_driver_fail_incompatible_args(
+ fdctx->fderr,
+ cctx.drvflags,
+ meta,program,
+ "--heuristics=<cfgfile>",
+ "--mkvars=<makefile>");
+
/* -static? */
if (cmdstatic) {
cctx.drvflags |= SLBT_DRIVER_STATIC;
@@ -1760,8 +926,12 @@ int slbt_get_driver_ctx(
cctx.output = 0;
}
+ /* config mode */
+ if (cctx.drvflags & SLBT_DRIVER_OUTPUT_CONFIG)
+ cctx.mode = SLBT_MODE_CONFIG;
+
/* info mode */
- if (cctx.drvflags & (SLBT_DRIVER_CONFIG | SLBT_DRIVER_FEATURES))
+ if (cctx.drvflags & (SLBT_DRIVER_INFO | SLBT_DRIVER_FEATURES))
cctx.mode = SLBT_MODE_INFO;
/* --tag */
@@ -1769,9 +939,13 @@ int slbt_get_driver_ctx(
if (cctx.tag == SLBT_TAG_UNKNOWN)
cctx.tag = SLBT_TAG_CC;
+ /* dlopen/dlpreopen: first vector member is a virtual archive */
+ if (ndlopen)
+ ndlopen++;
+
/* driver context */
- if (!(ctx = slbt_driver_ctx_alloc(meta,fdctx,&cctx,&sargv,envp)))
- return slbt_get_driver_ctx_fail(0,meta);
+ if (!(ctx = slbt_driver_ctx_alloc(fdctx,&cctx,&sargv,objlistv,envp,ndlopen)))
+ return slbt_lib_get_driver_ctx_fail(0,meta);
/* ctx */
ctx->ctx.program = program;
@@ -1779,11 +953,30 @@ int slbt_get_driver_ctx(
ctx->cctx.targv = sargv.targv;
ctx->cctx.cargv = sargv.cargv;
+ ctx->meta = meta;
- /* heuristics */
- if (cctx.drvflags & SLBT_DRIVER_HEURISTICS) {
- if (slbt_get_lconf_flags(&ctx->ctx,lconf,&lflags) < 0)
- return slbt_get_driver_ctx_fail(&ctx->ctx,0);
+ /* mkvars */
+ if (mkvars) {
+ if (slbt_get_mkvars_flags(&ctx->ctx,mkvars,&lflags) < 0)
+ return slbt_lib_get_driver_ctx_fail(&ctx->ctx,0);
+
+ if (ctx->cctx.host.host && !cfgmeta_host)
+ cfgmeta_host = cfgmkvars;
+
+ if (ctx->cctx.host.ar && !cfgmeta_ar)
+ cfgmeta_ar = cfgmkvars;
+
+ if (ctx->cctx.host.as && !cfgmeta_as)
+ cfgmeta_as = cfgmkvars;
+
+ if (ctx->cctx.host.nm && !cfgmeta_nm)
+ cfgmeta_nm = cfgmkvars;
+
+ if (ctx->cctx.host.ranlib && !cfgmeta_ranlib)
+ cfgmeta_ranlib = cfgmkvars;
+
+ if (ctx->cctx.host.dlltool && !cfgmeta_dlltool)
+ cfgmeta_dlltool = cfgmkvars;
if (cmdnoshared)
lflags &= ~(uint64_t)SLBT_DRIVER_DISABLE_STATIC;
@@ -1793,19 +986,77 @@ int slbt_get_driver_ctx(
cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_DISABLE_STATIC;
cctx.drvflags |= lflags;
- cctx.drvflags |= SLBT_DRIVER_SHARED;
- cctx.drvflags |= SLBT_DRIVER_STATIC;
- if (cmdstatic) {
- cctx.drvflags |= SLBT_DRIVER_DISABLE_SHARED;
- cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_DISABLE_STATIC;
- }
+ /* -disable-static? */
+ if (cctx.drvflags & SLBT_DRIVER_DISABLE_STATIC)
+ cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_STATIC;
- if (cmdshared) {
- cctx.drvflags |= SLBT_DRIVER_DISABLE_STATIC;
- cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_DISABLE_SHARED;
+ /* -disable-shared? */
+ if (cctx.drvflags & SLBT_DRIVER_DISABLE_SHARED)
+ cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_SHARED;
+
+ ctx->cctx.drvflags = cctx.drvflags;
+ }
+
+ /* heuristics */
+ if (mkvars)
+ cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_HEURISTICS;
+
+ if (cctx.drvflags & SLBT_DRIVER_HEURISTICS) {
+ if (slbt_get_lconf_flags(&ctx->ctx,lconf,&lflags,false) < 0)
+ return slbt_lib_get_driver_ctx_fail(&ctx->ctx,0);
+ } else {
+ switch (cctx.mode) {
+ case SLBT_MODE_UNKNOWN:
+ case SLBT_MODE_STOOLIE:
+ break;
+
+ case SLBT_MODE_CONFIG:
+ lconf = mkvars ? 0 : "slibtool.cfg";
+ break;
+
+ default:
+ lconf = "slibtool.cfg";
+ break;
}
+ if (lconf && (errinfp = ctx->errinfp))
+ if (slbt_get_lconf_flags(&ctx->ctx,lconf,&lflags,true) < 0)
+ for (ctx->errinfp=errinfp; *errinfp; errinfp++)
+ *errinfp = 0;
+
+ if (ctx->lconfctx)
+ cctx.drvflags |= SLBT_DRIVER_HEURISTICS;
+ }
+
+ if (cctx.drvflags & SLBT_DRIVER_HEURISTICS) {
+ if (ctx->cctx.host.host && !cfgmeta_host)
+ cfgmeta_host = cfglconf;
+
+ if (ctx->cctx.host.ar && !cfgmeta_ar)
+ cfgmeta_ar = cfglconf;
+
+ if (ctx->cctx.host.as && !cfgmeta_as)
+ cfgmeta_as = cfglconf;
+
+ if (ctx->cctx.host.nm && !cfgmeta_nm)
+ cfgmeta_nm = cfglconf;
+
+ if (ctx->cctx.host.ranlib && !cfgmeta_ranlib)
+ cfgmeta_ranlib = cfglconf;
+
+ if (ctx->cctx.host.dlltool && !cfgmeta_dlltool)
+ cfgmeta_dlltool = cfglconf;
+
+ if (cmdnoshared)
+ lflags &= ~(uint64_t)SLBT_DRIVER_DISABLE_STATIC;
+
+ if (cmdnostatic)
+ if (lflags & SLBT_DRIVER_DISABLE_SHARED)
+ cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_DISABLE_STATIC;
+
+ cctx.drvflags |= lflags;
+
/* -disable-static? */
if (cctx.drvflags & SLBT_DRIVER_DISABLE_STATIC)
cctx.drvflags &= ~(uint64_t)SLBT_DRIVER_STATIC;
@@ -1823,8 +1074,33 @@ int slbt_get_driver_ctx(
&ctx->cctx,
&ctx->host,
&ctx->cctx.host,
- &ctx->cctx.cfgmeta))
- return slbt_get_driver_ctx_fail(&ctx->ctx,0);
+ &ctx->cctx.cfgmeta,
+ cfgmeta_host,
+ cfgmeta_ar,
+ cfgmeta_as,
+ cfgmeta_nm,
+ cfgmeta_ranlib,
+ cfgmeta_dlltool))
+ return slbt_lib_get_driver_ctx_fail(&ctx->ctx,0);
+
+ /* host tool arguments */
+ if (slbt_driver_parse_tool_argv(ctx->cctx.host.ar,&ctx->host.ar_argv) < 0)
+ return slbt_lib_get_driver_ctx_fail(&ctx->ctx,0);
+
+ if (slbt_driver_parse_tool_argv(ctx->cctx.host.nm,&ctx->host.nm_argv) < 0)
+ return slbt_lib_get_driver_ctx_fail(&ctx->ctx,0);
+
+ if (slbt_driver_parse_tool_argv(ctx->cctx.host.ranlib,&ctx->host.ranlib_argv) < 0)
+ return slbt_lib_get_driver_ctx_fail(&ctx->ctx,0);
+
+ if (slbt_driver_parse_tool_argv(ctx->cctx.host.as,&ctx->host.as_argv) < 0)
+ return slbt_lib_get_driver_ctx_fail(&ctx->ctx,0);
+
+ if (slbt_driver_parse_tool_argv(ctx->cctx.host.dlltool,&ctx->host.dlltool_argv) < 0)
+ return slbt_lib_get_driver_ctx_fail(&ctx->ctx,0);
+
+ if (slbt_driver_parse_tool_argv(ctx->cctx.host.mdso,&ctx->host.mdso_argv) < 0)
+ return slbt_lib_get_driver_ctx_fail(&ctx->ctx,0);
/* flavor settings */
slbt_init_flavor_settings(
@@ -1833,26 +1109,83 @@ int slbt_get_driver_ctx(
/* ldpath */
if (slbt_init_ldrpath(&ctx->cctx,&ctx->cctx.host))
- return slbt_get_driver_ctx_fail(&ctx->ctx,0);
+ return slbt_lib_get_driver_ctx_fail(&ctx->ctx,0);
/* version info */
if (slbt_init_version_info(ctx,&ctx->cctx.verinfo))
- return slbt_get_driver_ctx_fail(&ctx->ctx,0);
+ return slbt_lib_get_driver_ctx_fail(&ctx->ctx,0);
/* link params */
if (cctx.mode == SLBT_MODE_LINK)
if (slbt_init_link_params(ctx))
- return slbt_get_driver_ctx_fail(&ctx->ctx,0);
+ return slbt_lib_get_driver_ctx_fail(&ctx->ctx,0);
+ /* dlpreopen */
+ if ((dlopenv = ctx->dlopenv)) {
+ for (entry=meta->entries; entry->fopt || entry->arg; entry++) {
+ if (entry->fopt) {
+ switch (entry->tag) {
+ case TAG_DLOPEN:
+ 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:
+ 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;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ /* -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;
return 0;
}
-static void slbt_free_driver_ctx_impl(struct slbt_driver_ctx_alloc * ictx)
+
+static void slbt_lib_free_driver_ctx_impl(struct slbt_driver_ctx_alloc * ictx)
{
struct slbt_error_info ** perr;
struct slbt_error_info * erri;
+ struct slbt_obj_list * objlistp;
for (perr=ictx->ctx.errinfp; *perr; perr++) {
erri = *perr;
@@ -1861,21 +1194,43 @@ static void slbt_free_driver_ctx_impl(struct slbt_driver_ctx_alloc * ictx)
free(erri->eany);
}
-
if (ictx->ctx.libname)
free(ictx->ctx.libname);
+ if (ictx->ctx.dlopenv)
+ free(ictx->ctx.dlopenv);
+
+ if (ictx->ctx.lconf.addr)
+ munmap(
+ ictx->ctx.lconf.addr,
+ ictx->ctx.lconf.size);
+
+ if (ictx->ctx.lconfctx)
+ slbt_lib_free_txtfile_ctx(ictx->ctx.lconfctx);
+
+ if (ictx->ctx.mkvarsctx)
+ slbt_lib_free_txtfile_ctx(ictx->ctx.mkvarsctx);
+
+ for (objlistp=ictx->ctx.objlistv; objlistp->name; objlistp++) {
+ free(objlistp->objv);
+ free(objlistp->addr);
+ }
+
+ free(ictx->ctx.objlistv);
+
free(ictx->ctx.dargs);
free(ictx->ctx.dargv);
free(ictx->ctx.targv);
slbt_free_host_params(&ictx->ctx.host);
slbt_free_host_params(&ictx->ctx.ahost);
- argv_free(ictx->meta);
+ argv_free(ictx->ctx.meta);
+
free(ictx);
}
-void slbt_free_driver_ctx(struct slbt_driver_ctx * ctx)
+
+void slbt_lib_free_driver_ctx(struct slbt_driver_ctx * ctx)
{
struct slbt_driver_ctx_alloc * ictx;
uintptr_t addr;
@@ -1884,97 +1239,18 @@ void slbt_free_driver_ctx(struct slbt_driver_ctx * ctx)
addr = (uintptr_t)ctx - offsetof(struct slbt_driver_ctx_impl,ctx);
addr = addr - offsetof(struct slbt_driver_ctx_alloc,ctx);
ictx = (struct slbt_driver_ctx_alloc *)addr;
- slbt_free_driver_ctx_impl(ictx);
- }
-}
-
-void slbt_reset_alternate_host(const struct slbt_driver_ctx * ctx)
-{
- struct slbt_driver_ctx_alloc * ictx;
- uintptr_t addr;
-
- addr = (uintptr_t)ctx - offsetof(struct slbt_driver_ctx_alloc,ctx);
- addr = addr - offsetof(struct slbt_driver_ctx_impl,ctx);
- ictx = (struct slbt_driver_ctx_alloc *)addr;
-
- slbt_free_host_params(&ictx->ctx.ahost);
-}
-
-int slbt_set_alternate_host(
- const struct slbt_driver_ctx * ctx,
- const char * host,
- const char * flavor)
-{
- struct slbt_driver_ctx_alloc * ictx;
- uintptr_t addr;
-
- addr = (uintptr_t)ctx - offsetof(struct slbt_driver_ctx_alloc,ctx);
- addr = addr - offsetof(struct slbt_driver_ctx_impl,ctx);
- ictx = (struct slbt_driver_ctx_alloc *)addr;
- slbt_free_host_params(&ictx->ctx.ahost);
-
- if (!(ictx->ctx.ahost.host = strdup(host)))
- return SLBT_SYSTEM_ERROR(ctx,0);
-
- if (!(ictx->ctx.ahost.flavor = strdup(flavor))) {
- slbt_free_host_params(&ictx->ctx.ahost);
- return SLBT_SYSTEM_ERROR(ctx,0);
- }
-
- ictx->ctx.cctx.ahost.host = ictx->ctx.ahost.host;
- ictx->ctx.cctx.ahost.flavor = ictx->ctx.ahost.flavor;
-
- if (slbt_init_host_params(
- 0,
- ctx->cctx,
- &ictx->ctx.ahost,
- &ictx->ctx.cctx.ahost,
- &ictx->ctx.cctx.acfgmeta)) {
- slbt_free_host_params(&ictx->ctx.ahost);
- return SLBT_CUSTOM_ERROR(ctx,SLBT_ERR_HOST_INIT);
+ slbt_lib_free_driver_ctx_impl(ictx);
}
-
- slbt_init_flavor_settings(
- &ictx->ctx.cctx,
- &ictx->ctx.cctx.ahost,
- &ictx->ctx.cctx.asettings);
-
- if (slbt_init_ldrpath(
- &ictx->ctx.cctx,
- &ictx->ctx.cctx.ahost)) {
- slbt_free_host_params(&ictx->ctx.ahost);
- return SLBT_CUSTOM_ERROR(ctx,SLBT_ERR_LDRPATH_INIT);
- }
-
- return 0;
}
-int slbt_get_flavor_settings(
- const char * flavor,
- const struct slbt_flavor_settings ** settings)
-{
- if (!strcmp(flavor,"midipix"))
- *settings = &host_flavor_midipix;
- else if (!strcmp(flavor,"mingw"))
- *settings = &host_flavor_mingw;
- else if (!strcmp(flavor,"cygwin"))
- *settings = &host_flavor_cygwin;
- else if (!strcmp(flavor,"darwin"))
- *settings = &host_flavor_darwin;
- else if (!strcmp(flavor,"default"))
- *settings = &host_flavor_default;
- else
- *settings = 0;
-
- return *settings ? 0 : -1;
-}
-const struct slbt_source_version * slbt_source_version(void)
+const struct slbt_source_version * slbt_api_source_version(void)
{
return &slbt_src_version;
}
-int slbt_get_driver_fdctx(
+
+int slbt_lib_get_driver_fdctx(
const struct slbt_driver_ctx * dctx,
struct slbt_fd_ctx * fdctx)
{
@@ -1992,7 +1268,8 @@ int slbt_get_driver_fdctx(
return 0;
}
-int slbt_set_driver_fdctx(
+
+int slbt_lib_set_driver_fdctx(
struct slbt_driver_ctx * dctx,
const struct slbt_fd_ctx * fdctx)
{