Fix dll support for macho

Export now all global symbols in export trie instead of only text
symbols.

I wrote too much data into dylib file because I did not check
for sk_unknown/sk_discard/sk_uw_info.

Simplified code in tccrun.c
This commit is contained in:
herman ten brugge 2022-12-18 14:07:19 +01:00
parent 04810db83a
commit f6f3d646fb
2 changed files with 12 additions and 17 deletions

View File

@ -1529,7 +1529,7 @@ static void export_trie(TCCState *s1, struct macho *mo)
ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index; ElfW(Sym) *sym = (ElfW(Sym) *)symtab_section->data + sym_index;
const char *name = (char*)symtab_section->link->data + sym->st_name; const char *name = (char*)symtab_section->link->data + sym->st_name;
if (sym->st_shndx == text_section->sh_num && if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE &&
(ELFW(ST_BIND)(sym->st_info) == STB_GLOBAL || (ELFW(ST_BIND)(sym->st_info) == STB_GLOBAL ||
ELFW(ST_BIND)(sym->st_info) == STB_WEAK)) { ELFW(ST_BIND)(sym->st_info) == STB_WEAK)) {
int flag = EXPORT_SYMBOL_FLAGS_KIND_REGULAR; int flag = EXPORT_SYMBOL_FLAGS_KIND_REGULAR;
@ -1538,7 +1538,7 @@ static void export_trie(TCCState *s1, struct macho *mo)
if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK) if (ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
flag |= EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION; flag |= EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;
dprintf ("%s %d %llx\n", name, flag, addr + vm_addr); dprintf ("%s %d %llx\n", name, flag, (long long)addr + vm_addr);
trie = tcc_realloc(trie, (n_trie + 1) * sizeof(struct trie_info)); trie = tcc_realloc(trie, (n_trie + 1) * sizeof(struct trie_info));
trie[n_trie].name = name; trie[n_trie].name = name;
trie[n_trie].flag = flag; trie[n_trie].flag = flag;
@ -1769,7 +1769,7 @@ static void collect_sections(TCCState *s1, struct macho *mo, const char *filenam
seg = NULL; seg = NULL;
numsec = 0; numsec = 0;
mo->elfsectomacho = tcc_mallocz(sizeof(*mo->elfsectomacho) * s1->nb_sections); mo->elfsectomacho = tcc_mallocz(sizeof(*mo->elfsectomacho) * s1->nb_sections);
for (sk = sk_text; sk < sk_last; sk++) { for (sk = sk_unknown; sk < sk_last; sk++) {
struct section_64 *sec = NULL; struct section_64 *sec = NULL;
if (seg) { if (seg) {
seg->vmsize = curaddr - seg->vmaddr; seg->vmsize = curaddr - seg->vmaddr;
@ -1786,7 +1786,8 @@ static void collect_sections(TCCState *s1, struct macho *mo, const char *filenam
export_trie(s1, mo); export_trie(s1, mo);
} }
#endif #endif
if ((s1->output_type != TCC_OUTPUT_EXE || mo->segment[sk]) && if (skinfo[sk].seg_initial &&
(s1->output_type != TCC_OUTPUT_EXE || mo->segment[sk]) &&
mo->sk_to_sect[sk].s) { mo->sk_to_sect[sk].s) {
uint64_t al = 0; uint64_t al = 0;
int si; int si;
@ -1838,14 +1839,14 @@ static void collect_sections(TCCState *s1, struct macho *mo, const char *filenam
for (s = mo->sk_to_sect[sk].s; s; s = s->prev) { for (s = mo->sk_to_sect[sk].s; s; s = s->prev) {
al = s->sh_addralign; al = s->sh_addralign;
curaddr = (curaddr + al - 1) & -al; curaddr = (curaddr + al - 1) & -al;
dprintf("curaddr now 0x%lx\n", (long)curaddr); dprintf("%s: curaddr now 0x%lx\n", s->name, (long)curaddr);
s->sh_addr = curaddr; s->sh_addr = curaddr;
curaddr += s->sh_size; curaddr += s->sh_size;
if (s->sh_type != SHT_NOBITS) { if (s->sh_type != SHT_NOBITS) {
fileofs = (fileofs + al - 1) & -al; fileofs = (fileofs + al - 1) & -al;
s->sh_offset = fileofs; s->sh_offset = fileofs;
fileofs += s->sh_size; fileofs += s->sh_size;
dprintf("fileofs now %ld\n", (long)fileofs); dprintf("%s: fileofs now %ld\n", s->name, (long)fileofs);
} }
if (sec) if (sec)
mo->elfsectomacho[s->sh_num] = numsec; mo->elfsectomacho[s->sh_num] = numsec;
@ -1964,7 +1965,8 @@ static void macho_write(TCCState *s1, struct macho *mo, FILE *fp)
for (sk = sk_unknown; sk < sk_last; sk++) { for (sk = sk_unknown; sk < sk_last; sk++) {
//struct segment_command_64 *seg; //struct segment_command_64 *seg;
if ((s1->output_type == TCC_OUTPUT_EXE && !mo->segment[sk]) || if (skinfo[sk].seg_initial == 0 ||
(s1->output_type == TCC_OUTPUT_EXE && !mo->segment[sk]) ||
!mo->sk_to_sect[sk].s) !mo->sk_to_sect[sk].s)
continue; continue;
/*seg =*/ get_segment(mo, mo->segment[sk]); /*seg =*/ get_segment(mo, mo->segment[sk]);
@ -2058,7 +2060,7 @@ ST_FUNC void bind_rebase_import(TCCState *s1, struct macho *mo)
for (j = 0; j < page_count; j++) { for (j = 0; j < page_count; j++) {
addr_t start = seg->vmaddr + j * SEG_PAGE_SIZE; addr_t start = seg->vmaddr + j * SEG_PAGE_SIZE;
addr_t end = start + SEG_PAGE_SIZE; addr_t end = start + SEG_PAGE_SIZE;
void *last; void *last = NULL;
addr_t last_o = 0; addr_t last_o = 0;
addr_t cur_o, cur; addr_t cur_o, cur;
struct dyld_chained_ptr_64_rebase *rebase; struct dyld_chained_ptr_64_rebase *rebase;

View File

@ -771,9 +771,6 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc,
} filename_table[FILE_TABLE_SIZE]; } filename_table[FILE_TABLE_SIZE];
addr_t last_pc; addr_t last_pc;
addr_t pc; addr_t pc;
#if defined TCC_TARGET_MACHO
addr_t first_pc;
#endif
addr_t func_addr; addr_t func_addr;
int line; int line;
char *filename; char *filename;
@ -782,9 +779,6 @@ static addr_t rt_printline_dwarf (rt_context *rc, addr_t wanted_pc,
next: next:
ln = rc->dwarf_line; ln = rc->dwarf_line;
while (ln < rc->dwarf_line_end) { while (ln < rc->dwarf_line_end) {
#if defined TCC_TARGET_MACHO
first_pc = 0;
#endif
dir_size = 0; dir_size = 0;
filename_size = 0; filename_size = 0;
last_pc = 0; last_pc = 0;
@ -937,9 +931,8 @@ check_pc:
pc = dwarf_read_8(cp, end); pc = dwarf_read_8(cp, end);
#endif #endif
#if defined TCC_TARGET_MACHO #if defined TCC_TARGET_MACHO
if (first_pc == 0 && rc->prog_base != (addr_t) -1) if (rc->prog_base != (addr_t) -1)
first_pc += rc->prog_base; pc += rc->prog_base;
pc += first_pc;
#endif #endif
opindex = 0; opindex = 0;
break; break;