|
|
2ec747 |
/*******************************************************************/
|
|
|
eac61a |
/* slibtool: a strong libtool implementation, written in C */
|
|
|
2ec747 |
/* Copyright (C) 2016--2024 SysDeer Technologies, LLC */
|
|
|
2ec747 |
/* Released under the Standard MIT License; see COPYING.SLIBTOOL. */
|
|
|
2ec747 |
/*******************************************************************/
|
|
|
2ec747 |
|
|
|
2ec747 |
#include <slibtool/slibtool.h>
|
|
|
2ec747 |
#include "slibtool_ar_impl.h"
|
|
|
2ec747 |
#include "slibtool_driver_impl.h"
|
|
|
2ec747 |
#include "slibtool_snprintf_impl.h"
|
|
|
2ec747 |
#include "slibtool_errinfo_impl.h"
|
|
|
2ec747 |
|
|
|
9f06b2 |
static const char * slbt_strong_symname(
|
|
|
9f06b2 |
const char * symname,
|
|
|
9f06b2 |
bool fcoff,
|
|
|
9f06b2 |
char (*strbuf)[4096])
|
|
|
9f06b2 |
{
|
|
|
9f06b2 |
const char * dot;
|
|
|
9f06b2 |
const char * mark;
|
|
|
9f06b2 |
char * sym;
|
|
|
9f06b2 |
|
|
|
9f06b2 |
if (fcoff) {
|
|
|
9f06b2 |
if (!strncmp(symname,"__imp_",6))
|
|
|
9f06b2 |
return 0;
|
|
|
9f06b2 |
|
|
|
9f06b2 |
if (strncmp(symname,".weak.",6))
|
|
|
9f06b2 |
return symname;
|
|
|
9f06b2 |
|
|
|
9f06b2 |
sym = *strbuf;
|
|
|
9f06b2 |
mark = &symname[6];
|
|
|
9f06b2 |
dot = strchr(mark,'.');
|
|
|
9f06b2 |
|
|
|
9f06b2 |
strncpy(sym,mark,dot-mark);
|
|
|
9f06b2 |
sym[dot-mark] = '\0';
|
|
|
9f06b2 |
|
|
|
9f06b2 |
return sym;
|
|
|
9f06b2 |
}
|
|
|
9f06b2 |
|
|
|
9f06b2 |
return symname;
|
|
|
9f06b2 |
}
|
|
|
9f06b2 |
|
|
|
9f06b2 |
|
|
|
2ec747 |
static int slbt_ar_dlsyms_define_by_type(
|
|
|
2ec747 |
int fdout,
|
|
|
2ec747 |
const char * arname,
|
|
|
2ec747 |
struct slbt_archive_meta_impl * mctx,
|
|
|
2ec747 |
const char * desc,
|
|
|
2ec747 |
const char stype)
|
|
|
2ec747 |
{
|
|
|
9f06b2 |
uint64_t idx;
|
|
|
9f06b2 |
uint64_t nsyms;
|
|
|
9f06b2 |
bool fcoff;
|
|
|
9f06b2 |
const char * symname;
|
|
|
9f06b2 |
char strbuf[4096];
|
|
|
2ec747 |
|
|
|
9f06b2 |
for (idx=0,nsyms=0; idx<mctx->armaps.armap_nsyms; idx++)
|
|
|
2ec747 |
if (mctx->syminfv[idx]->ar_symbol_type[0] == stype)
|
|
|
2ec747 |
nsyms++;
|
|
|
2ec747 |
|
|
|
2ec747 |
if (nsyms == 0)
|
|
|
2ec747 |
return 0;
|
|
|
2ec747 |
|
|
|
9f06b2 |
fcoff = slbt_host_objfmt_is_coff(mctx->dctx);
|
|
|
9f06b2 |
fcoff |= (mctx->ofmtattr & AR_OBJECT_ATTR_COFF);
|
|
|
9f06b2 |
|
|
|
2ec747 |
if (slbt_dprintf(fdout,"/* %s (%s) */\n",desc,arname) < 0)
|
|
|
2ec747 |
return SLBT_SYSTEM_ERROR(mctx->dctx,0);
|
|
|
2ec747 |
|
|
|
2ec747 |
for (idx=0; idx<mctx->armaps.armap_nsyms; idx++)
|
|
|
2ec747 |
if (mctx->syminfv[idx]->ar_symbol_type[0] == stype)
|
|
|
9f06b2 |
if ((symname = slbt_strong_symname(
|
|
|
9f06b2 |
mctx->syminfv[idx]->ar_symbol_name,
|
|
|
9f06b2 |
fcoff,&strbuf)))
|
|
|
9f06b2 |
if (slbt_dprintf(fdout,
|
|
|
9f06b2 |
(stype == 'T')
|
|
|
9f06b2 |
? "extern int %s();\n"
|
|
|
9f06b2 |
: "extern char %s[];\n",
|
|
|
9f06b2 |
symname) < 0)
|
|
|
9f06b2 |
return SLBT_SYSTEM_ERROR(mctx->dctx,0);
|
|
|
2ec747 |
|
|
|
2ec747 |
if (slbt_dprintf(fdout,"\n") < 0)
|
|
|
2ec747 |
return SLBT_SYSTEM_ERROR(mctx->dctx,0);
|
|
|
2ec747 |
|
|
|
2ec747 |
return 0;
|
|
|
2ec747 |
}
|
|
|
2ec747 |
|
|
|
2ec747 |
static int slbt_ar_dlsyms_get_max_len_by_type(
|
|
|
2ec747 |
int mlen,
|
|
|
2ec747 |
struct slbt_archive_meta_impl * mctx,
|
|
|
2ec747 |
const char stype)
|
|
|
2ec747 |
{
|
|
|
9f06b2 |
int len;
|
|
|
9f06b2 |
uint64_t idx;
|
|
|
9f06b2 |
bool fcoff;
|
|
|
9f06b2 |
const char * symname;
|
|
|
9f06b2 |
char strbuf[4096];
|
|
|
9f06b2 |
|
|
|
9f06b2 |
fcoff = slbt_host_objfmt_is_coff(mctx->dctx);
|
|
|
9f06b2 |
fcoff |= (mctx->ofmtattr & AR_OBJECT_ATTR_COFF);
|
|
|
2ec747 |
|
|
|
2ec747 |
for (idx=0; idx<mctx->armaps.armap_nsyms; idx++)
|
|
|
2ec747 |
if (mctx->syminfv[idx]->ar_symbol_type[0] == stype)
|
|
|
9f06b2 |
if ((symname = slbt_strong_symname(
|
|
|
9f06b2 |
mctx->syminfv[idx]->ar_symbol_name,
|
|
|
9f06b2 |
fcoff,&strbuf)))
|
|
|
9f06b2 |
if ((len = strlen(symname)) > mlen)
|
|
|
9f06b2 |
mlen = len;
|
|
|
2ec747 |
|
|
|
2ec747 |
return mlen;
|
|
|
2ec747 |
}
|
|
|
2ec747 |
|
|
|
2ec747 |
static int slbt_ar_dlsyms_add_by_type(
|
|
|
2ec747 |
int fdout,
|
|
|
2ec747 |
struct slbt_archive_meta_impl * mctx,
|
|
|
2ec747 |
const char * fmt,
|
|
|
2ec747 |
const char stype,
|
|
|
2ec747 |
char (*namebuf)[4096])
|
|
|
2ec747 |
{
|
|
|
9f06b2 |
uint64_t idx;
|
|
|
9f06b2 |
uint64_t nsyms;
|
|
|
9f06b2 |
bool fcoff;
|
|
|
9f06b2 |
const char * symname;
|
|
|
9f06b2 |
char strbuf[4096];
|
|
|
2ec747 |
|
|
|
2ec747 |
nsyms = 0;
|
|
|
2ec747 |
symname = *namebuf;
|
|
|
2ec747 |
|
|
|
9f06b2 |
fcoff = slbt_host_objfmt_is_coff(mctx->dctx);
|
|
|
9f06b2 |
fcoff |= (mctx->ofmtattr & AR_OBJECT_ATTR_COFF);
|
|
|
9f06b2 |
|
|
|
2ec747 |
for (idx=0; idx<mctx->armaps.armap_nsyms; idx++)
|
|
|
2ec747 |
if (mctx->syminfv[idx]->ar_symbol_type[0] == stype)
|
|
|
2ec747 |
nsyms++;
|
|
|
2ec747 |
|
|
|
2ec747 |
if (nsyms == 0)
|
|
|
2ec747 |
return 0;
|
|
|
2ec747 |
|
|
|
2ec747 |
if (slbt_dprintf(fdout,"\n") < 0)
|
|
|
2ec747 |
return SLBT_SYSTEM_ERROR(mctx->dctx,0);
|
|
|
2ec747 |
|
|
|
2ec747 |
for (idx=0; idx<mctx->armaps.armap_nsyms; idx++) {
|
|
|
2ec747 |
if (mctx->syminfv[idx]->ar_symbol_type[0] == stype) {
|
|
|
9f06b2 |
symname = slbt_strong_symname(
|
|
|
9f06b2 |
mctx->syminfv[idx]->ar_symbol_name,
|
|
|
9f06b2 |
fcoff,&strbuf);
|
|
|
9f06b2 |
|
|
|
9f06b2 |
if (symname) {
|
|
|
9f06b2 |
if (slbt_snprintf(*namebuf,sizeof(*namebuf),
|
|
|
9f06b2 |
"%s\",",symname) < 0)
|
|
|
9f06b2 |
return SLBT_SYSTEM_ERROR(mctx->dctx,0);
|
|
|
9f06b2 |
|
|
|
9f06b2 |
if (slbt_dprintf(fdout,fmt,
|
|
|
9f06b2 |
*namebuf,
|
|
|
9f06b2 |
(stype == 'T') ? "&" : "",
|
|
|
9f06b2 |
symname) < 0)
|
|
|
9f06b2 |
return SLBT_NESTED_ERROR(mctx->dctx);
|
|
|
9f06b2 |
}
|
|
|
2ec747 |
}
|
|
|
2ec747 |
}
|
|
|
2ec747 |
|
|
|
2ec747 |
return 0;
|
|
|
2ec747 |
}
|
|
|
2ec747 |
|
|
|
2ec747 |
|
|
|
2ec747 |
static int slbt_ar_output_dlsyms_impl(
|
|
|
2ec747 |
int fdout,
|
|
|
2ec747 |
const struct slbt_driver_ctx * dctx,
|
|
|
2ec747 |
struct slbt_archive_ctx ** arctxv,
|
|
|
2ec747 |
const char * dsounit)
|
|
|
2ec747 |
{
|
|
|
2ec747 |
int ret;
|
|
|
2ec747 |
int idx;
|
|
|
2ec747 |
unsigned len;
|
|
|
2ec747 |
unsigned cmp;
|
|
|
2ec747 |
const char * arname;
|
|
|
b7e6e8 |
const char * soname;
|
|
|
2ec747 |
struct slbt_archive_ctx * actx;
|
|
|
2ec747 |
struct slbt_archive_ctx ** parctx;
|
|
|
2ec747 |
struct slbt_archive_ctx_impl * ictx;
|
|
|
2ec747 |
struct slbt_archive_meta_impl * mctx;
|
|
|
2ec747 |
const struct slbt_source_version * verinfo;
|
|
|
2ec747 |
char dlsymfmt[32];
|
|
|
2ec747 |
char cline[6][73];
|
|
|
2ec747 |
char symname[4096];
|
|
|
2ec747 |
|
|
|
2ec747 |
/* init */
|
|
|
2ec747 |
actx = arctxv[0];
|
|
|
2ec747 |
verinfo = slbt_api_source_version();
|
|
|
2ec747 |
|
|
|
2ec747 |
/* preamble */
|
|
|
2ec747 |
memset(cline[0],'*',72);
|
|
|
2ec747 |
memset(cline[1],' ',72);
|
|
|
2ec747 |
memset(cline[2],' ',72);
|
|
|
2ec747 |
memset(cline[3],' ',72);
|
|
|
2ec747 |
memset(cline[4],'*',72);
|
|
|
2ec747 |
|
|
|
2ec747 |
memset(cline[5],0,72);
|
|
|
2ec747 |
cline[5][0] = '\n';
|
|
|
2ec747 |
|
|
|
da73d2 |
len = snprintf(&cline[1][3],69,
|
|
|
2ec747 |
"backward-compatible dlsym table");
|
|
|
2ec747 |
|
|
|
2ec747 |
cline[1][3+len] = ' ';
|
|
|
2ec747 |
|
|
|
da73d2 |
len = snprintf(&cline[2][3],69,
|
|
|
2ec747 |
"Generated by %s (slibtool %d.%d.%d)",
|
|
|
2ec747 |
dctx->program,
|
|
|
2ec747 |
verinfo->major,verinfo->minor,verinfo->revision);
|
|
|
2ec747 |
|
|
|
2ec747 |
cline[2][3+len] = ' ';
|
|
|
2ec747 |
|
|
|
da73d2 |
len = snprintf(&cline[3][3],69,
|
|
|
2ec747 |
"[commit reference: %s]",
|
|
|
2ec747 |
verinfo->commit);
|
|
|
2ec747 |
|
|
|
2ec747 |
cline[3][3+len] = ' ';
|
|
|
2ec747 |
|
|
|
2ec747 |
for (idx=0; idx<5; idx++) {
|
|
|
2ec747 |
cline[idx][0] = '/';
|
|
|
2ec747 |
cline[idx][1] = '*';
|
|
|
2ec747 |
|
|
|
2ec747 |
cline[idx][70] = '*';
|
|
|
2ec747 |
cline[idx][71] = '/';
|
|
|
2ec747 |
|
|
|
2ec747 |
cline[idx][72] = '\n';
|
|
|
2ec747 |
}
|
|
|
2ec747 |
|
|
|
2ec747 |
if (slbt_dprintf(fdout,"%s",&cline[0]) < 0)
|
|
|
2ec747 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
2ec747 |
|
|
|
2ec747 |
if (slbt_dprintf(fdout,
|
|
|
2ec747 |
"#ifdef __cplusplus\n"
|
|
|
2ec747 |
"extern \"C\" {\n"
|
|
|
2ec747 |
"#endif\n\n") < 0)
|
|
|
2ec747 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
2ec747 |
|
|
|
2ec747 |
/* declarations */
|
|
|
2ec747 |
for (parctx=arctxv; *parctx; parctx++) {
|
|
|
2ec747 |
actx = *parctx;
|
|
|
2ec747 |
ictx = slbt_get_archive_ictx(actx);
|
|
|
2ec747 |
mctx = slbt_archive_meta_ictx(ictx->meta);
|
|
|
2ec747 |
|
|
|
2ec747 |
if ((arname = strrchr(*actx->path,'/')))
|
|
|
2ec747 |
arname++;
|
|
|
2ec747 |
|
|
|
2ec747 |
if (!arname)
|
|
|
2ec747 |
arname = *actx->path;
|
|
|
2ec747 |
|
|
|
2ec747 |
ret = slbt_ar_dlsyms_define_by_type(fdout,arname,mctx,"Data Symbols: Absolute Values", 'A');
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_define_by_type(fdout,arname,mctx,"Data Symbols: BSS Section", 'B');
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_define_by_type(fdout,arname,mctx,"Data Symbols: Common Section", 'C');
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_define_by_type(fdout,arname,mctx,"Data Symbols: Initialized Data", 'D');
|
|
|
2ec747 |
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_define_by_type(fdout,arname,mctx,"Data Symbols: Small Globals", 'G');
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_define_by_type(fdout,arname,mctx,"Data Symbols: Indirect References", 'I');
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_define_by_type(fdout,arname,mctx,"Data Symbols: Read-Only Section", 'R');
|
|
|
2ec747 |
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_define_by_type(fdout,arname,mctx,"Data Symbols: Small Objects", 'S');
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_define_by_type(fdout,arname,mctx,"Data Symbols: Weak Symbols", 'W');
|
|
|
2ec747 |
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_define_by_type(fdout,arname,mctx,"Text Section: Public Interfaces", 'T');
|
|
|
2ec747 |
|
|
|
2ec747 |
if (ret < 0)
|
|
|
2ec747 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
2ec747 |
|
|
|
2ec747 |
}
|
|
|
2ec747 |
|
|
|
2ec747 |
/* vtable struct definition */
|
|
|
2ec747 |
if (slbt_dprintf(fdout,
|
|
|
2ec747 |
"/* name-address Public ABI struct definition */\n"
|
|
|
2ec747 |
"struct lt_dlsym_symdef {\n"
|
|
|
2ec747 |
"\tconst char * dlsym_name;\n"
|
|
|
2ec747 |
"\tvoid * dlsym_addr;\n"
|
|
|
2ec747 |
"};\n\n") < 0)
|
|
|
2ec747 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
2ec747 |
|
|
|
b7e6e8 |
soname = (strcmp(dsounit,"@PROGRAM@")) ? dsounit : "_PROGRAM_";
|
|
|
b7e6e8 |
|
|
|
2ec747 |
if (slbt_dprintf(fdout,
|
|
|
2ec747 |
"/* dlsym vtable */\n"
|
|
|
2ec747 |
"extern const struct lt_dlsym_symdef "
|
|
|
2ec747 |
"lt_%s_LTX_preloaded_symbols[];\n\n"
|
|
|
2ec747 |
"const struct lt_dlsym_symdef "
|
|
|
2ec747 |
"lt_%s_LTX_preloaded_symbols[] = {\n",
|
|
|
b7e6e8 |
soname,soname) < 0)
|
|
|
2ec747 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
2ec747 |
|
|
|
2ec747 |
/* align dlsym_name and dlsym_addr columsn (because we can) */
|
|
|
2ec747 |
for (parctx=arctxv,len=0; *parctx; parctx++) {
|
|
|
2ec747 |
actx = *parctx;
|
|
|
2ec747 |
ictx = slbt_get_archive_ictx(actx);
|
|
|
2ec747 |
mctx = slbt_archive_meta_ictx(ictx->meta);
|
|
|
2ec747 |
|
|
|
2ec747 |
if ((arname = strrchr(*actx->path,'/')))
|
|
|
2ec747 |
arname++;
|
|
|
2ec747 |
|
|
|
2ec747 |
if (!arname)
|
|
|
2ec747 |
arname = *actx->path;
|
|
|
2ec747 |
|
|
|
2ec747 |
if (len < (cmp = strlen(arname)))
|
|
|
2ec747 |
len = cmp;
|
|
|
2ec747 |
|
|
|
2ec747 |
len = slbt_ar_dlsyms_get_max_len_by_type(len,mctx,'A');
|
|
|
2ec747 |
len = slbt_ar_dlsyms_get_max_len_by_type(len,mctx,'B');
|
|
|
2ec747 |
len = slbt_ar_dlsyms_get_max_len_by_type(len,mctx,'C');
|
|
|
2ec747 |
len = slbt_ar_dlsyms_get_max_len_by_type(len,mctx,'D');
|
|
|
2ec747 |
|
|
|
2ec747 |
len = slbt_ar_dlsyms_get_max_len_by_type(len,mctx,'G');
|
|
|
2ec747 |
len = slbt_ar_dlsyms_get_max_len_by_type(len,mctx,'I');
|
|
|
2ec747 |
len = slbt_ar_dlsyms_get_max_len_by_type(len,mctx,'R');
|
|
|
2ec747 |
|
|
|
2ec747 |
len = slbt_ar_dlsyms_get_max_len_by_type(len,mctx,'S');
|
|
|
2ec747 |
len = slbt_ar_dlsyms_get_max_len_by_type(len,mctx,'T');
|
|
|
2ec747 |
len = slbt_ar_dlsyms_get_max_len_by_type(len,mctx,'W');
|
|
|
2ec747 |
}
|
|
|
2ec747 |
|
|
|
2ec747 |
/* quote, comma */
|
|
|
2ec747 |
len += 2;
|
|
|
2ec747 |
|
|
|
2ec747 |
if (len >= sizeof(symname))
|
|
|
2ec747 |
return SLBT_CUSTOM_ERROR(
|
|
|
2ec747 |
dctx,
|
|
|
2ec747 |
SLBT_ERR_FLOW_ERROR);
|
|
|
2ec747 |
|
|
|
2ec747 |
/* aligned print format */
|
|
|
2ec747 |
snprintf(dlsymfmt,sizeof(dlsymfmt),"\t{\"%%-%ds %%s%%s},\n",len);
|
|
|
2ec747 |
|
|
|
2ec747 |
/* dso unit */
|
|
|
2ec747 |
if (slbt_snprintf(symname,sizeof(symname),"%s\",",dsounit) < 0)
|
|
|
2ec747 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
2ec747 |
|
|
|
2ec747 |
if (slbt_dprintf(fdout,dlsymfmt,symname,"","0") < 0)
|
|
|
2ec747 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
2ec747 |
|
|
|
deae20 |
/* (-dlopen force) */
|
|
|
deae20 |
if (!arctxv[0]->meta->a_memberv)
|
|
|
deae20 |
if (!strcmp(*arctxv[0]->path,"@PROGRAM@"))
|
|
|
deae20 |
arctxv++;
|
|
|
deae20 |
|
|
|
2ec747 |
/* at long last */
|
|
|
2ec747 |
for (parctx=arctxv; *parctx; parctx++) {
|
|
|
2ec747 |
actx = *parctx;
|
|
|
2ec747 |
ictx = slbt_get_archive_ictx(actx);
|
|
|
2ec747 |
mctx = slbt_archive_meta_ictx(ictx->meta);
|
|
|
2ec747 |
|
|
|
2ec747 |
if ((arname = strrchr(*actx->path,'/')))
|
|
|
2ec747 |
arname++;
|
|
|
2ec747 |
|
|
|
2ec747 |
if (!arname)
|
|
|
2ec747 |
arname = *actx->path;
|
|
|
2ec747 |
|
|
|
2ec747 |
if (slbt_dprintf(fdout,"\n") < 0)
|
|
|
2ec747 |
return SLBT_NESTED_ERROR(mctx->dctx);
|
|
|
2ec747 |
|
|
|
2ec747 |
if (slbt_snprintf(symname,sizeof(symname),"%s\",",arname) < 0)
|
|
|
2ec747 |
return SLBT_SYSTEM_ERROR(mctx->dctx,0);
|
|
|
2ec747 |
|
|
|
2ec747 |
if (slbt_dprintf(fdout,dlsymfmt,symname,"","0") < 0)
|
|
|
2ec747 |
return SLBT_NESTED_ERROR(mctx->dctx);
|
|
|
2ec747 |
|
|
|
2ec747 |
ret = slbt_ar_dlsyms_add_by_type(fdout,mctx,dlsymfmt,'A',&symname);
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_add_by_type(fdout,mctx,dlsymfmt,'B',&symname);
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_add_by_type(fdout,mctx,dlsymfmt,'C',&symname);
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_add_by_type(fdout,mctx,dlsymfmt,'D',&symname);
|
|
|
2ec747 |
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_add_by_type(fdout,mctx,dlsymfmt,'G',&symname);
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_add_by_type(fdout,mctx,dlsymfmt,'I',&symname);
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_add_by_type(fdout,mctx,dlsymfmt,'R',&symname);
|
|
|
2ec747 |
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_add_by_type(fdout,mctx,dlsymfmt,'S',&symname);
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_add_by_type(fdout,mctx,dlsymfmt,'S',&symname);
|
|
|
2ec747 |
ret |= slbt_ar_dlsyms_add_by_type(fdout,mctx,dlsymfmt,'T',&symname);
|
|
|
2ec747 |
|
|
|
2ec747 |
if (ret < 0)
|
|
|
2ec747 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
2ec747 |
}
|
|
|
2ec747 |
|
|
|
25a7d0 |
/* null-terminate the vtable */
|
|
|
25a7d0 |
if (slbt_dprintf(fdout,"\n\t{%d,%*c%d}\n",0,len,' ',0) < 0)
|
|
|
25a7d0 |
return SLBT_NESTED_ERROR(mctx->dctx);
|
|
|
25a7d0 |
|
|
|
2ec747 |
/* close vtable, wrap translation unit */
|
|
|
2ec747 |
if (slbt_dprintf(fdout,
|
|
|
2ec747 |
"};\n\n"
|
|
|
2ec747 |
"#ifdef __cplusplus\n"
|
|
|
2ec747 |
"}\n"
|
|
|
2ec747 |
"#endif\n") < 0)
|
|
|
2ec747 |
return SLBT_SYSTEM_ERROR(dctx,0);
|
|
|
2ec747 |
|
|
|
2ec747 |
return 0;
|
|
|
2ec747 |
}
|
|
|
2ec747 |
|
|
|
2ec747 |
|
|
|
2ec747 |
static int slbt_ar_create_dlsyms_impl(
|
|
|
2ec747 |
struct slbt_archive_ctx ** arctxv,
|
|
|
2ec747 |
const char * dlunit,
|
|
|
2ec747 |
const char * path,
|
|
|
2ec747 |
mode_t mode)
|
|
|
2ec747 |
{
|
|
|
2ec747 |
int ret;
|
|
|
6f477a |
struct slbt_archive_ctx ** actx;
|
|
|
6f477a |
struct slbt_exec_ctx * ectx;
|
|
|
2ec747 |
struct slbt_archive_meta_impl * mctx;
|
|
|
2ec747 |
const struct slbt_driver_ctx * dctx;
|
|
|
2ec747 |
struct slbt_fd_ctx fdctx;
|
|
|
2ec747 |
int fdout;
|
|
|
2ec747 |
|
|
|
2ec747 |
mctx = slbt_archive_meta_ictx(arctxv[0]->meta);
|
|
|
2ec747 |
dctx = mctx->dctx;
|
|
|
6f477a |
ectx = 0;
|
|
|
2ec747 |
|
|
|
2ec747 |
if (slbt_lib_get_driver_fdctx(dctx,&fdctx) < 0)
|
|
|
2ec747 |
return SLBT_NESTED_ERROR(dctx);
|
|
|
2ec747 |
|
|
|
2ec747 |
if (path) {
|
|
|
2ec747 |
if ((fdout = openat(
|
|
|
2ec747 |
fdctx.fdcwd,path,
|
|
|
2ec747 |
O_WRONLY|O_CREAT|O_TRUNC,
|
|
|
2ec747 |
mode)) < 0)
|
|
|
926d54 |
return SLBT_SYSTEM_ERROR(dctx,path);
|
|
|
2ec747 |
} else {
|
|
|
2ec747 |
fdout = fdctx.fdout;
|
|
|
2ec747 |
}
|
|
|
2ec747 |
|
|
|
6f477a |
for (actx=arctxv; *actx; actx++) {
|
|
|
6f477a |
mctx = slbt_archive_meta_ictx((*actx)->meta);
|
|
|
6f477a |
|
|
|
6f477a |
if (!mctx->syminfo && !ectx)
|
|
|
6f477a |
if (slbt_ectx_get_exec_ctx(dctx,&ectx) < 0)
|
|
|
6f477a |
return SLBT_NESTED_ERROR(dctx);
|
|
|
6f477a |
|
|
|
6f477a |
if (!mctx->syminfo)
|
|
|
3077bb |
if (slbt_ar_update_syminfo(*actx) < 0)
|
|
|
6f477a |
return SLBT_NESTED_ERROR(dctx);
|
|
|
6f477a |
}
|
|
|
6f477a |
|
|
|
6f477a |
if (ectx)
|
|
|
6f477a |
slbt_ectx_free_exec_ctx(ectx);
|
|
|
6f477a |
|
|
|
2ec747 |
ret = slbt_ar_output_dlsyms_impl(
|
|
|
2ec747 |
fdout,dctx,arctxv,dlunit);
|
|
|
2ec747 |
|
|
|
2ec747 |
if (path) {
|
|
|
2ec747 |
close(fdout);
|
|
|
2ec747 |
}
|
|
|
2ec747 |
|
|
|
2ec747 |
return ret;
|
|
|
2ec747 |
}
|
|
|
2ec747 |
|
|
|
2ec747 |
|
|
|
2ec747 |
int slbt_ar_create_dlsyms(
|
|
|
2ec747 |
struct slbt_archive_ctx ** arctxv,
|
|
|
2ec747 |
const char * dlunit,
|
|
|
2ec747 |
const char * path,
|
|
|
2ec747 |
mode_t mode)
|
|
|
2ec747 |
{
|
|
|
2ec747 |
return slbt_ar_create_dlsyms_impl(arctxv,dlunit,path,mode);
|
|
|
2ec747 |
}
|