Blame src/logic/slbt_exec_ctx.c

528799
/*******************************************************************/
eac61a
/*  slibtool: a strong 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"
39aef6
#include "slibtool_mkdir_impl.h"
39e52e
#include "slibtool_linkcmd_impl.h"
2a6c45
#include "slibtool_errinfo_impl.h"
39e52e
#include "slibtool_ar_impl.h"
528799
a07095
#define SLBT_ECTX_LIB_EXTRAS	26
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;
e9a1d6
	size_t                          exts;
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
dfb331
	/* initial buffer size (cargv, -Wc), .libs/.exe.wrapper */
55d6e3
	argc = 0;
55d6e3
	csrc = 0;
55d6e3
	size = 0;
dfb331
	exts = 20;
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
e9a1d6
	/* argument transformation: assume for each argv member */
e9a1d6
	if (dctx->cctx->shrext) {
e9a1d6
		exts += argc * (strlen(dctx->cctx->shrext));
e9a1d6
	}
e9a1d6
e9a1d6
	if (dctx->cctx->settings.dsosuffix) {
e9a1d6
		exts += argc * (strlen(dctx->cctx->settings.dsosuffix));
e9a1d6
	}
e9a1d6
e9a1d6
	size += argc * exts;
08f5f9
55d6e3
	/* buffer size (csrc, ldirname, lbasename, lobjname, aobjname, etc.) */
55d6e3
	if (dctx->cctx->libname) {
55d6e3
		slen  = strlen(dctx->cctx->libname);
e9a1d6
		size += (strlen(".slibtool.expsyms.extension") + slen + exts + 1) * SLBT_ECTX_LIB_EXTRAS;
df088e
55d6e3
	} else if (dctx->cctx->output) {
55d6e3
		slen  = strlen(dctx->cctx->output);
e9a1d6
		size += (strlen(".slibtool.expsyms.extension") + slen + exts + 1) * SLBT_ECTX_LIB_EXTRAS;
f0c096
55d6e3
	} else if ((csrc = slbt_source_file(dctx->cctx->cargv))) {
55d6e3
		slen  = strlen(csrc);
e9a1d6
		size += (strlen(".slibtool.expsyms.extension") + slen + exts + 1) * SLBT_ECTX_LIB_EXTRAS;
e9a1d6
	} else {
e9a1d6
		size += exts * 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;
e9a1d6
	ictx->exts   = exts;
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;
d054ee
	struct slbt_error_info**        errinfp;
528799
	char **				parg;
d98877
	char **				src;
d98877
	char **				dst;
528799
	char *				ch;
014f4c
	char *				mark;
7f35de
	const char *			dmark;
6b2fa6
	const char *                    dsoext;
f47761
	char *				slash;
39e52e
	char *                          arname;
39e52e
	struct slbt_archive_ctx **      dlactxv;
a07095
	struct argv_entry *             dlentry;
a07095
	struct argv_entry **            dlopenv;
a07095
	bool                            fpreopen;
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);
e9a1d6
			ch += ictx->exts;
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) {
6b2fa6
		if (!(dsoext = dctx->cctx->shrext))
6b2fa6
			dsoext = dctx->cctx->settings.dsosuffix;
6b2fa6
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,
6b2fa6
				dsoext);
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 : "",
6b2fa6
				dsoext);
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,
6b2fa6
				dsoext);
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,
6b2fa6
					dsoext);
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,
6b2fa6
					dsoext);
112a2b
			ch++;
112a2b
		}
39e52e
39e52e
		/* dlopensrc, dlopenobj */
a07095
		if (idctx->dlopenv) {
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
a07095
			ictx->ctx.dlpreopen = ch;
a07095
			ch += sprintf(ch,"%s%s%s.dlpreopen.a",
a07095
					ictx->ctx.ldirname,
a07095
					dsoprefix,
a07095
					dctx->cctx->libname);
a07095
a07095
			ch++;
a07095
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
a07095
		ictx->ctx.dlpreopen = ch;
a07095
		ch += sprintf(ch,"%s.dlpreopen.a",
a07095
				ictx->ctx.exefilename);
a07095
a07095
		ch++;
a07095
9bc8c2
		ictx->ctx.dlunit = ch;
9bc8c2
		ch += sprintf(ch,"%s",
9bc8c2
				"@PROGRAM@");
9bc8c2
9bc8c2
		ch++;
445102
445102
		ictx->ctx.mapfilename = ch;
445102
		ch += sprintf(ch,"%s%s",
445102
				ictx->ctx.exefilename,
445102
				dctx->cctx->settings.mapsuffix);
445102
		ch++;
445102
39e52e
	}
