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.
Unified · Split
| @@ -1535,7 +1535,8 @@ ST_FUNC void build_got_entries(TCCState *s1); · 1534 unmodified lines | ||
| 1535 | 1535 | ST_FUNC struct sym_attr *get_sym_attr(TCCState *s1, int index, int alloc); |
| 1536 | 1536 | ST_FUNC void squeeze_multi_relocs(Section *sec, size_t oldrelocoffset); |
| 1537 | 1537 | |
| 1538 | −ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err); | |
| 1538 | +ST_FUNC int find_c_sym(TCCState *, const char *name); | |
| 1539 | +ST_FUNC addr_t get_sym_addr(TCCState *s, const char *name, int err, int forc); | |
| 1539 | 1540 | ST_FUNC void list_elf_symbols(TCCState *s, void *ctx, |
| 1540 | 1541 | void (*symbol_cb)(void *ctx, const char *name, const void *val)); |
| 1541 | 1542 | #if defined TCC_IS_NATIVE || defined TCC_TARGET_PE |
| @@ -481,13 +481,33 @@ ST_FUNC int find_elf_sym(Section *s, const char *name) · 480 unmodified lines | ||
| 481 | 481 | return 0; |
| 482 | 482 | } |
| 483 | 483 | |
| 484 | −/* return elf symbol value, signal error if 'err' is nonzero */ | |
| 485 | −ST_FUNC addr_t get_elf_sym_addr(TCCState *s1, const char *name, int err) | |
| 484 | +ST_FUNC int find_c_sym(TCCState *s1, const char *name) | |
| 485 | +{ | |
| 486 | + int ret; | |
| 487 | + CString cstr; | |
| 488 | + if (s1->leading_underscore) { | |
| 489 | + cstr_new(&cstr); | |
| 490 | + cstr_ccat(&cstr, '_'); | |
| 491 | + cstr_cat(&cstr, name, 0); | |
| 492 | + name = cstr.data; | |
| 493 | + } | |
| 494 | + ret = find_elf_sym(s1->symtab, name); | |
| 495 | + if (s1->leading_underscore) | |
| 496 | + cstr_free(&cstr); | |
| 497 | + return ret; | |
| 498 | +} | |
| 499 | + | |
| 500 | +/* return elf symbol value, signal error if 'err' is nonzero, decorate | |
| 501 | + name if FORC */ | |
| 502 | +ST_FUNC addr_t get_sym_addr(TCCState *s1, const char *name, int err, int forc) | |
| 486 | 503 | { |
| 487 | 504 | int sym_index; |
| 488 | 505 | ElfW(Sym) *sym; |
| 489 | 506 | |
| 490 | − sym_index = find_elf_sym(s1->symtab, name); | |
| 507 | + if (forc) | |
| 508 | + sym_index = find_c_sym(s1, name); | |
| 509 | + else | |
| 510 | + sym_index = find_elf_sym(s1->symtab, name); | |
| 491 | 511 | sym = &((ElfW(Sym) *)s1->symtab->data)[sym_index]; |
| 492 | 512 | if (!sym_index || sym->st_shndx == SHN_UNDEF) { |
| 493 | 513 | if (err) |
| @@ -524,7 +544,7 @@ ST_FUNC void list_elf_symbols(TCCState *s, void *ctx, · 30 unmodified lines | ||
| 524 | 544 | /* return elf symbol value */ |
| 525 | 545 | LIBTCCAPI void *tcc_get_symbol(TCCState *s, const char *name) |
| 526 | 546 | { |
| 527 | − return (void*)(uintptr_t)get_elf_sym_addr(s, name, 0); | |
| 547 | + return (void*)(uintptr_t)get_sym_addr(s, name, 0, 1); | |
| 528 | 548 | } |
| 529 | 549 | |
| 530 | 550 | /* list elf symbol names and values */ |
| @@ -538,7 +558,7 @@ LIBTCCAPI void tcc_list_symbols(TCCState *s, void *ctx, · 7 unmodified lines | ||
| 538 | 558 | /* return elf symbol value or error */ |
| 539 | 559 | ST_FUNC void* tcc_get_symbol_err(TCCState *s, const char *name) |
| 540 | 560 | { |
| 541 | − return (void*)(uintptr_t)get_elf_sym_addr(s, name, 1); | |
| 561 | + return (void*)(uintptr_t)get_sym_addr(s, name, 1, 1); | |
| 542 | 562 | } |
| 543 | 563 | #endif |
| 544 | 564 | |
| @@ -2177,7 +2197,7 @@ static void tcc_output_elf(TCCState *s1, FILE *f, int phnum, ElfW(Phdr) *phdr, · 1632 unmodified lines | ||
| 2177 | 2197 | default: |
| 2178 | 2198 | case TCC_OUTPUT_EXE: |
| 2179 | 2199 | ehdr.e_type = ET_EXEC; |
| 2180 | − ehdr.e_entry = get_elf_sym_addr(s1, "_start", 1); | |
| 2200 | + ehdr.e_entry = get_sym_addr(s1, "_start", 1, 0); | |
| 2181 | 2201 | break; |
| 2182 | 2202 | case TCC_OUTPUT_DLL: |
| 2183 | 2203 | ehdr.e_type = ET_DYN; |
| @@ -818,7 +818,7 @@ ST_FUNC int macho_output_file(TCCState *s1, const char *filename) · 817 unmodified lines | ||
| 818 | 818 | Section *s; |
| 819 | 819 | collect_sections(s1, &mo); |
| 820 | 820 | relocate_syms(s1, s1->symtab, 0); |
| 821 | − mo.ep.entryoff = get_elf_sym_addr(s1, "_main", 1) - mo.seg[1]->vmaddr; | |
| 821 | + mo.ep.entryoff = get_sym_addr(s1, "_main", 1, 0) - mo.seg[1]->vmaddr; | |
| 822 | 822 | if (s1->nb_errors) |
| 823 | 823 | goto do_ret; |
| 824 | 824 | |
| @@ -126,8 +126,8 @@ ST_FUNC void tcc_run_free(TCCState *s1) · 125 unmodified lines | ||
| 126 | 126 | |
| 127 | 127 | static void run_cdtors(TCCState *s1, const char *start, const char *end) |
| 128 | 128 | { |
| 129 | − void **a = tcc_get_symbol(s1, start); | |
| 130 | − void **b = tcc_get_symbol(s1, end); | |
| 129 | + void **a = (void **)get_sym_addr(s1, start, 0, 0); | |
| 130 | + void **b = (void **)get_sym_addr(s1, end, 0, 0); | |
| 131 | 131 | while (a != b) |
| 132 | 132 | ((void(*)(void))*a++)(); |
| 133 | 133 | } |
| @@ -140,12 +140,12 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 6 unmodified lines | ||
| 140 | 140 | rt_context *rc = &g_rtctxt; |
| 141 | 141 | #endif |
| 142 | 142 | |
| 143 | − s1->runtime_main = s1->nostdlib ? "_start" : s1->leading_underscore ? "_main" : "main"; | |
| 144 | − if ((s1->dflag & 16) && !find_elf_sym(s1->symtab, s1->runtime_main)) | |
| 143 | + s1->runtime_main = s1->nostdlib ? "_start" : "main"; | |
| 144 | + if ((s1->dflag & 16) && !find_c_sym(s1, s1->runtime_main)) | |
| 145 | 145 | return 0; |
| 146 | 146 | #ifdef CONFIG_TCC_BACKTRACE |
| 147 | 147 | if (s1->do_debug) |
| 148 | − tcc_add_symbol(s1, "exit", rt_exit); | |
| 148 | + tcc_add_symbol(s1, "_exit" + !s1->leading_underscore, rt_exit); | |
| 149 | 149 | #endif |
| 150 | 150 | if (tcc_relocate(s1, TCC_RELOCATE_AUTO) < 0) |
| 151 | 151 | return -1; |
| @@ -182,6 +182,7 @@ LIBTCCAPI int tcc_run(TCCState *s1, int argc, char **argv) · 30 unmodified lines | ||
| 182 | 182 | errno = 0; /* clean errno value */ |
| 183 | 183 | fflush(stdout); |
| 184 | 184 | fflush(stderr); |
| 185 | + /* These aren't C symbols, so don't need leading underscore handling. */ | |
| 185 | 186 | run_cdtors(s1, "__init_array_start", "__init_array_end"); |
| 186 | 187 | #ifdef CONFIG_TCC_BACKTRACE |
| 187 | 188 | if (!rc->do_jmp || !(ret = setjmp(rc->jmp_buf))) |