diff options
| author | Thomas Preud'homme <thomas.preudhomme@celest.fr> | 2010-04-26 00:46:39 +0200 |
|---|---|---|
| committer | Thomas Preud'homme <thomas.preudhomme@celest.fr> | 2010-05-01 16:45:36 +0200 |
| commit | a28b18fa16edaeb6bc7d34cf1ddac690b27ba610 (patch) | |
| tree | 909b72cbe83ba6cc163d38afbba2c1f063d91810 /tccelf.c | |
| parent | 036ff17916586febc968b964ee416e1d4d1da70f (diff) | |
| download | tinycc-a28b18fa16edaeb6bc7d34cf1ddac690b27ba610.tar.gz tinycc-a28b18fa16edaeb6bc7d34cf1ddac690b27ba610.tar.bz2 | |
Link alias symbols together
Make sure alias symbols resolve to the same address in program .bss or .data
section. This ensure for example that if a program reference environ (via an
extern char **environ declaration) and the libc change its value via the
__environ alias after the R_ARCH_COPY relocation have been performed, then
the program will see the new value.
Diffstat (limited to 'tccelf.c')
| -rw-r--r-- | tccelf.c | 20 |
1 files changed, 20 insertions, 0 deletions
@@ -1510,12 +1510,32 @@ static int elf_output_file(TCCState *s1, const char *filename) sym - (ElfW(Sym) *)symtab_section->data); } else if (type == STT_OBJECT) { unsigned long offset; + ElfW(Sym) *dynsym, *dynsym_end; offset = bss_section->data_offset; /* XXX: which alignment ? */ offset = (offset + 16 - 1) & -16; 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); + } + } put_elf_reloc(s1->dynsym, bss_section, offset, R_COPY, index); offset += esym->st_size; |
