Update tccmacho.c for weak symbols. Undo tests/tcctest.c disable weak symbols test.
Unified · Split
| @@ -304,7 +304,7 @@ struct macho { · 303 unmodified lines | |||
| 304 | } sk_to_sect[sk_last]; | 304 | } sk_to_sect[sk_last]; |
| 305 | int *elfsectomacho; | 305 | int *elfsectomacho; |
| 306 | int *e2msym; | 306 | int *e2msym; |
| 307 | Section *rebase, *binding, *lazy_binding, *exports; | 307 | Section *rebase, *binding, *weak_binding, *lazy_binding, *exports; |
| 308 | Section *symtab, *strtab, *wdata, *indirsyms; | 308 | Section *symtab, *strtab, *wdata, *indirsyms; |
| 309 | Section *stubs, *stub_helper, *la_symbol_ptr; | 309 | Section *stubs, *stub_helper, *la_symbol_ptr; |
| 310 | int nr_plt, n_got; | 310 | int nr_plt, n_got; |
| @@ -887,6 +887,7 @@ static void create_symtab(TCCState *s1, struct macho *mo) · 576 unmodified lines | |||
| 887 | SHN_UNDEF, "dyld_stub_binder"); | 887 | SHN_UNDEF, "dyld_stub_binder"); |
| 888 | mo->rebase = new_section(s1, "REBASE", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE); | 888 | mo->rebase = new_section(s1, "REBASE", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE); |
| 889 | mo->binding = new_section(s1, "BINDING", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE); | 889 | mo->binding = new_section(s1, "BINDING", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE); |
| 890 | mo->weak_binding = new_section(s1, "WEAK_BINDING", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE); | ||
| 890 | mo->lazy_binding = new_section(s1, "LAZY_BINDING", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE); | 891 | mo->lazy_binding = new_section(s1, "LAZY_BINDING", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE); |
| 891 | mo->exports = new_section(s1, "EXPORT", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE); | 892 | mo->exports = new_section(s1, "EXPORT", SHT_LINKEDIT, SHF_ALLOC | SHF_WRITE); |
| 892 | 893 | ||
| @@ -1003,11 +1004,14 @@ static void do_bind_rebase(TCCState *s1, struct macho *mo) · 110 unmodified lines | |||
| 1003 | } | 1004 | } |
| 1004 | for (i = 0; i < mo->n_bind; i++) { | 1005 | for (i = 0; i < mo->n_bind; i++) { |
| 1005 | int sym_index = ELFW(R_SYM)(mo->bind[i].rel.r_info); | 1006 | int sym_index = ELFW(R_SYM)(mo->bind[i].rel.r_info); |
| 1007 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; | ||
| 1006 | Section *s = s1->sections[mo->bind[i].section]; | 1008 | Section *s = s1->sections[mo->bind[i].section]; |
| 1009 | Section *binding = ELFW(ST_BIND)(sym->st_info) == STB_WEAK | ||
| 1010 | ? mo->weak_binding : mo->binding; | ||
| 1007 | 1011 | ||
| 1008 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; | 1012 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; |
| 1009 | name = (char *) symtab_section->link->data + sym->st_name; | 1013 | name = (char *) symtab_section->link->data + sym->st_name; |
| 1010 | ptr = section_ptr_add(mo->binding, 5 + strlen(name)); | 1014 | ptr = section_ptr_add(binding, 5 + strlen(name)); |
| 1011 | *ptr++ = BIND_OPCODE_SET_DYLIB_SPECIAL_IMM | | 1015 | *ptr++ = BIND_OPCODE_SET_DYLIB_SPECIAL_IMM | |
| 1012 | (BIND_SPECIAL_DYLIB_FLAT_LOOKUP & 0xf); | 1016 | (BIND_SPECIAL_DYLIB_FLAT_LOOKUP & 0xf); |
| 1013 | *ptr++ = BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | 0; | 1017 | *ptr++ = BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | 0; |
| @@ -1016,9 +1020,9 @@ static void do_bind_rebase(TCCState *s1, struct macho *mo) · 2 unmodified lines | |||
| 1016 | *ptr++ = BIND_OPCODE_SET_TYPE_IMM | BIND_TYPE_POINTER; | 1020 | *ptr++ = BIND_OPCODE_SET_TYPE_IMM | BIND_TYPE_POINTER; |
| 1017 | set_segment_and_offset(mo, s->sh_addr, ptr, | 1021 | set_segment_and_offset(mo, s->sh_addr, ptr, |
| 1018 | BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB, | 1022 | BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB, |
| 1019 | mo->binding, | 1023 | binding, |
| 1020 | mo->bind[i].rel.r_offset + s->sh_addr); | 1024 | mo->bind[i].rel.r_offset + s->sh_addr); |
| 1021 | ptr = section_ptr_add(mo->binding, 1); | 1025 | ptr = section_ptr_add(binding, 1); |
| 1022 | *ptr++ = BIND_OPCODE_DO_BIND; | 1026 | *ptr++ = BIND_OPCODE_DO_BIND; |
| 1023 | } | 1027 | } |
| 1024 | if (mo->rebase->data_offset) { | 1028 | if (mo->rebase->data_offset) { |
| @@ -1270,6 +1274,10 @@ static void collect_sections(TCCState *s1, struct macho *mo) · 245 unmodified lines | |||
| 1270 | mo->dyldinfo->bind_off = mo->binding->sh_offset; | 1274 | mo->dyldinfo->bind_off = mo->binding->sh_offset; |
| 1271 | mo->dyldinfo->bind_size = mo->binding->data_offset; | 1275 | mo->dyldinfo->bind_size = mo->binding->data_offset; |
| 1272 | } | 1276 | } |
| 1277 | if (mo->weak_binding->data_offset) { | ||
| 1278 | mo->dyldinfo->weak_bind_off = mo->weak_binding->sh_offset; | ||
| 1279 | mo->dyldinfo->weak_bind_size = mo->weak_binding->data_offset; | ||
| 1280 | } | ||
| 1273 | if (mo->lazy_binding->data_offset) { | 1281 | if (mo->lazy_binding->data_offset) { |
| 1274 | mo->dyldinfo->lazy_bind_off = mo->lazy_binding->sh_offset; | 1282 | mo->dyldinfo->lazy_bind_off = mo->lazy_binding->sh_offset; |
| 1275 | mo->dyldinfo->lazy_bind_size = mo->lazy_binding->data_offset; | 1283 | mo->dyldinfo->lazy_bind_size = mo->lazy_binding->data_offset; |
| @@ -3898,7 +3898,7 @@ void builtin_test(void) · 3897 unmodified lines | |||
| 3898 | //printf("bera: %p\n", __builtin_extract_return_addr((void*)43)); | 3898 | //printf("bera: %p\n", __builtin_extract_return_addr((void*)43)); |
| 3899 | } | 3899 | } |
| 3900 | 3900 | ||
| 3901 | #if defined _WIN32 || defined __APPLE__ | 3901 | #if defined _WIN32 |
| 3902 | void weak_test(void) {} | 3902 | void weak_test(void) {} |
| 3903 | #else | 3903 | #else |
| 3904 | extern int __attribute__((weak)) weak_f1(void); | 3904 | extern int __attribute__((weak)) weak_f1(void); |