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.c650
1 files changed, 8 insertions, 642 deletions
diff --git a/src/driver/slbt_driver_ctx.c b/src/driver/slbt_driver_ctx.c
index 126dc85..ec468a2 100644
--- a/src/driver/slbt_driver_ctx.c
+++ b/src/driver/slbt_driver_ctx.c
@@ -26,6 +26,10 @@
extern char ** environ;
+/* annotation strings */
+static const char cfgexplicit[] = "command-line argument";
+static const char cfglconf[] = "derived from <libtool>";
+
/* package info */
static const struct slbt_source_version slbt_src_version = {
SLBT_TAG_VER_MAJOR,
@@ -44,72 +48,9 @@ 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");
-
-
-/* annotation strings */
-static const char cfgexplicit[] = "command-line argument";
-static const char cfghost[] = "derived from <host>";
-static const char cfglconf[] = "derived from <libtool>";
-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";
@@ -119,11 +60,6 @@ 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)
{
@@ -774,499 +710,6 @@ static int slbt_split_argv(
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,
- const char * cfgmeta_ar,
- const char * cfgmeta_ranlib)
-{
- 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 = cfgmeta_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 = cfgmeta_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,
@@ -2023,6 +1466,7 @@ int slbt_get_driver_ctx(
return 0;
}
+
static void slbt_free_driver_ctx_impl(struct slbt_driver_ctx_alloc * ictx)
{
struct slbt_error_info ** perr;
@@ -2057,6 +1501,7 @@ static void slbt_free_driver_ctx_impl(struct slbt_driver_ctx_alloc * ictx)
free(ictx);
}
+
void slbt_free_driver_ctx(struct slbt_driver_ctx * ctx)
{
struct slbt_driver_ctx_alloc * ictx;
@@ -2070,93 +1515,13 @@ void slbt_free_driver_ctx(struct slbt_driver_ctx * ctx)
}
}
-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,
- 0,0)) {
- slbt_free_host_params(&ictx->ctx.ahost);
- return SLBT_CUSTOM_ERROR(ctx,SLBT_ERR_HOST_INIT);
- }
-
- 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)
{
return &slbt_src_version;
}
+
int slbt_get_driver_fdctx(
const struct slbt_driver_ctx * dctx,
struct slbt_fd_ctx * fdctx)
@@ -2175,6 +1540,7 @@ int slbt_get_driver_fdctx(
return 0;
}
+
int slbt_set_driver_fdctx(
struct slbt_driver_ctx * dctx,
const struct slbt_fd_ctx * fdctx)