39e52e
39e52e
	/* dlopen, dlpreopen */
39e52e
	if ((dlopenv = idctx->dlopenv), (dlactxv = ictx->dlactxv)) {
e2b582
		if (slbt_ar_get_varchive_ctx(dctx,dlactxv) < 0)
e2b582
			return slbt_ectx_free_exec_ctx_impl(
e2b582
				ictx,
e2b582
				SLBT_NESTED_ERROR(dctx));
e2b582
3077bb
		if (slbt_ar_update_syminfo(*dlactxv) < 0)
e2b582
			return slbt_ectx_free_exec_ctx_impl(
e2b582
				ictx,
e2b582
				SLBT_NESTED_ERROR(dctx));
e2b582
e2b582
		dlactxv++;
445102
39e52e
		for (; *dlopenv; ) {
a07095
			dlentry  = *dlopenv;
a07095
			fpreopen = (dlentry->tag == TAG_DLPREOPEN);
a07095
39e52e
			arname = ictx->sbuf;
a07095
			strcpy(arname,dlentry->arg);
39e52e
d054ee
			slbt_adjust_wrapper_argument(
d054ee
				arname,true,
d054ee
				".expsyms.a");
d054ee
d054ee
			errinfp = idctx->errinfp;
d054ee
d054ee
			if (slbt_ar_get_archive_ctx(dctx,arname,dlactxv) < 0) {
a07095
				if ((*errinfp)->esyscode != ENOENT)
a07095
					return slbt_ectx_free_exec_ctx_impl(
a07095
						ictx,
a07095
						SLBT_NESTED_ERROR(dctx));
a07095
a07095
				strcpy(arname,dlentry->arg);
d054ee
d054ee
				slbt_adjust_wrapper_argument(
d054ee
					arname,true,
d054ee
					dctx->cctx->settings.arsuffix);
d054ee
d054ee
				if (slbt_ar_get_archive_ctx(dctx,arname,dlactxv) < 0)
d054ee
					return slbt_ectx_free_exec_ctx_impl(
d054ee
						ictx,
d054ee
						SLBT_NESTED_ERROR(dctx));
d054ee
d054ee
				idctx->errinfp = errinfp;
d054ee
d054ee
				for (; *errinfp; )
d054ee
					*errinfp++ = 0;
a07095
a07095
				fpreopen = true;
d054ee
			}
39e52e
a07095
			if (fpreopen) {
3077bb
				if (slbt_ar_update_syminfo(*dlactxv) < 0)
a07095
					return slbt_ectx_free_exec_ctx_impl(
a07095
						ictx,
a07095
						SLBT_NESTED_ERROR(dctx));
a07095
a07095
				dlactxv++;
a07095
			} else {
a07095
				slbt_ar_free_archive_ctx(*dlactxv);
a07095
				*dlactxv = 0;
a07095
			}
39e52e
39e52e
			dlopenv++;
39e52e
		}
39e52e
39aef6
		if (slbt_mkdir(dctx,ictx->ctx.ldirname) < 0)
39aef6
			return slbt_ectx_free_exec_ctx_impl(
39aef6
				ictx,
39aef6
				SLBT_SYSTEM_ERROR(
39aef6
					dctx,
39aef6
					ictx->ctx.ldirname));
39aef6
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));
a07095
a07095
		if (slbt_ar_merge_archives(ictx->dlactxv,&ictx->dlpreopen) < 0)
a07095
				return slbt_ectx_free_exec_ctx_impl(
a07095
					ictx,
a07095
					SLBT_NESTED_ERROR(dctx));
a07095
a07095
		if (slbt_ar_store_archive(ictx->dlpreopen,ictx->ctx.dlpreopen,0644) < 0)
a07095
				return slbt_ectx_free_exec_ctx_impl(
a07095
					ictx,
a07095
					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
}