TinyCC fails to link correctly to libraries when both R_ARM_PLT32 and R_ARM_GOT32 relocation to a same symbol exist (see http://lists.nongnu.org/archive/html/tinycc-devel/2010-05/msg00032.html for more details). The patch marks all undefined weak symbols found in external libraries as strong. The value of all remaining weak symbols is set to zero just before the section is output. Note by Thomas Preud'homme: it's been 2 months in Debian without any new bug report, hence commiting.
Unified · Split
| @@ -1356,6 +1356,17 @@ void patch_dynsym_undef(TCCState *s1, Section *s) · 1355 unmodified lines | |||
| 1356 | #else | 1356 | #else |
| 1357 | #define HAVE_PHDR 0 | 1357 | #define HAVE_PHDR 0 |
| 1358 | #define EXTRA_RELITEMS 9 | 1358 | #define EXTRA_RELITEMS 9 |
| 1359 | |||
| 1360 | /* zero plt offsets of weak symbols in .dynsym */ | ||
| 1361 | void patch_dynsym_undef(TCCState *s1, Section *s) | ||
| 1362 | { | ||
| 1363 | ElfW(Sym) *sym, *sym_end; | ||
| 1364 | |||
| 1365 | sym_end = (ElfW(Sym) *)(s->data + s->data_offset); | ||
| 1366 | for (sym = (ElfW(Sym) *)s->data + 1; sym < sym_end; sym++) | ||
| 1367 | if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK) | ||
| 1368 | sym->st_value = 0; | ||
| 1369 | } | ||
| 1359 | #endif | 1370 | #endif |
| 1360 | 1371 | ||
| 1361 | ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel) | 1372 | ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel) |
| @@ -1499,7 +1510,7 @@ static int elf_output_file(TCCState *s1, const char *filename) · 137 unmodified lines | |||
| 1499 | type = ELFW(ST_TYPE)(esym->st_info); | 1510 | type = ELFW(ST_TYPE)(esym->st_info); |
| 1500 | if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) { | 1511 | if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) { |
| 1501 | put_got_entry(s1, R_JMP_SLOT, esym->st_size, | 1512 | put_got_entry(s1, R_JMP_SLOT, esym->st_size, |
| 1502 | esym->st_info, | 1513 | ELFW(ST_INFO)(STB_GLOBAL,type), |
| 1503 | sym - (ElfW(Sym) *)symtab_section->data); | 1514 | sym - (ElfW(Sym) *)symtab_section->data); |
| 1504 | } else if (type == STT_OBJECT) { | 1515 | } else if (type == STT_OBJECT) { |
| 1505 | unsigned long offset; | 1516 | unsigned long offset; |
| @@ -2125,10 +2136,8 @@ static int elf_output_file(TCCState *s1, const char *filename) · 619 unmodified lines | |||
| 2125 | for(i=1;i<s1->nb_sections;i++) { | 2136 | for(i=1;i<s1->nb_sections;i++) { |
| 2126 | s = s1->sections[section_order[i]]; | 2137 | s = s1->sections[section_order[i]]; |
| 2127 | if (s->sh_type != SHT_NOBITS) { | 2138 | if (s->sh_type != SHT_NOBITS) { |
| 2128 | #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) | ||
| 2129 | if (s->sh_type == SHT_DYNSYM) | 2139 | if (s->sh_type == SHT_DYNSYM) |
| 2130 | patch_dynsym_undef(s1, s); | 2140 | patch_dynsym_undef(s1, s); |
| 2131 | #endif | ||
| 2132 | while (offset < s->sh_offset) { | 2141 | while (offset < s->sh_offset) { |
| 2133 | fputc(0, f); | 2142 | fputc(0, f); |
| 2134 | offset++; | 2143 | offset++; |