diff options
Diffstat (limited to 'src/driver/slbt_driver_ctx.c')
-rw-r--r-- | src/driver/slbt_driver_ctx.c | 650 |
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) |