Add find_c_sym and friends

for handling leading underscores when looking up symbols.
Necessary on MacOS, as there C symbols have a '_' prepended.
get_sym_addr (replacing get_elf_sym_addr) gets an argument to
specify if bare/raw/ELF symbols should be looked up or if decorated
C symbols should be looked up.  That reflects into tcc_get_symbol.
tcc_add_symbol is _not_ yet changed, but probably should be.
This commit is contained in:
Michael Matz 2020-05-22 04:28:02 +02:00
parent cc11750bda
commit 71b0634168
4 changed files with 35 additions and 13 deletions

3
tcc.h
View File

@ -1535,7 +1535,8 @@ ST_FUNC void build_got_entries(TCCState *s1);
ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc); 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 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 int find_c_sym(TCCState *, const char *name);
ST_FUNC addr_t get_sym_addr(TCCState *s, const char *name, int err, int forc);
ST_FUNC void list_elf_symbols(TCCState *s, void *ctx, ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
void (*symbol_cb)(void *ctx, const char *name, const void *val)); void (*symbol_cb)(void *ctx, const char *name, const void *val));
#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE

View File

@ -481,13 +481,33 @@ ST_FUNC int find_elf_sym(Section *s, const char *name)
return 0; return 0;
} }
/* return elf symbol value, signal error if 'err' is nonzero */ ST_FUNC int find_c_sym(TCCState *s1, const char *name)
ST_FUNC addr_t get_elf_sym_addr(TCCState *s1, const char *name, int err) {
int ret;
CString cstr;
if (s1->leading_underscore) {
cstr_new(&cstr);
cstr_ccat(&cstr, '_');
cstr_cat(&cstr, name, 0);
name = cstr.data;
}
ret = find_elf_sym(s1->symtab, name);
if (s1->leading_underscore)
cstr_free(&cstr);
return ret;
}
/* return elf symbol value, signal error if 'err' is nonzero, decorate
name if FORC */
ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc)
{ {
int sym_index; int sym_index;
ElfW(Sym) *sym; ElfW(Sym) *sym;
sym_index = find_elf_sym(s1->symtab, name); if (forc)
sym_index = find_c_sym(s1, name);
else
sym_index = find_elf_sym(s1->symtab, name);
sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index]; sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index];
if (!sym_index || sym->st_shndx == SHN_UNDEF) { if (!sym_index || sym->st_shndx == SHN_UNDEF) {
if (err) if (err)
@ -524,7 +544,7 @@ ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
/* return elf symbol value */ /* return elf symbol value */
LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name) LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name)
{ {
return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0); return (void*)(uintptr_t)get_sym_addr(s, name, 0, 1);
} }
/* list elf symbol names and values */ /* list elf symbol names and values */
@ -538,7 +558,7 @@ LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx,
/* return elf symbol value or error */ /* return elf symbol value or error */
ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name) ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name)
{ {
return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1); return (void*)(uintptr_t)get_sym_addr(s, name, 1, 1);
} }
#endif #endif
@ -2177,7 +2197,7 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
default: default:
case TCC_OUTPUT_EXE: case TCC_OUTPUT_EXE:
ehdr.e_type = ET_EXEC; ehdr.e_type = ET_EXEC;
ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1); ehdr.e_entry = get_sym_addr(s1, "_start", 1, 0);
break; break;
case TCC_OUTPUT_DLL: case TCC_OUTPUT_DLL:
ehdr.e_type = ET_DYN; ehdr.e_type = ET_DYN;

View File

@ -818,7 +818,7 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename)
Section *s; Section *s;
collect_sections(s1, &mo); collect_sections(s1, &mo);
relocate_syms(s1, s1->symtab, 0); relocate_syms(s1, s1->symtab, 0);
mo.ep.entryoff = get_elf_sym_addr(s1, "_main", 1) - mo.seg[1]->vmaddr; mo.ep.entryoff = get_sym_addr(s1, "_main", 1, 0) - mo.seg[1]->vmaddr;
if (s1->nb_errors) if (s1->nb_errors)
goto do_ret; goto do_ret;

View File

@ -126,8 +126,8 @@ ST_FUNC void tcc_run_free(TCCState *s1)
static void run_cdtors(TCCState *s1, const char *start, const char *end) static void run_cdtors(TCCState *s1, const char *start, const char *end)
{ {
void **a = tcc_get_symbol(s1, start); void **a = (void **)get_sym_addr(s1, start, 0, 0);
void **b = tcc_get_symbol(s1, end); void **b = (void **)get_sym_addr(s1, end, 0, 0);
while (a != b) while (a != b)
((void(*)(void))*a++)(); ((void(*)(void))*a++)();
} }
@ -140,12 +140,12 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
rt_context *rc = &g_rtctxt; rt_context *rc = &g_rtctxt;
#endif #endif
s1->runtime_main = s1->nostdlib ? "_start" : s1->leading_underscore ? "_main" : "main"; s1->runtime_main = s1->nostdlib ? "_start" : "main";
if ((s1->dflag & 16) && !find_elf_sym(s1->symtab, s1->runtime_main)) if ((s1->dflag & 16) && !find_c_sym(s1, s1->runtime_main))
return 0; return 0;
#ifdef CONFIG_TCC_BACKTRACE #ifdef CONFIG_TCC_BACKTRACE
if (s1->do_debug) if (s1->do_debug)
tcc_add_symbol(s1, "exit", rt_exit); tcc_add_symbol(s1, "_exit" + !s1->leading_underscore, rt_exit);
#endif #endif
if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0) if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
return -1; return -1;
@ -182,6 +182,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
errno = 0; /* clean errno value */ errno = 0; /* clean errno value */
fflush(stdout); fflush(stdout);
fflush(stderr); fflush(stderr);
/* These aren't C symbols, so don't need leading underscore handling. */
run_cdtors(s1, "__init_array_start", "__init_array_end"); run_cdtors(s1, "__init_array_start", "__init_array_end");
#ifdef CONFIG_TCC_BACKTRACE #ifdef CONFIG_TCC_BACKTRACE
if (!rc->do_jmp || !(ret = setjmp(rc->jmp_buf))) if (!rc->do_jmp || !(ret = setjmp(rc->jmp_buf)))