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.
Unified · Split
| @@ -1510,12 +1510,32 @@ static int elf_output_file(TCCState *s1, const char *filename) · 1509 unmodified lines | ||
| 1510 | 1510 | sym - (ElfW(Sym) *)symtab_section->data); |
| 1511 | 1511 | } else if (type == STT_OBJECT) { |
| 1512 | 1512 | unsigned long offset; |
| 1513 | + ElfW(Sym) *dynsym, *dynsym_end; | |
| 1513 | 1514 | offset = bss_section->data_offset; |
| 1514 | 1515 | /* XXX: which alignment ? */ |
| 1515 | 1516 | offset = (offset + 16 - 1) & -16; |
| 1516 | 1517 | index = put_elf_sym(s1->dynsym, offset, esym->st_size, |
| 1517 | 1518 | esym->st_info, 0, |
| 1518 | 1519 | bss_section->sh_num, name); |
| 1520 | + /* Ensure symbol aliases (that is, symbols with | |
| 1521 | + the same st_value) resolve to the same | |
| 1522 | + address in program .bss or .data section. */ | |
| 1523 | + dynsym_end = (ElfW(Sym) *) | |
| 1524 | + (s1->dynsymtab_section->data + | |
| 1525 | + s1->dynsymtab_section->data_offset); | |
| 1526 | + for(dynsym = (ElfW(Sym) *)s1->dynsymtab_section->data + 1; | |
| 1527 | + dynsym < dynsym_end; dynsym++) { | |
| 1528 | + if (dynsym->st_value == esym->st_value) { | |
| 1529 | + char *dynname; | |
| 1530 | + dynname = s1->dynsymtab_section->link->data | |
| 1531 | + + dynsym->st_name; | |
| 1532 | + put_elf_sym(s1->dynsym, offset, | |
| 1533 | + dynsym->st_size, | |
| 1534 | + dynsym->st_info, 0, | |
| 1535 | + bss_section->sh_num, | |
| 1536 | + dynname); | |
| 1537 | + } | |
| 1538 | + } | |
| 1519 | 1539 | put_elf_reloc(s1->dynsym, bss_section, |
| 1520 | 1540 | offset, R_COPY, index); |
| 1521 | 1541 | offset += esym->st_size; |