| @@ -299,6 +299,9 @@ static void rebuild_hash(Section *s, unsigned int nb_buckets) · 298 unmodified lines |
| 299 | strtab = s->link->data; | 299 | strtab = s->link->data; |
| 300 | nb_syms = s->data_offset / sizeof(ElfW(Sym)); | 300 | nb_syms = s->data_offset / sizeof(ElfW(Sym)); |
| 301 | | 301 | |
| | 302 | if (!nb_buckets) |
| | 303 | nb_buckets = ((int*)s->hash->data)[0]; |
| | 304 | |
| 302 | s->hash->data_offset = 0; | 305 | s->hash->data_offset = 0; |
| 303 | ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int)); | 306 | ptr = section_ptr_add(s->hash, (2 + nb_buckets + nb_syms) * sizeof(int)); |
| 304 | ptr[0] = nb_buckets; | 307 | ptr[0] = nb_buckets; |
| @@ -370,9 +373,7 @@ ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, · 65 unmodified lines |
| 370 | return sym_index; | 373 | return sym_index; |
| 371 | } | 374 | } |
| 372 | | 375 | |
| 373 | /* find global ELF symbol 'name' and return its index. Return 0 if not | 376 | static int find_elf_sym_1(Section *s, const char *name, int onlydef) |
| 374 | found. */ | | |
| 375 | ST_FUNC int find_elf_sym(Section *s, const char *name) | | |
| 376 | { | 377 | { |
| 377 | ElfW(Sym) *sym; | 378 | ElfW(Sym) *sym; |
| 378 | Section *hs; | 379 | Section *hs; |
| @@ -388,13 +389,21 @@ ST_FUNC int find_elf_sym(Section *s, const char *name) · 9 unmodified lines |
| 388 | while (sym_index != 0) { | 389 | while (sym_index != 0) { |
| 389 | sym = &((ElfW(Sym) *)s->data)[sym_index]; | 390 | sym = &((ElfW(Sym) *)s->data)[sym_index]; |
| 390 | name1 = (char *) s->link->data + sym->st_name; | 391 | name1 = (char *) s->link->data + sym->st_name; |
| 391 | if (!strcmp(name, name1) && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) | 392 | if (!strcmp(name, name1) && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL |
| | 393 | && (!onlydef || sym->st_shndx != SHN_UNDEF)) |
| 392 | return sym_index; | 394 | return sym_index; |
| 393 | sym_index = ((int *)hs->data)[2 + nbuckets + sym_index]; | 395 | sym_index = ((int *)hs->data)[2 + nbuckets + sym_index]; |
| 394 | } | 396 | } |
| 395 | return 0; | 397 | return 0; |
| 396 | } | 398 | } |
| 397 | | 399 | |
| | 400 | /* find global ELF symbol 'name' and return its index. Return 0 if not |
| | 401 | found. */ |
| | 402 | ST_FUNC int find_elf_sym(Section *s, const char *name) |
| | 403 | { |
| | 404 | return find_elf_sym_1(s, name, 0); |
| | 405 | } |
| | 406 | |
| 398 | /* return elf symbol value, signal error if 'err' is nonzero */ | 407 | /* return elf symbol value, signal error if 'err' is nonzero */ |
| 399 | ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err) | 408 | ST_FUNC addr_t get_elf_sym_addr(TCCState *s, const char *name, int err) |
| 400 | { | 409 | { |
| @@ -716,21 +725,6 @@ static void sort_syms(TCCState *s1, Section *s) · 315 unmodified lines |
| 716 | tcc_free(old_to_new_syms); | 725 | tcc_free(old_to_new_syms); |
| 717 | } | 726 | } |
| 718 | | 727 | |
| 719 | /* relocate common symbols in the .bss section */ | | |
| 720 | ST_FUNC void relocate_common_syms(void) | | |
| 721 | { | | |
| 722 | ElfW(Sym) *sym; | | |
| 723 | | | |
| 724 | for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { | | |
| 725 | if (sym->st_shndx == SHN_COMMON) { | | |
| 726 | /* symbol alignment is in st_value for SHN_COMMONs */ | | |
| 727 | sym->st_value = section_add(bss_section, sym->st_size, | | |
| 728 | sym->st_value); | | |
| 729 | sym->st_shndx = bss_section->sh_num; | | |
| 730 | } | | |
| 731 | } | | |
| 732 | } | | |
| 733 | | | |
| 734 | /* relocate symbol table, resolve undefined symbols if do_resolve is | 728 | /* relocate symbol table, resolve undefined symbols if do_resolve is |
| 735 | true and output error if undefined symbol. */ | 729 | true and output error if undefined symbol. */ |
| 736 | ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve) | 730 | ST_FUNC void relocate_syms(TCCState *s1, Section *symtab, int do_resolve) |
| @@ -1167,7 +1161,7 @@ ST_FUNC void tcc_add_runtime(TCCState *s1) · 430 unmodified lines |
| 1167 | /* add various standard linker symbols (must be done after the | 1161 | /* add various standard linker symbols (must be done after the |
| 1168 | sections are filled (for example after allocating common | 1162 | sections are filled (for example after allocating common |
| 1169 | symbols)) */ | 1163 | symbols)) */ |
| 1170 | ST_FUNC void tcc_add_linker_symbols(TCCState *s1) | 1164 | static void tcc_add_linker_symbols(TCCState *s1) |
| 1171 | { | 1165 | { |
| 1172 | char buf[1024]; | 1166 | char buf[1024]; |
| 1173 | int i; | 1167 | int i; |
| @@ -1226,6 +1220,47 @@ ST_FUNC void tcc_add_linker_symbols(TCCState *s1) · 52 unmodified lines |
| 1226 | } | 1220 | } |
| 1227 | } | 1221 | } |
| 1228 | | 1222 | |
| | 1223 | /* Do final regular symbol preparation (for those coming from .c/.o/.s files, |
| | 1224 | not from shared libs) */ |
| | 1225 | ST_FUNC void resolve_regular_syms(void) |
| | 1226 | { |
| | 1227 | int rebuild = 0; |
| | 1228 | ElfW(Sym) *sym; |
| | 1229 | |
| | 1230 | /* Allocate common symbols in BSS. */ |
| | 1231 | for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { |
| | 1232 | if (sym->st_shndx == SHN_COMMON) { |
| | 1233 | /* symbol alignment is in st_value for SHN_COMMONs */ |
| | 1234 | sym->st_value = section_add(bss_section, sym->st_size, |
| | 1235 | sym->st_value); |
| | 1236 | sym->st_shndx = bss_section->sh_num; |
| | 1237 | } |
| | 1238 | } |
| | 1239 | |
| | 1240 | /* Now assign linker provided symbols their value. */ |
| | 1241 | tcc_add_linker_symbols(tcc_state); |
| | 1242 | |
| | 1243 | /* And finally resolve still UNDEF symbols (for multi-file mode), |
| | 1244 | and globalize those that are still UNDEF. */ |
| | 1245 | rebuild_hash(symtab_section, 0); |
| | 1246 | for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { |
| | 1247 | if (sym->st_shndx == SHN_UNDEF) { |
| | 1248 | const char *name = (char *) symtab_section->link->data + sym->st_name; |
| | 1249 | int symndx = find_elf_sym_1(symtab_section, name, 1); |
| | 1250 | if (symndx) { |
| | 1251 | *sym = ((ElfSym *)symtab_section->data)[symndx]; |
| | 1252 | rebuild = 1; |
| | 1253 | } else if (ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) { |
| | 1254 | sym->st_info |
| | 1255 | = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info)); |
| | 1256 | rebuild = 1; |
| | 1257 | } |
| | 1258 | } |
| | 1259 | } |
| | 1260 | if (rebuild) |
| | 1261 | rebuild_hash(symtab_section, 0); |
| | 1262 | } |
| | 1263 | |
| 1229 | static void tcc_output_binary(TCCState *s1, FILE *f, | 1264 | static void tcc_output_binary(TCCState *s1, FILE *f, |
| 1230 | const int *sec_order) | 1265 | const int *sec_order) |
| 1231 | { | 1266 | { |
| @@ -2016,8 +2051,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 784 unmodified lines |
| 2016 | if (file_type != TCC_OUTPUT_OBJ) { | 2051 | if (file_type != TCC_OUTPUT_OBJ) { |
| 2017 | /* if linking, also link in runtime libraries (libc, libgcc, etc.) */ | 2052 | /* if linking, also link in runtime libraries (libc, libgcc, etc.) */ |
| 2018 | tcc_add_runtime(s1); | 2053 | tcc_add_runtime(s1); |
| 2019 | relocate_common_syms(); | 2054 | resolve_regular_syms(); |
| 2020 | tcc_add_linker_symbols(s1); | | |
| 2021 | | 2055 | |
| 2022 | if (!s1->static_link) { | 2056 | if (!s1->static_link) { |
| 2023 | if (file_type == TCC_OUTPUT_EXE) { | 2057 | if (file_type == TCC_OUTPUT_EXE) { |
| @@ -2058,6 +2092,14 @@ static int elf_output_file(TCCState *s1, const char *filename) · 34 unmodified lines |
| 2058 | } | 2092 | } |
| 2059 | } | 2093 | } |
| 2060 | build_got_entries(s1); | 2094 | build_got_entries(s1); |
| | 2095 | } else { |
| | 2096 | for_each_elem(symtab_section, 1, sym, ElfW(Sym)) { |
| | 2097 | if (sym->st_shndx == SHN_UNDEF |
| | 2098 | && ELFW(ST_BIND)(sym->st_info) == STB_LOCAL) { |
| | 2099 | sym->st_info |
| | 2100 | = ELFW(ST_INFO)(STB_GLOBAL, ELFW(ST_TYPE)(sym->st_info)); |
| | 2101 | } |
| | 2102 | } |
| 2061 | } | 2103 | } |
| 2062 | | 2104 | |
| 2063 | /* we add a section for symbols */ | 2105 | /* we add a section for symbols */ |