|
|
528799 |
/*******************************************************************/
|
|
|
528799 |
/* slibtool: a skinny libtool implementation, written in C */
|
|
|
49181b |
/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */
|
|
|
528799 |
/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
|
|
|
528799 |
/*******************************************************************/
|
|
|
528799 |
|
|
|
528799 |
#include <stdint.h>
|
|
|
528799 |
#include <unistd.h>
|
|
|
528799 |
#include <stdlib.h>
|
|
|
528799 |
#include <string.h>
|
|
|
528799 |
|
|
|
528799 |
#include <slibtool/slibtool.h>
|
|
|
9706fa |
#include "slibtool_driver_impl.h"
|
|
|
39e52e |
#include "slibtool_linkcmd_impl.h"
|
|
|
2a6c45 |
#include "slibtool_errinfo_impl.h"
|
|
|
39e52e |
#include "slibtool_ar_impl.h"
|
|
|
528799 |
|
|
|
39e52e |
#define SLBT_ECTX_LIB_EXTRAS 24
|
|
|
55d6e3 |
#define SLBT_ECTX_SPARE_PTRS 16
|
|
|
528799 |
|
|
|
39e52e |
static int slbt_ectx_free_exec_ctx_impl(
|
|
|
39e52e |
struct slbt_exec_ctx_impl * ictx,
|
|
|
39e52e |
int status);
|
|
|
39e52e |
|
|
|
528799 |
static size_t slbt_parse_comma_separated_flags(
|
|
|
528799 |
const char * str,
|
|
|
528799 |
int * argc)
|
|
|
528799 |
{
|
|
|
528799 |
const char * ch;
|
|
|
528799 |
|
|
|
528799 |
for (ch=str; *ch; ch++)
|
|
|
528799 |
if (*ch == ',')
|
|
|
528799 |
(*argc)++;
|
|
|
528799 |
|
|
|
528799 |
return ch - str;
|
|
|
528799 |
}
|
|
|
528799 |
|
|
|
528799 |
|
|
|
df088e |
static char * slbt_source_file(char ** argv)
|
|
|
df088e |
{
|
|
|
df088e |
char ** parg;
|
|
|
df088e |
char * ch;
|
|
|
df088e |
|
|
|
df088e |
for (parg=argv; *parg; parg++)
|
|
|
df088e |
if ((ch = strrchr(*parg,'.')))
|
|
|
df088e |
if ((!(strcmp(++ch,"s")))
|
|
|
df088e |
|| (!(strcmp(ch,"S")))
|
|
|
533d94 |
|| (!(strcmp(ch,"asm")))
|
|
|
df088e |
|| (!(strcmp(ch,"c")))
|
|
|
df088e |
|| (!(strcmp(ch,"cc")))
|
|
|
855e36 |
|| (!(strcmp(ch,"cpp")))
|
|
|
df088e |
|| (!(strcmp(ch,"cxx"))))
|
|
|
df088e |
return *parg;
|
|
|
df088e |
return 0;
|
|
|
df088e |
}
|
|
|
df088e |
|
|
|
df088e |
|
|
|
5c8c00 |
static int slbt_exec_ctx_tool_argc(char ** argv)
|
|
|
5c8c00 |
{
|
|
|
5c8c00 |
char ** parg;
|
|
|
5c8c00 |
|
|
|
5c8c00 |
if (!(parg = argv))
|
|
|
5c8c00 |
return 0;
|
|
|
5c8c00 |
|
|
|
5c8c00 |
for (; *parg; )
|
|
|
5c8c00 |
parg++;
|
|
|
5c8c00 |
|
|
|
5c8c00 |
return parg - argv + 1;
|
|
|
5c8c00 |
}
|
|
|
5c8c00 |
|
|
|
5c8c00 |
|
|
|
528799 |
static struct slbt_exec_ctx_impl * slbt_exec_ctx_alloc(
|
|
|
528799 |
const struct slbt_driver_ctx * dctx)
|
|
|
528799 |
{
|
|
|
5c8c00 |
struct slbt_driver_ctx_impl * ctx;
|
|
|
528799 |
struct slbt_exec_ctx_impl * ictx;
|
|
|
528799 |
size_t size;
|
|
|
55d6e3 |
size_t slen;
|
|
|
528799 |
int argc;
|
|
|
528799 |
char * args;
|
|
|
e7ddb2 |
char * shadow;
|
|
|
df088e |
char * csrc;
|
|
|
528799 |
char ** parg;
|
|
|
39e52e |
struct slbt_archive_ctx ** dlactxv;
|
|
|
39e52e |
size_t ndlopen;
|
|
|
528799 |
|
|
|
5c8c00 |
/* internal driver context for host-specific tool arguments */
|
|
|
5c8c00 |
ctx = slbt_get_driver_ictx(dctx);
|
|
|
5c8c00 |
|
|
|
55d6e3 |
/* initial buffer size (cargv, -Wc) */
|
|
|
55d6e3 |
argc = 0;
|
|
|
55d6e3 |
csrc = 0;
|
|
|
55d6e3 |
size = 0;
|
|
|
528799 |
|
|
|
55d6e3 |
for (parg=dctx->cctx->cargv; *parg; parg++, argc++) {
|
|
|
55d6e3 |
if (!(strncmp("-Wc,",*parg,4))) {
|
|
|
c59280 |
size += slbt_parse_comma_separated_flags(
|
|
|
c59280 |
&(*parg)[4],&argc) + 1;
|
|
|
55d6e3 |
} else {
|
|
|
c59280 |
size += strlen(*parg) + 1;
|
|
|
55d6e3 |
}
|
|
|
55d6e3 |
}
|
|
|
528799 |
|
|
|
55d6e3 |
/* argument transformation: additive, worst case scenario */
|
|
|
55d6e3 |
size += argc * (strlen(".lo") + 1);
|
|
|
55d6e3 |
size += argc * (strlen(".libs/") + 1);
|
|
|
55d6e3 |
size += argc * (strlen(".0000.0000.0000") + 1);
|
|
|
08f5f9 |
|
|
|
55d6e3 |
/* buffer size (csrc, ldirname, lbasename, lobjname, aobjname, etc.) */
|
|
|
55d6e3 |
if (dctx->cctx->libname) {
|
|
|
55d6e3 |
slen = strlen(dctx->cctx->libname);
|
|
|
55d6e3 |
size += (strlen(".slibtool.expsyms.extension") + slen + 1) * SLBT_ECTX_LIB_EXTRAS;
|
|
|
df088e |
|
|
|
55d6e3 |
} else if (dctx->cctx->output) {
|
|
|
55d6e3 |
slen = strlen(dctx->cctx->output);
|
|
|
55d6e3 |
size += (strlen(".slibtool.expsyms.extension") + slen + 1) * SLBT_ECTX_LIB_EXTRAS;
|
|
|
f0c096 |
|
|
|
55d6e3 |
} else if ((csrc = slbt_source_file(dctx->cctx->cargv))) {
|
|
|
55d6e3 |
slen = strlen(csrc);
|
|
|
55d6e3 |
size += (strlen(".slibtool.expsyms.extension") + slen + 1) * SLBT_ECTX_LIB_EXTRAS;
|
|
|
55d6e3 |
}
|
|
|
55d6e3 |
|
|
|
55d6e3 |
/* string buffers: args, shadow */
|
|
|
df088e |
if (!(args = malloc(size)))
|
|
|
528799 |
return 0;
|
|
|
528799 |
|
|
|
e7ddb2 |
if (!(shadow = malloc(size))) {
|
|
|
e7ddb2 |
free(args);
|
|
|
e7ddb2 |
return 0;
|
|
|
e7ddb2 |
}
|
|
|
e7ddb2 |
|
|
|
55d6e3 |
/* tool-specific argv: to simplify matters, be additive */
|
|
|
55d6e3 |
argc += slbt_exec_ctx_tool_argc(ctx->host.ar_argv);
|
|
|
55d6e3 |
argc += slbt_exec_ctx_tool_argc(ctx->host.as_argv);
|
|
|
55d6e3 |
argc += slbt_exec_ctx_tool_argc(ctx->host.nm_argv);
|
|
|
55d6e3 |
argc += slbt_exec_ctx_tool_argc(ctx->host.ranlib_argv);
|
|
|
55d6e3 |
argc += slbt_exec_ctx_tool_argc(ctx->host.windres_argv);
|
|
|
55d6e3 |
argc += slbt_exec_ctx_tool_argc(ctx->host.dlltool_argv);
|
|
|
55d6e3 |
argc += slbt_exec_ctx_tool_argc(ctx->host.mdso_argv);
|
|
|
55d6e3 |
|
|
|
55d6e3 |
/* argv transformation: .libs/libfoo.so --> -L.libs -lfoo */
|
|
|
55d6e3 |
argc *= 2;
|
|
|
46aa6f |
|
|
|
55d6e3 |
/* argv ad-hoc extensions */
|
|
|
55d6e3 |
argc += SLBT_ECTX_SPARE_PTRS;
|
|
|
528799 |
|
|
|
55d6e3 |
/* ctx alloc and vector alloc: argv, xargv, and altv, where we */
|
|
|
39e52e |
/* assume -Wl,--whole-archive arg -Wl,--no-whole-archive; */
|
|
|
39e52e |
/* and also dlargv for compiling dlunit.dlopen.c */
|
|
|
55d6e3 |
if (!(ictx = calloc(1,sizeof(*ictx)))) {
|
|
|
528799 |
free(args);
|
|
|
e7ddb2 |
free(shadow);
|
|
|
528799 |
return 0;
|
|
|
528799 |
}
|
|
|
528799 |
|
|
|
39e52e |
if (!(ictx->vbuffer = calloc(6*(argc+1),sizeof(char *)))) {
|
|
|
55d6e3 |
free(args);
|
|
|
55d6e3 |
free(shadow);
|
|
|
55d6e3 |
free(ictx);
|
|
|
55d6e3 |
}
|
|
|
55d6e3 |
|
|
|
39e52e |
if ((ndlopen = (slbt_get_driver_ictx(dctx))->ndlopen)) {
|
|
|
39e52e |
if (!(dlactxv = calloc(ndlopen+1,sizeof(*dlactxv)))) {
|
|
|
39e52e |
free(ictx->vbuffer);
|
|
|
39e52e |
free(ictx);
|
|
|
39e52e |
free(args);
|
|
|
39e52e |
free(shadow);
|
|
|
39e52e |
}
|
|
|
39e52e |
|
|
|
39e52e |
ictx->dlactxv = dlactxv;
|
|
|
39e52e |
}
|
|
|
39e52e |
|
|
|
55d6e3 |
/* all ready */
|
|
|
280b99 |
ictx->dctx = dctx;
|
|
|
528799 |
ictx->args = args;
|
|
|
528799 |
ictx->argc = argc;
|
|
|
528799 |
|
|
|
e7ddb2 |
ictx->size = size;
|
|
|
e7ddb2 |
ictx->shadow = shadow;
|
|
|
e7ddb2 |
|
|
|
9706fa |
ictx->ctx.csrc = csrc;
|
|
|
9706fa |
ictx->fdwrapper = (-1);
|
|
|
df088e |
|
|
|
e8bfe5 |
ictx->ctx.envp = slbt_driver_envp(dctx);
|
|
|
e8bfe5 |
|
|
|
528799 |
return ictx;
|
|
|
528799 |
}
|
|
|
528799 |
|
|
|
528799 |
|
|
|
f3d47a |
int slbt_ectx_get_exec_ctx(
|
|
|
528799 |
const struct slbt_driver_ctx * dctx,
|
|
|
528799 |
struct slbt_exec_ctx ** ectx)
|
|
|
528799 |
{
|
|
|
528799 |
struct slbt_exec_ctx_impl * ictx;
|
|
|
39e52e |
struct slbt_driver_ctx_impl * idctx;
|
|
|
528799 |
char ** parg;
|
|
|
d98877 |
char ** src;
|
|
|
d98877 |
char ** dst;
|
|
|
528799 |
char * ch;
|
|
|
014f4c |
char * mark;
|
|
|
7f35de |
const char * dmark;
|
|
|
f47761 |
char * slash;
|
|
|
39e52e |
char * arname;
|
|
|
39e52e |
struct slbt_archive_ctx ** dlactxv;
|
|
|
39e52e |
const char ** dlopenv;
|
|
|
f63307 |
const char * arprefix;
|
|
|
f63307 |
const char * dsoprefix;
|
|
|
2f9f52 |
const char * impprefix;
|
|
|
df088e |
const char * ref;
|
|
|
528799 |
int i;
|
|
|
528799 |
|
|
|
39e52e |
/* internal driver context */
|
|
|
39e52e |
idctx = slbt_get_driver_ictx(dctx);
|
|
|
39e52e |
|
|
|
528799 |
/* alloc */
|
|
|
528799 |
if (!(ictx = slbt_exec_ctx_alloc(dctx)))
|
|
|
2a6c45 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
528799 |
|
|
|
528799 |
/* init with guard for later .lo check */
|
|
|
528799 |
ch = ictx->args + strlen(".lo");
|
|
|
54d0a5 |
ictx->ctx.argv = ictx->vbuffer;
|
|
|
46aa6f |
ictx->ctx.xargv = &ictx->ctx.argv [ictx->argc + 1];
|
|
|
46aa6f |
ictx->ctx.altv = &ictx->ctx.xargv[ictx->argc + 1];
|
|
|
39e52e |
ictx->dlargv = &ictx->ctx.altv [ictx->argc + 1];
|
|
|
528799 |
|
|
|
528799 |
/* <compiler> */
|
|
|
27a8e1 |
ictx->ctx.compiler = dctx->cctx->cargv[0];
|
|
|
27a8e1 |
ictx->ctx.cargv = ictx->ctx.argv;
|
|
|
528799 |
|
|
|
df088e |
/* ldirname, lbasename */
|
|
|
df088e |
ref = (dctx->cctx->output)
|
|
|
df088e |
? dctx->cctx->output
|
|
|
df088e |
: ictx->ctx.csrc;
|
|
|
df088e |
|
|
|
014f4c |
if (ref && !ictx->ctx.csrc && (mark = strrchr(ref,'/'))) {
|
|
|
7f35de |
if (!(strncmp(ref,"../",3)))
|
|
|
7f35de |
dmark = 0;
|
|
|
7f35de |
else if (!(strncmp(ref,"./",2)))
|
|
|
7f35de |
dmark = &ref[1];
|
|
|
7f35de |
else
|
|
|
7f35de |
dmark = strchr(ref,'/');
|
|
|
7f35de |
|
|
|
7f35de |
for (; dmark; ) {
|
|
|
7f35de |
if (!(strncmp(dmark,"/./",3))) {
|
|
|
7f35de |
dmark = strchr(&dmark[2],'/');
|
|
|
7f35de |
} else if (!(strncmp(dmark,"/../",4))) {
|
|
|
7f35de |
ictx->ctx.ldirdepth = -1;
|
|
|
7f35de |
dmark = 0;
|
|
|
7f35de |
} else {
|
|
|
7f35de |
for (; *dmark=='/'; )
|
|
|
7f35de |
dmark++;
|
|
|
7f35de |
|
|
|
7f35de |
ictx->ctx.ldirdepth++;
|
|
|
7f35de |
dmark = strchr(dmark,'/');
|
|
|
7f35de |
}
|
|
|
7f35de |
}
|
|
|
7f35de |
|
|
|
df088e |
ictx->ctx.ldirname = ch;
|
|
|
df088e |
strcpy(ch,ref);
|
|
|
014f4c |
ch += mark - ref;
|
|
|
df088e |
ch += sprintf(ch,"%s","/.libs/");
|
|
|
df088e |
ch++;
|
|
|
df088e |
|
|
|
df088e |
ictx->ctx.lbasename = ch;
|
|
|
014f4c |
ch += sprintf(ch,"%s",++mark);
|
|
|
df088e |
ch++;
|
|
|
df088e |
} else if (ref) {
|
|
|
df088e |
ictx->ctx.ldirname = ch;
|
|
|
df088e |
ch += sprintf(ch,"%s",".libs/");
|
|
|
df088e |
ch++;
|
|
|
df088e |
|
|
|
df088e |
ictx->ctx.lbasename = ch;
|
|
|
014f4c |
mark = strrchr(ref,'/');
|
|
|
014f4c |
ch += sprintf(ch,"%s",mark ? ++mark : ref);
|
|
|
df088e |
ch++;
|
|
|
df088e |
}
|
|
|
df088e |
|
|
|
df088e |
/* lbasename suffix */
|
|
|
df088e |
if (ref && (dctx->cctx->mode == SLBT_MODE_COMPILE)) {
|
|
|
df088e |
if ((ch[-4] == '.') && (ch[-3] == 'l') && (ch[-2] == 'o')) {
|
|
|
df088e |
ch[-3] = 'o';
|
|
|
f7d687 |
ch[-2] = 0;
|
|
|
df088e |
ch--;
|
|
|
df088e |
} else if (ictx->ctx.csrc) {
|
|
|
cae4bb |
if ((mark = strrchr(ictx->ctx.lbasename,'.'))) {
|
|
|
cae4bb |
ch = mark;
|
|
|
df088e |
*++ch = 'o';
|
|
|
f7d687 |
*++ch = 0;
|
|
|
df088e |
ch++;
|
|
|
df088e |
}
|
|
|
df088e |
}
|
|
|
df088e |
}
|
|
|
df088e |
|
|
|
528799 |
/* cargv, -Wc */
|
|
|
528799 |
for (i=0, parg=dctx->cctx->cargv; *parg; parg++, ch++) {
|
|
|
528799 |
if (!(strncmp("-Wc,",*parg,4))) {
|
|
|
4c2181 |
strcpy(ch,&(*parg)[4]);
|
|
|
528799 |
ictx->ctx.argv[i++] = ch;
|
|
|
528799 |
|
|
|
528799 |
for (; *ch; ch++)
|
|
|
528799 |
if (*ch == ',') {
|
|
|
f7d687 |
*ch++ = 0;
|
|
|
869626 |
ictx->ctx.argv[i++] = ch;
|
|
|
528799 |
}
|
|
|
528799 |
} else {
|
|
|
528799 |
ictx->ctx.argv[i++] = ch;
|
|
|
528799 |
ch += sprintf(ch,"%s",*parg);
|
|
|
b6184d |
ch += strlen(".libs/-L-l");
|
|
|
528799 |
}
|
|
|
528799 |
}
|
|
|
528799 |
|
|
|
5aae4b |
/* placeholders for -DPIC, -fPIC, -c, -o, <output> */
|
|
|
5aae4b |
ictx->ctx.dpic = &ictx->ctx.argv[i++];
|
|
|
5aae4b |
ictx->ctx.fpic = &ictx->ctx.argv[i++];
|
|
|
5aae4b |
ictx->ctx.cass = &ictx->ctx.argv[i++];
|
|
|
528799 |
|
|
|
93b62c |
ictx->ctx.noundef = &ictx->ctx.argv[i++];
|
|
|
0f8591 |
ictx->ctx.soname = &ictx->ctx.argv[i++];
|
|
|
0f8591 |
ictx->ctx.lsoname = &ictx->ctx.argv[i++];
|
|
|
e15ee1 |
ictx->ctx.symdefs = &ictx->ctx.argv[i++];
|
|
|
e15ee1 |
ictx->ctx.symfile = &ictx->ctx.argv[i++];
|
|
|
f42074 |
ictx->ctx.explarg = &ictx->ctx.argv[i++];
|
|
|
f42074 |
ictx->ctx.expsyms = &ictx->ctx.argv[i++];
|
|
|
0f8591 |
|
|
|
5aae4b |
ictx->ctx.lout[0] = &ictx->ctx.argv[i++];
|
|
|
5aae4b |
ictx->ctx.lout[1] = &ictx->ctx.argv[i++];
|
|
|
2330a5 |
|
|
|
2330a5 |
ictx->ctx.rpath[0] = &ictx->ctx.argv[i++];
|
|
|
2330a5 |
ictx->ctx.rpath[1] = &ictx->ctx.argv[i++];
|
|
|
2330a5 |
|
|
|
b1f977 |
ictx->ctx.sentinel= &ictx->ctx.argv[i++];
|
|
|
df088e |
|
|
|
62a7c9 |
slbt_reset_placeholders(&ictx->ctx);
|
|
|
62a7c9 |
|
|
|
2f9f52 |
/* dsoprefix */
|
|
|
2f9f52 |
if (dctx->cctx->settings.dsoprefix) {
|
|
|
2f9f52 |
ictx->dsoprefix = ch;
|
|
|
2f9f52 |
strcpy(ch,dctx->cctx->settings.dsoprefix);
|
|
|
2f9f52 |
ch += strlen(ch) + 1;
|
|
|
2f9f52 |
}
|
|
|
2f9f52 |
|
|
|
df088e |
/* output file name */
|
|
|
2691fe |
if (ref && ((dctx->cctx->mode == SLBT_MODE_COMPILE))) {
|
|
|
5aae4b |
*ictx->ctx.lout[0] = "-o";
|
|
|
5aae4b |
*ictx->ctx.lout[1] = ch;
|
|
|
5aae4b |
ictx->ctx.lobjname = ch;
|
|
|
528799 |
|
|
|
e02305 |
ch += sprintf(ch,"%s%s",
|
|
|
df088e |
ictx->ctx.ldirname,
|
|
|
e02305 |
ictx->ctx.lbasename)
|
|
|
c59280 |
+ 1;
|
|
|
e02305 |
|
|
|
e02305 |
ictx->ctx.aobjname = ch;
|
|
|
e02305 |
|
|
|
e02305 |
ch += sprintf(ch,"%s",ictx->ctx.ldirname);
|
|
|
e02305 |
ch -= strlen(".libs/");
|
|
|
e88a39 |
ch += sprintf(ch,"%s",
|
|
|
e88a39 |
ictx->ctx.lbasename)
|
|
|
c59280 |
+ 1;
|
|
|
e88a39 |
|
|
|
e88a39 |
ictx->ctx.ltobjname = ch;
|
|
|
e88a39 |
strcpy(ch,ictx->ctx.aobjname);
|
|
|
e88a39 |
|
|
|
cae4bb |
if ((mark = strrchr(ch,'.')))
|
|
|
cae4bb |
ch = mark + sprintf(mark,"%s",".lo")
|
|
|
c59280 |
+ 1;
|
|
|
528799 |
}
|
|
|
528799 |
|
|
|
f42074 |
/* linking: arfilename, lafilename, laifilename, dsobasename, dsofilename, mapfilename */
|
|
|
731e44 |
if (dctx->cctx->mode == SLBT_MODE_LINK && dctx->cctx->libname) {
|
|
|
f63307 |
/* arprefix, dsoprefix */
|
|
|
f63307 |
if (dctx->cctx->drvflags & SLBT_DRIVER_MODULE) {
|
|
|
2f9f52 |
ictx->ctx.sonameprefix = "";
|
|
|
f63307 |
arprefix = "";
|
|
|
f63307 |
dsoprefix = "";
|
|
|
2f9f52 |
impprefix = "";
|
|
|
f63307 |
} else {
|
|
|
2f9f52 |
ictx->ctx.sonameprefix = ictx->dsoprefix;
|
|
|
f63307 |
arprefix = dctx->cctx->settings.arprefix;
|
|
|
f63307 |
dsoprefix = dctx->cctx->settings.dsoprefix;
|
|
|
2f9f52 |
impprefix = dctx->cctx->settings.impprefix;
|
|
|
f63307 |
}
|
|
|
f63307 |
|
|
|
731e44 |
/* arfilename */
|
|
|
731e44 |
ictx->ctx.arfilename = ch;
|
|
|
731e44 |
ch += sprintf(ch,"%s%s%s%s",
|
|
|
731e44 |
ictx->ctx.ldirname,
|
|
|
f63307 |
arprefix,
|
|
|
731e44 |
dctx->cctx->libname,
|
|
|
c59280 |
dctx->cctx->settings.arsuffix);
|
|
|
c59280 |
ch++;
|
|
|
731e44 |
|
|
|
731e44 |
|
|
|
731e44 |
|
|
|
731e44 |
/* lafilename */
|
|
|
731e44 |
ictx->ctx.lafilename = ch;
|
|
|
731e44 |
ch += sprintf(ch,"%s%s%s.la",
|
|
|
731e44 |
ictx->ctx.ldirname,
|
|
|
f63307 |
dsoprefix,
|
|
|
c59280 |
dctx->cctx->libname);
|
|
|
c59280 |
ch++;
|
|
|
731e44 |
|
|
|
731e44 |
|
|
|
26ea30 |
/* laifilename */
|
|
|
26ea30 |
ictx->ctx.laifilename = ch;
|
|
|
26ea30 |
ch += sprintf(ch,"%s%s%s.lai",
|
|
|
26ea30 |
ictx->ctx.ldirname,
|
|
|
26ea30 |
dsoprefix,
|
|
|
26ea30 |
dctx->cctx->libname);
|
|
|
26ea30 |
ch++;
|
|
|
26ea30 |
|
|
|
26ea30 |
|
|
|
08f5f9 |
/* dsobasename */
|
|
|
08f5f9 |
ictx->ctx.dsobasename = ch;
|
|
|
08f5f9 |
ch += sprintf(ch,"%s%s%s",
|
|
|
08f5f9 |
ictx->ctx.ldirname,
|
|
|
08f5f9 |
dsoprefix,
|
|
|
08f5f9 |
dctx->cctx->libname);
|
|
|
08f5f9 |
ch++;
|
|
|
08f5f9 |
|
|
|
731e44 |
/* dsofilename */
|
|
|
731e44 |
ictx->ctx.dsofilename = ch;
|
|
|
731e44 |
ch += sprintf(ch,"%s%s%s%s",
|
|
|
731e44 |
ictx->ctx.ldirname,
|
|
|
f63307 |
dsoprefix,
|
|
|
731e44 |
dctx->cctx->libname,
|
|
|
c59280 |
dctx->cctx->settings.dsosuffix);
|
|
|
c59280 |
ch++;
|
|
|
b4491f |
|
|
|
f42074 |
/* mapfilename */
|
|
|
f42074 |
ictx->ctx.mapfilename = ch;
|
|
|
f42074 |
ch += sprintf(ch,"%s%s%s%s%s%s",
|
|
|
f42074 |
ictx->ctx.ldirname,
|
|
|
f42074 |
dsoprefix,
|
|
|
f42074 |
dctx->cctx->libname,
|
|
|
f42074 |
dctx->cctx->release ? "-" : "",
|
|
|
f42074 |
dctx->cctx->release ? dctx->cctx->release : "",
|
|
|
f42074 |
dctx->cctx->settings.mapsuffix);
|
|
|
f42074 |
ch++;
|
|
|
f42074 |
|
|
|
b4491f |
/* deffilename */
|
|
|
b4491f |
ictx->ctx.deffilename = ch;
|
|
|
8b2e8d |
ch += sprintf(ch,"%s%s%s%s%s%s.def",
|
|
|
b4491f |
ictx->ctx.ldirname,
|
|
|
f63307 |
dsoprefix,
|
|
|
b4491f |
dctx->cctx->libname,
|
|
|
8b2e8d |
dctx->cctx->release ? "-" : "",
|
|
|
8b2e8d |
dctx->cctx->release ? dctx->cctx->release : "",
|
|
|
c59280 |
dctx->cctx->settings.dsosuffix);
|
|
|
c59280 |
ch++;
|
|
|
1677f4 |
|
|
|
2330a5 |
/* rpathfilename */
|
|
|
2330a5 |
ictx->ctx.rpathfilename = ch;
|
|
|
2330a5 |
ch += sprintf(ch,"%s%s%s%s.slibtool.rpath",
|
|
|
2330a5 |
ictx->ctx.ldirname,
|
|
|
2330a5 |
dsoprefix,
|
|
|
2330a5 |
dctx->cctx->libname,
|
|
|
2330a5 |
dctx->cctx->settings.dsosuffix);
|
|
|
2330a5 |
ch++;
|
|
|
2330a5 |
|
|
|
1677f4 |
/* default implib file name */
|
|
|
1677f4 |
ictx->ctx.dimpfilename = ch;
|
|
|
1677f4 |
ch += sprintf(ch,"%s%s%s%s",
|
|
|
1677f4 |
ictx->ctx.ldirname,
|
|
|
2f9f52 |
impprefix,
|
|
|
1677f4 |
dctx->cctx->libname,
|
|
|
c59280 |
dctx->cctx->settings.impsuffix);
|
|
|
c59280 |
ch++;
|
|
|
1677f4 |
|
|
|
1677f4 |
|
|
|
1677f4 |
/* primary implib file name */
|
|
|
1677f4 |
ictx->ctx.pimpfilename = ch;
|
|
|
f02083 |
ch += sprintf(ch,"%s%s%s%s%s.%d%s",
|
|
|
1677f4 |
ictx->ctx.ldirname,
|
|
|
2f9f52 |
impprefix,
|
|
|
1677f4 |
dctx->cctx->libname,
|
|
|
f02083 |
dctx->cctx->release ? "-" : "",
|
|
|
f02083 |
dctx->cctx->release ? dctx->cctx->release : "",
|
|
|
1677f4 |
dctx->cctx->verinfo.major,
|
|
|
c59280 |
dctx->cctx->settings.impsuffix);
|
|
|
c59280 |
ch++;
|
|
|
1677f4 |
|
|
|
1677f4 |
/* versioned implib file name */
|
|
|
1677f4 |
ictx->ctx.vimpfilename = ch;
|
|
|
f02083 |
ch += sprintf(ch,"%s%s%s%s%s.%d.%d.%d%s",
|
|
|
1677f4 |
ictx->ctx.ldirname,
|
|
|
2f9f52 |
impprefix,
|
|
|
1677f4 |
dctx->cctx->libname,
|
|
|
f02083 |
dctx->cctx->release ? "-" : "",
|
|
|
f02083 |
dctx->cctx->release ? dctx->cctx->release : "",
|
|
|
1677f4 |
dctx->cctx->verinfo.major,
|
|
|
1677f4 |
dctx->cctx->verinfo.minor,
|
|
|
1677f4 |
dctx->cctx->verinfo.revision,
|
|
|
c59280 |
dctx->cctx->settings.impsuffix);
|
|
|
c59280 |
ch++;
|
|
|
112a2b |
|
|
|
112a2b |
/* relfilename */
|
|
|
112a2b |
if (dctx->cctx->release) {
|
|
|
112a2b |
ictx->ctx.relfilename = ch;
|
|
|
600957 |
ch += dctx->cctx->verinfo.verinfo
|
|
|
08f5f9 |
? sprintf(ch,"%s%s%s-%s%s.%d.%d.%d%s",
|
|
|
600957 |
ictx->ctx.ldirname,
|
|
|
600957 |
dsoprefix,
|
|
|
600957 |
dctx->cctx->libname,
|
|
|
600957 |
dctx->cctx->release,
|
|
|
08f5f9 |
dctx->cctx->settings.osdsuffix,
|
|
|
600957 |
dctx->cctx->verinfo.major,
|
|
|
600957 |
dctx->cctx->verinfo.minor,
|
|
|
08f5f9 |
dctx->cctx->verinfo.revision,
|
|
|
08f5f9 |
dctx->cctx->settings.osdfussix)
|
|
|
600957 |
: sprintf(ch,"%s%s%s-%s%s",
|
|
|
600957 |
ictx->ctx.ldirname,
|
|
|
600957 |
dsoprefix,
|
|
|
600957 |
dctx->cctx->libname,
|
|
|
600957 |
dctx->cctx->release,
|
|
|
600957 |
dctx->cctx->settings.dsosuffix);
|
|
|
600957 |
ch++;
|
|
|
600957 |
}
|
|
|
600957 |
|
|
|
600957 |
/* dsorellnkname */
|
|
|
600957 |
if (dctx->cctx->release) {
|
|
|
600957 |
ictx->ctx.dsorellnkname = ch;
|
|
|
112a2b |
ch += sprintf(ch,"%s%s%s-%s%s",
|
|
|
112a2b |
ictx->ctx.ldirname,
|
|
|
112a2b |
dsoprefix,
|
|
|
112a2b |
dctx->cctx->libname,
|
|
|
112a2b |
dctx->cctx->release,
|
|
|
112a2b |
dctx->cctx->settings.dsosuffix);
|
|
|
112a2b |
ch++;
|
|
|
112a2b |
}
|
|
|
39e52e |
|
|
|
39e52e |
/* dlopensrc, dlopenobj */
|
|
|
39e52e |
if (idctx->ndlopen) {
|
|
|
39e52e |
ictx->ctx.dlopensrc = ch;
|
|
|
39e52e |
ch += sprintf(ch,"%s%s%s.dlopen.c",
|
|
|
39e52e |
ictx->ctx.ldirname,
|
|
|
39e52e |
dsoprefix,
|
|
|
39e52e |
dctx->cctx->libname);
|
|
|
39e52e |
|
|
|
39e52e |
ch++;
|
|
|
39e52e |
|
|
|
39e52e |
ictx->ctx.dlopenobj = ch;
|
|
|
39e52e |
ch += sprintf(ch,"%s%s%s.dlopen.o",
|
|
|
39e52e |
ictx->ctx.ldirname,
|
|
|
39e52e |
dsoprefix,
|
|
|
39e52e |
dctx->cctx->libname);
|
|
|
39e52e |
|
|
|
39e52e |
ch++;
|
|
|
39e52e |
|
|
|
39e52e |
ictx->ctx.dlunit = ch;
|
|
|
39e52e |
ch += sprintf(ch,"%s%s",
|
|
|
39e52e |
dsoprefix,
|
|
|
39e52e |
dctx->cctx->libname);
|
|
|
39e52e |
|
|
|
39e52e |
ch++;
|
|
|
39e52e |
}
|
|
|
9bc8c2 |
|
|
|
9bc8c2 |
/* linking: exefilename */
|
|
|
9bc8c2 |
} else if (dctx->cctx->mode == SLBT_MODE_LINK) {
|
|
|
9bc8c2 |
ictx->ctx.exefilename = ch;
|
|
|
9bc8c2 |
|
|
|
9bc8c2 |
if ((slash = strrchr(dctx->cctx->output,'/'))) {
|
|
|
9bc8c2 |
strcpy(ch,dctx->cctx->output);
|
|
|
9bc8c2 |
mark = ch + (slash - dctx->cctx->output);
|
|
|
9bc8c2 |
sprintf(++mark,".libs/%s",++slash);
|
|
|
9bc8c2 |
ch += strlen(ch) + 1;
|
|
|
9bc8c2 |
} else
|
|
|
9bc8c2 |
ch += sprintf(ch,".libs/%s",dctx->cctx->output) + 1;
|
|
|
9bc8c2 |
}
|
|
|
9bc8c2 |
|
|
|
9bc8c2 |
/* dlopensrc, dlopenobj: executable program */
|
|
|
9bc8c2 |
if (idctx->dlopenv && !dctx->cctx->libname) {
|
|
|
9bc8c2 |
ictx->ctx.dlopensrc = ch;
|
|
|
9bc8c2 |
ch += sprintf(ch,"%s.dlopen.c",
|
|
|
9bc8c2 |
ictx->ctx.exefilename);
|
|
|
9bc8c2 |
|
|
|
9bc8c2 |
ch++;
|
|
|
9bc8c2 |
|
|
|
9bc8c2 |
ictx->ctx.dlopenobj = ch;
|
|
|
9bc8c2 |
ch += sprintf(ch,"%s.dlopen.o",
|
|
|
9bc8c2 |
ictx->ctx.exefilename);
|
|
|
9bc8c2 |
|
|
|
9bc8c2 |
ch++;
|
|
|
9bc8c2 |
|
|
|
9bc8c2 |
ictx->ctx.dlunit = ch;
|
|
|
9bc8c2 |
ch += sprintf(ch,"%s",
|
|
|
9bc8c2 |
"@PROGRAM@");
|
|
|
9bc8c2 |
|
|
|
9bc8c2 |
ch++;
|
|
|
39e52e |
}
|
|
|
39e52e |
|
|
|
39e52e |
/* dlopen, dlpreopen */
|
|
|
39e52e |
if ((dlopenv = idctx->dlopenv), (dlactxv = ictx->dlactxv)) {
|
|
|
39e52e |
for (; *dlopenv; ) {
|
|
|
39e52e |
arname = ictx->sbuf;
|
|
|
39e52e |
strcpy(arname,*dlopenv);
|
|
|
39e52e |
slbt_adjust_wrapper_argument(arname,true);
|
|
|
39e52e |
|
|
|
39e52e |
if (slbt_ar_get_archive_ctx(dctx,arname,dlactxv) < 0)
|
|
|
39e52e |
return slbt_ectx_free_exec_ctx_impl(
|
|
|
39e52e |
ictx,
|
|
|
39e52e |
SLBT_NESTED_ERROR(dctx));
|
|
|
39e52e |
|
|
|
39e52e |
if (slbt_ar_update_syminfo(*dlactxv,&ictx->ctx) < 0)
|
|
|
39e52e |
return slbt_ectx_free_exec_ctx_impl(
|
|
|
39e52e |
ictx,
|
|
|
39e52e |
SLBT_NESTED_ERROR(dctx));
|
|
|
39e52e |
|
|
|
39e52e |
dlopenv++;
|
|
|
39e52e |
dlactxv++;
|
|
|
39e52e |
}
|
|
|
39e52e |
|
|
|
39e52e |
if (slbt_ar_create_dlsyms(
|
|
|
39e52e |
ictx->dlactxv,
|
|
|
39e52e |
ictx->ctx.dlunit,
|
|
|
39e52e |
ictx->ctx.dlopensrc,
|
|
|
39e52e |
0644) < 0)
|
|
|
39e52e |
return slbt_ectx_free_exec_ctx_impl(
|
|
|
39e52e |
ictx,
|
|
|
39e52e |
SLBT_NESTED_ERROR(dctx));
|
|
|
731e44 |
}
|
|
|
731e44 |
|
|
|
f42074 |
/* vector of exported symbols (raw input via -export-symbols) */
|
|
|
f42074 |
if (dctx->cctx->expsyms)
|
|
|
f42074 |
if (slbt_lib_get_symlist_ctx(
|
|
|
f42074 |
dctx,dctx->cctx->expsyms,
|
|
|
f42074 |
&ictx->sctx) < 0)
|
|
|
f42074 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
f42074 |
|
|
|
e7ddb2 |
/* argument strings shadow copy */
|
|
|
e7ddb2 |
memcpy(ictx->shadow,ictx->args,ictx->size);
|
|
|
e7ddb2 |
|
|
|
d98877 |
/* compile mode: argument vector shadow copy */
|
|
|
d98877 |
if (dctx->cctx->mode == SLBT_MODE_COMPILE)
|
|
|
d98877 |
for (src=ictx->ctx.argv, dst=ictx->ctx.xargv; *src; src++, dst++)
|
|
|
d98877 |
*dst = *src;
|
|
|
d98877 |
|
|
|
d98877 |
/* save the full vector's lout, mout */
|
|
|
d98877 |
ictx->lout[0] = ictx->ctx.lout[0];
|
|
|
d98877 |
ictx->lout[1] = ictx->ctx.lout[1];
|
|
|
d98877 |
|
|
|
d98877 |
ictx->mout[0] = ictx->ctx.mout[0];
|
|
|
d98877 |
ictx->mout[1] = ictx->ctx.mout[1];
|
|
|
d98877 |
|
|
|
d98877 |
/* all done */
|
|
|
528799 |
*ectx = &ictx->ctx;
|
|
|
528799 |
return 0;
|
|
|
528799 |
}
|
|
|
528799 |
|
|
|
528799 |
|
|
|
f3d47a |
static int slbt_ectx_free_exec_ctx_impl(
|
|
|
528799 |
struct slbt_exec_ctx_impl * ictx,
|
|
|
528799 |
int status)
|
|
|
528799 |
{
|
|
|
39e52e |
struct slbt_archive_ctx ** dlactxv;
|
|
|
39e52e |
|
|
|
f42074 |
if (ictx->sctx)
|
|
|
f42074 |
slbt_lib_free_symlist_ctx(ictx->sctx);
|
|
|
f42074 |
|
|
|
9706fa |
if (ictx->fdwrapper >= 0)
|
|
|
9706fa |
close(ictx->fdwrapper);
|
|
|
5ee0d1 |
|
|
|
39e52e |
if (ictx->dlactxv) {
|
|
|
39e52e |
for (dlactxv=ictx->dlactxv; *dlactxv; dlactxv++)
|
|
|
39e52e |
slbt_ar_free_archive_ctx(*dlactxv);
|
|
|
39e52e |
|
|
|
39e52e |
free(ictx->dlactxv);
|
|
|
39e52e |
}
|
|
|
39e52e |
|
|
|
528799 |
free(ictx->args);
|
|
|
e7ddb2 |
free(ictx->shadow);
|
|
|
55d6e3 |
free(ictx->vbuffer);
|
|
|
528799 |
free (ictx);
|
|
|
9706fa |
|
|
|
528799 |
return status;
|
|
|
528799 |
}
|
|
|
528799 |
|
|
|
528799 |
|
|
|
f3d47a |
void slbt_ectx_free_exec_ctx(struct slbt_exec_ctx * ctx)
|
|
|
528799 |
{
|
|
|
528799 |
struct slbt_exec_ctx_impl * ictx;
|
|
|
528799 |
uintptr_t addr;
|
|
|
528799 |
|
|
|
528799 |
if (ctx) {
|
|
|
528799 |
addr = (uintptr_t)ctx - offsetof(struct slbt_exec_ctx_impl,ctx);
|
|
|
528799 |
ictx = (struct slbt_exec_ctx_impl *)addr;
|
|
|
f3d47a |
slbt_ectx_free_exec_ctx_impl(ictx,0);
|
|
|
528799 |
}
|
|
|
528799 |
}
|
|
|
5aae4b |
|
|
|
5aae4b |
|
|
|
f3d47a |
void slbt_ectx_reset_arguments(struct slbt_exec_ctx * ectx)
|
|
|
e7ddb2 |
{
|
|
|
e7ddb2 |
struct slbt_exec_ctx_impl * ictx;
|
|
|
e7ddb2 |
uintptr_t addr;
|
|
|
e7ddb2 |
|
|
|
e7ddb2 |
addr = (uintptr_t)ectx - offsetof(struct slbt_exec_ctx_impl,ctx);
|
|
|
e7ddb2 |
ictx = (struct slbt_exec_ctx_impl *)addr;
|
|
|
e7ddb2 |
memcpy(ictx->args,ictx->shadow,ictx->size);
|
|
|
e7ddb2 |
}
|
|
|
e7ddb2 |
|
|
|
e7ddb2 |
|
|
|
f3d47a |
void slbt_ectx_reset_argvector(struct slbt_exec_ctx * ectx)
|
|
|
d98877 |
{
|
|
|
d98877 |
struct slbt_exec_ctx_impl * ictx;
|
|
|
d98877 |
uintptr_t addr;
|
|
|
d98877 |
char ** src;
|
|
|
d98877 |
char ** dst;
|
|
|
d98877 |
|
|
|
d98877 |
addr = (uintptr_t)ectx - offsetof(struct slbt_exec_ctx_impl,ctx);
|
|
|
d98877 |
ictx = (struct slbt_exec_ctx_impl *)addr;
|
|
|
d98877 |
|
|
|
d98877 |
for (src=ectx->xargv, dst=ectx->argv; *src; src++, dst++)
|
|
|
d98877 |
*dst = *src;
|
|
|
d98877 |
|
|
|
d98877 |
*dst = 0;
|
|
|
d98877 |
|
|
|
d98877 |
ectx->lout[0] = ictx->lout[0];
|
|
|
d98877 |
ectx->lout[1] = ictx->lout[1];
|
|
|
d98877 |
|
|
|
d98877 |
ectx->mout[0] = ictx->mout[0];
|
|
|
d98877 |
ectx->mout[1] = ictx->mout[1];
|
|
|
d98877 |
}
|
|
|
d98877 |
|
|
|
d98877 |
|
|
|
f3d47a |
slbt_hidden void slbt_reset_placeholders(struct slbt_exec_ctx * ectx)
|
|
|
5aae4b |
{
|
|
|
4af256 |
struct slbt_exec_ctx_impl * ictx;
|
|
|
4af256 |
|
|
|
4af256 |
ictx = slbt_get_exec_ictx(ectx);
|
|
|
4af256 |
|
|
|
4af256 |
if (ictx->lout[0]) {
|
|
|
4af256 |
ectx->lout[0] = ictx->lout[0];
|
|
|
4af256 |
ectx->lout[1] = ictx->lout[1];
|
|
|
4af256 |
}
|
|
|
4af256 |
|
|
|
a40c9a |
*ectx->dpic = "-USLIBTOOL_PLACEHOLDER_DPIC";
|
|
|
a40c9a |
*ectx->fpic = "-USLIBTOOL_PLACEHOLDER_FPIC";
|
|
|
a40c9a |
*ectx->cass = "-USLIBTOOL_PLACEHOLDER_COMPILE_ASSEMBLE";
|
|
|
5aae4b |
|
|
|
93b62c |
*ectx->noundef = "-USLIBTOOL_PLACEHOLDER_NO_UNDEFINED";
|
|
|
0f8591 |
*ectx->soname = "-USLIBTOOL_PLACEHOLDER_SONAME";
|
|
|
0f8591 |
*ectx->lsoname = "-USLIBTOOL_PLACEHOLDER_LSONAME";
|
|
|
e15ee1 |
*ectx->symdefs = "-USLIBTOOL_PLACEHOLDER_SYMDEF_SWITCH";
|
|
|
e15ee1 |
*ectx->symfile = "-USLIBTOOL_PLACEHOLDER_SYMDEF_FILE";
|
|
|
f42074 |
*ectx->explarg = "-USLIBTOOL_PLACEHOLDER_EXPSYMS_SWITCH";
|
|
|
f42074 |
*ectx->expsyms = "-USLIBTOOL_PLACEHOLDER_EXPSYMS_FILE";
|
|
|
0f8591 |
|
|
|
a40c9a |
*ectx->lout[0] = "-USLIBTOOL_PLACEHOLDER_OUTPUT_SWITCH";
|
|
|
a40c9a |
*ectx->lout[1] = "-USLIBTOOL_PLACEHOLDER_OUTPUT_FILE";
|
|
|
3e7d5b |
|
|
|
3e7d5b |
*ectx->rpath[0] = "-USLIBTOOL_PLACEHOLDER_RPATH_SWITCH";
|
|
|
3e7d5b |
*ectx->rpath[1] = "-USLIBTOOL_PLACEHOLDER_RPATH_DIR";
|
|
|
3e7d5b |
|
|
|
df07fb |
ectx->mout[0] = 0;
|
|
|
df07fb |
ectx->mout[1] = 0;
|
|
|
df07fb |
|
|
|
b1f977 |
*ectx->sentinel= 0;
|
|
|
5aae4b |
}
|
|
|
2a7f1c |
|
|
|
f3d47a |
slbt_hidden void slbt_disable_placeholders(struct slbt_exec_ctx * ectx)
|
|
|
2a7f1c |
{
|
|
|
2a7f1c |
*ectx->dpic = 0;
|
|
|
2a7f1c |
*ectx->fpic = 0;
|
|
|
2a7f1c |
*ectx->cass = 0;
|
|
|
2a7f1c |
|
|
|
2a7f1c |
*ectx->noundef = 0;
|
|
|
2a7f1c |
*ectx->soname = 0;
|
|
|
2a7f1c |
*ectx->lsoname = 0;
|
|
|
e15ee1 |
*ectx->symdefs = 0;
|
|
|
e15ee1 |
*ectx->symfile = 0;
|
|
|
f42074 |
*ectx->explarg = 0;
|
|
|
f42074 |
*ectx->expsyms = 0;
|
|
|
2a7f1c |
|
|
|
2a7f1c |
*ectx->lout[0] = 0;
|
|
|
2a7f1c |
*ectx->lout[1] = 0;
|
|
|
3e7d5b |
|
|
|
3e7d5b |
*ectx->rpath[0] = 0;
|
|
|
3e7d5b |
*ectx->rpath[1] = 0;
|
|
|
3e7d5b |
|
|
|
2a7f1c |
*ectx->sentinel= 0;
|
|
|
2a7f1c |
}
|