Add function to list all symbols, for purpose of linking separate in-memory compilations

mob
Jan Boon 2019-09-16 15:24:16 +08:00
parent c6635504fe
commit 944c4003bd
3 changed files with 37 additions and 0 deletions

View File

@ -93,6 +93,10 @@ LIBTCCAPI int tcc_relocate(TCCState *s1, void *ptr);
/* return symbol value or NULL if not found */
LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name);
/* return symbol value or NULL if not found */
LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
void (*symbol_cb)(void *ctx, const char *name, const void *val));
#ifdef __cplusplus
}
#endif

2
tcc.h
View File

@ -1470,6 +1470,8 @@ ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc);
ST_FUNC void squeeze_multi_relocs(Section *sec, size_t oldrelocoffset);
ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err);
ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
void (*symbol_cb)(void *ctx, const char *name, const void *val));
#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
ST_FUNC void *tcc_get_symbol_err(TCCState *s, const char *name);
#endif

View File

@ -471,12 +471,43 @@ ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err)
return sym->st_value;
}
/* list elf symbol names and values */
ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
void (*symbol_cb)(void *ctx, const char *name, const void *val))
{
ElfW(Sym) *sym;
Section *symtab;
int sym_index, end_sym;
const char *name;
unsigned char sym_vis, sym_bind;
symtab = s->symtab;
end_sym = symtab->data_offset / sizeof (ElfSym);
for (sym_index = 0; sym_index < end_sym; ++sym_index) {
sym = &((ElfW(Sym) *)symtab->data)[sym_index];
if (sym->st_value) {
name = (char *) symtab->link->data + sym->st_name;
sym_bind = ELFW(ST_BIND)(sym->st_info);
sym_vis = ELFW(ST_VISIBILITY)(sym->st_other);
if (sym_bind == STB_GLOBAL && sym_vis == STV_DEFAULT)
symbol_cb(ctx, name, (void*)(uintptr_t)sym->st_value);
}
}
}
/* return elf symbol value */
LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
{
return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0);
}
/* list elf symbol names and values */
LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
void (*symbol_cb)(void *ctx, const char *name, const void *val))
{
list_elf_symbols(s, ctx, symbol_cb);
}
#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
/* return elf symbol value or error */
ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)