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:
parent
cc11750bda
commit
71b0634168
4 changed files with 35 additions and 13 deletions
3
tcc.h
3
tcc.h
|
@ -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 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,
|
||||
void (*symbol_cb)(void *ctx, const char *name, const void *val));
|
||||
#if defined TCC_IS_NATIVE || defined TCC_TARGET_PE
|
||||
|
|
32
tccelf.c
32
tccelf.c
|
@ -481,13 +481,33 @@ ST_FUNC int find_elf_sym(Section *s, const char *name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* return elf symbol value, signal error if 'err' is nonzero */
|
||||
ST_FUNC addr_t get_elf_sym_addr(TCCState *s1, const char *name, int err)
|
||||
ST_FUNC int find_c_sym(TCCState *s1, const char *name)
|
||||
{
|
||||
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;
|
||||
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];
|
||||
if (!sym_index || sym->st_shndx == SHN_UNDEF) {
|
||||
if (err)
|
||||
|
@ -524,7 +544,7 @@ ST_FUNC void list_elf_symbols(TCCState *s, void *ctx,
|
|||
/* 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);
|
||||
return (void*)(uintptr_t)get_sym_addr(s, name, 0, 1);
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
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
|
||||
|
||||
|
@ -2177,7 +2197,7 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr,
|
|||
default:
|
||||
case TCC_OUTPUT_EXE:
|
||||
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;
|
||||
case TCC_OUTPUT_DLL:
|
||||
ehdr.e_type = ET_DYN;
|
||||
|
|
|
@ -818,7 +818,7 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename)
|
|||
Section *s;
|
||||
collect_sections(s1, &mo);
|
||||
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)
|
||||
goto do_ret;
|
||||
|
||||
|
|
11
tccrun.c
11
tccrun.c
|
@ -126,8 +126,8 @@ ST_FUNC void tcc_run_free(TCCState *s1)
|
|||
|
||||
static void run_cdtors(TCCState *s1, const char *start, const char *end)
|
||||
{
|
||||
void **a = tcc_get_symbol(s1, start);
|
||||
void **b = tcc_get_symbol(s1, end);
|
||||
void **a = (void **)get_sym_addr(s1, start, 0, 0);
|
||||
void **b = (void **)get_sym_addr(s1, end, 0, 0);
|
||||
while (a != b)
|
||||
((void(*)(void))*a++)();
|
||||
}
|
||||
|
@ -140,12 +140,12 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
|||
rt_context *rc = &g_rtctxt;
|
||||
#endif
|
||||
|
||||
s1->runtime_main = s1->nostdlib ? "_start" : s1->leading_underscore ? "_main" : "main";
|
||||
if ((s1->dflag & 16) && !find_elf_sym(s1->symtab, s1->runtime_main))
|
||||
s1->runtime_main = s1->nostdlib ? "_start" : "main";
|
||||
if ((s1->dflag & 16) && !find_c_sym(s1, s1->runtime_main))
|
||||
return 0;
|
||||
#ifdef CONFIG_TCC_BACKTRACE
|
||||
if (s1->do_debug)
|
||||
tcc_add_symbol(s1, "exit", rt_exit);
|
||||
tcc_add_symbol(s1, "_exit" + !s1->leading_underscore, rt_exit);
|
||||
#endif
|
||||
if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0)
|
||||
return -1;
|
||||
|
@ -182,6 +182,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv)
|
|||
errno = 0; /* clean errno value */
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
/* These aren't C symbols, so don't need leading underscore handling. */
|
||||
run_cdtors(s1, "__init_array_start", "__init_array_end");
|
||||
#ifdef CONFIG_TCC_BACKTRACE
|
||||
if (!rc->do_jmp || !(ret = setjmp(rc->jmp_buf)))
|
||||
|
|
Loading…
Reference in a new issue