Do not create a new symbol in add_elf_sym if a symbol with same properties (value, size, info, etc.) already exists. This prevents symbols from being exported twice in the dynamic symbol table.
Unified · Split
| @@ -394,12 +394,17 @@ ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size, · 393 unmodified lines | |||
| 394 | sym_type = ELFW(ST_TYPE)(info); | 394 | sym_type = ELFW(ST_TYPE)(info); |
| 395 | sym_vis = ELFW(ST_VISIBILITY)(other); | 395 | sym_vis = ELFW(ST_VISIBILITY)(other); |
| 396 | 396 | ||
| 397 | sym_index = find_elf_sym(s, name); | ||
| 398 | esym = &((ElfW(Sym) *)s->data)[sym_index]; | ||
| 399 | if (sym_index && esym->st_value == value && esym->st_size == size | ||
| 400 | && esym->st_info == info && esym->st_other == other | ||
| 401 | && esym->st_shndx == sh_num) | ||
| 402 | return sym_index; | ||
| 403 | |||
| 397 | if (sym_bind != STB_LOCAL) { | 404 | if (sym_bind != STB_LOCAL) { |
| 398 | /* we search global or weak symbols */ | 405 | /* we search global or weak symbols */ |
| 399 | sym_index = find_elf_sym(s, name); | ||
| 400 | if (!sym_index) | 406 | if (!sym_index) |
| 401 | goto do_def; | 407 | goto do_def; |
| 402 | esym = &((ElfW(Sym) *)s->data)[sym_index]; | ||
| 403 | if (esym->st_shndx != SHN_UNDEF) { | 408 | if (esym->st_shndx != SHN_UNDEF) { |
| 404 | esym_bind = ELFW(ST_BIND)(esym->st_info); | 409 | esym_bind = ELFW(ST_BIND)(esym->st_info); |
| 405 | /* propagate the most constraining visibility */ | 410 | /* propagate the most constraining visibility */ |
| @@ -2058,7 +2063,7 @@ static void bind_exe_dynsyms(TCCState *s1) · 1652 unmodified lines | |||
| 2058 | } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { | 2063 | } else if (s1->rdynamic && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) { |
| 2059 | /* if -rdynamic option, then export all non local symbols */ | 2064 | /* if -rdynamic option, then export all non local symbols */ |
| 2060 | name = (char *) symtab_section->link->data + sym->st_name; | 2065 | name = (char *) symtab_section->link->data + sym->st_name; |
| 2061 | put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info, | 2066 | add_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info, |
| 2062 | 0, sym->st_shndx, name); | 2067 | 0, sym->st_shndx, name); |
| 2063 | } | 2068 | } |
| 2064 | } | 2069 | } |
| @@ -2081,7 +2086,7 @@ static void bind_libs_dynsyms(TCCState *s1) · 16 unmodified lines | |||
| 2081 | -rdynamic ? */ | 2086 | -rdynamic ? */ |
| 2082 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; | 2087 | sym = &((ElfW(Sym) *)symtab_section->data)[sym_index]; |
| 2083 | if (sym_index && sym->st_shndx != SHN_UNDEF) | 2088 | if (sym_index && sym->st_shndx != SHN_UNDEF) |
| 2084 | put_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info, | 2089 | add_elf_sym(s1->dynsym, sym->st_value, sym->st_size, sym->st_info, |
| 2085 | 0, sym->st_shndx, name); | 2090 | 0, sym->st_shndx, name); |
| 2086 | else if (esym->st_shndx == SHN_UNDEF) { | 2091 | else if (esym->st_shndx == SHN_UNDEF) { |
| 2087 | /* weak symbols can stay undefined */ | 2092 | /* weak symbols can stay undefined */ |