diff options
| author | Thomas Preud'homme <thomas.preudhomme@celest.fr> | 2011-05-16 13:49:08 +0200 |
|---|---|---|
| committer | Thomas Preud'homme <thomas.preudhomme@celest.fr> | 2011-05-16 13:49:08 +0200 |
| commit | db9d5f0fa4dc65bbf869ee4f98f53eafbab6059f (patch) | |
| tree | 1b334e0822c2b22e13d1bdb9460746ce65281271 /tccelf.c | |
| parent | 921f002a6d2ac385aa38ec9f4ea6fdb35ea61819 (diff) | |
| download | tinycc-db9d5f0fa4dc65bbf869ee4f98f53eafbab6059f.tar.gz tinycc-db9d5f0fa4dc65bbf869ee4f98f53eafbab6059f.tar.bz2 | |
Improve weak aliases handling
* Include only the STB_GLOBAL alias symbol in .dynsym section
* Stop the loop when STB_GLOBAL symbol is found
* Reword / simplify comment
Diffstat (limited to 'tccelf.c')
| -rw-r--r-- | tccelf.c | 36 |
1 files changed, 19 insertions, 17 deletions
@@ -1544,23 +1544,25 @@ static int elf_output_file(TCCState *s1, const char *filename) index = put_elf_sym(s1->dynsym, offset, esym->st_size, esym->st_info, 0, bss_section->sh_num, name); - /* Ensure symbol aliases (that is, symbols with - the same st_value) resolve to the same - address in program .bss or .data section. */ - dynsym_end = (ElfW(Sym) *) - (s1->dynsymtab_section->data + - s1->dynsymtab_section->data_offset); - for(dynsym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1; - dynsym < dynsym_end; dynsym++) { - if (dynsym->st_value == esym->st_value) { - char *dynname; - dynname = s1->dynsymtab_section->link->data - + dynsym->st_name; - put_elf_sym(s1->dynsym, offset, - dynsym->st_size, - dynsym->st_info, 0, - bss_section->sh_num, - dynname); + // Ensure R_COPY works for weak symbol aliases + if (ELFW(ST_BIND)(esym->st_info) == STB_WEAK) { + dynsym_end = (ElfW(Sym) *) + (s1->dynsymtab_section->data + + s1->dynsymtab_section->data_offset); + for(dynsym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1; + dynsym < dynsym_end; dynsym++) { + if ((dynsym->st_value == esym->st_value) + && (ELFW(ST_BIND)(dynsym->st_info) == STB_GLOBAL)) { + char *dynname; + dynname = s1->dynsymtab_section->link->data + + dynsym->st_name; + put_elf_sym(s1->dynsym, offset, + dynsym->st_size, + dynsym->st_info, 0, + bss_section->sh_num, + dynname); + break; + } } } put_elf_reloc(s1->dynsym, bss_section, |
