mirror of https://github.com/frida/tinycc
Add tcc_set_linker_resolve_func()
Useful for resolving symbols dynamically.
This commit is contained in:
parent
949e096b02
commit
7e6ed199c2
7
libtcc.c
7
libtcc.c
|
@ -617,6 +617,13 @@ LIBTCCAPI void tcc_set_cpp_load_func(TCCState *s, void *cpp_load_opaque,
|
|||
s->cpp_load_func = cpp_load_func;
|
||||
}
|
||||
|
||||
LIBTCCAPI void tcc_set_linker_resolve_func(TCCState *s, void *resolve_opaque,
|
||||
void *(*resolve_func)(void *opaque, const char *name))
|
||||
{
|
||||
s->linker_resolve_opaque = resolve_opaque;
|
||||
s->linker_resolve_func = resolve_func;
|
||||
}
|
||||
|
||||
/* error without aborting current compilation */
|
||||
PUB_FUNC void _tcc_error_noabort(const char *fmt, ...)
|
||||
{
|
||||
|
|
4
libtcc.h
4
libtcc.h
|
@ -37,6 +37,10 @@ LIBTCCAPI void *tcc_get_error_opaque(TCCState *s);
|
|||
LIBTCCAPI void tcc_set_cpp_load_func(TCCState *s, void *cpp_load_opaque,
|
||||
const char *(*cpp_load_func)(void *opaque, const char *path, int *len));
|
||||
|
||||
/* set linker resolver callback */
|
||||
LIBTCCAPI void tcc_set_linker_resolve_func(TCCState *s, void *resolve_opaque,
|
||||
void *(*resolve_func)(void *opaque, const char *name));
|
||||
|
||||
/* set options as from command line (multiple supported) */
|
||||
LIBTCCAPI void tcc_set_options(TCCState *s, const char *str);
|
||||
|
||||
|
|
4
tcc.h
4
tcc.h
|
@ -805,6 +805,10 @@ struct TCCState {
|
|||
void *cpp_load_opaque;
|
||||
const char *(*cpp_load_func)(void *opaque, const char *path, int *len);
|
||||
|
||||
/* linker symbol handling */
|
||||
void *linker_resolve_opaque;
|
||||
void *(*linker_resolve_func)(void *opaque, const char *name);
|
||||
|
||||
/* output file for preprocessing (-E) */
|
||||
FILE *ppfp;
|
||||
enum {
|
||||
|
|
18
tccelf.c
18
tccelf.c
|
@ -898,20 +898,34 @@ ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve)
|
|||
ElfW(Sym) *sym;
|
||||
int sym_bind, sh_num;
|
||||
const char *name;
|
||||
void *addr;
|
||||
|
||||
for_each_elem(symtab, 1, sym, ElfW(Sym)) {
|
||||
sh_num = sym->st_shndx;
|
||||
if (sh_num == SHN_UNDEF) {
|
||||
name = (char *) s1->symtab->link->data + sym->st_name;
|
||||
|
||||
if (s1->linker_resolve_func) {
|
||||
addr = s1->linker_resolve_func(s1->linker_resolve_opaque, name);
|
||||
if (addr) {
|
||||
sym->st_value = (addr_t) addr;
|
||||
#ifdef DEBUG_RELOC
|
||||
printf ("relocate_sym: %s -> 0x%lx\n", name,
|
||||
sym->st_value);
|
||||
#endif
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use ld.so to resolve symbol for us (for tcc -run) */
|
||||
if (do_resolve) {
|
||||
#if defined TCC_IS_NATIVE && !defined TCC_TARGET_PE
|
||||
#ifdef TCC_TARGET_MACHO
|
||||
/* The symbols in the symtables have a prepended '_'
|
||||
but dlsym() needs the undecorated name. */
|
||||
void *addr = dlsym(RTLD_DEFAULT, name + 1);
|
||||
addr = dlsym(RTLD_DEFAULT, name + 1);
|
||||
#else
|
||||
void *addr = dlsym(RTLD_DEFAULT, name);
|
||||
addr = dlsym(RTLD_DEFAULT, name);
|
||||
#endif
|
||||
if (addr) {
|
||||
sym->st_value = (addr_t) addr;
|
||||
|
|
14
tccpe.c
14
tccpe.c
|
@ -1248,8 +1248,22 @@ static int pe_check_symbols(struct pe_info *pe)
|
|||
int imp_sym = pe_find_import(pe->s1, sym);
|
||||
struct import_symbol *is;
|
||||
|
||||
if (imp_sym <= 0) {
|
||||
TCCState *s1 = pe->s1;
|
||||
|
||||
if (s1->linker_resolve_func) {
|
||||
void *addr = s1->linker_resolve_func(
|
||||
s1->linker_resolve_opaque,
|
||||
name);
|
||||
if (addr) {
|
||||
tcc_add_symbol(s1, name, addr);
|
||||
imp_sym = pe_find_import(s1, sym);
|
||||
}
|
||||
}
|
||||
|
||||
if (imp_sym <= 0)
|
||||
goto not_found;
|
||||
}
|
||||
|
||||
if (type == STT_NOTYPE) {
|
||||
/* symbols from assembler have no type, find out which */
|
||||
|
|
Loading…
Reference in New Issue