Fix problem with PLT and GOT relocs on armel.

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.
master
Daniel Glöckner 2010-06-23 00:20:32 +02:00 committed by Thomas Preud'homme
parent bf374a5f23
commit ab7ed48ee8
1 changed files with 12 additions and 3 deletions

View File

@ -1356,6 +1356,17 @@ void patch_dynsym_undef(TCCState *s1, Section *s)
#else
#define HAVE_PHDR 0
#define EXTRA_RELITEMS 9
/* zero plt offsets of weak symbols in .dynsym */
void patch_dynsym_undef(TCCState *s1, Section *s)
{
ElfW(Sym) *sym, *sym_end;
sym_end = (ElfW(Sym) *)(s->data + s->data_offset);
for (sym = (ElfW(Sym) *)s->data + 1; sym < sym_end; sym++)
if (sym->st_shndx == SHN_UNDEF && ELFW(ST_BIND)(sym->st_info) == STB_WEAK)
sym->st_value = 0;
}
#endif
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)
type = ELFW(ST_TYPE)(esym->st_info);
if ((type == STT_FUNC) || (type == STT_GNU_IFUNC)) {
put_got_entry(s1, R_JMP_SLOT, esym->st_size,
esym->st_info,
ELFW(ST_INFO)(STB_GLOBAL,type),
sym - (ElfW(Sym) *)symtab_section->data);
} else if (type == STT_OBJECT) {
unsigned long offset;
@ -2125,10 +2136,8 @@ static int elf_output_file(TCCState *s1, const char *filename)
for(i=1;i<s1->nb_sections;i++) {
s = s1->sections[section_order[i]];
if (s->sh_type != SHT_NOBITS) {
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
if (s->sh_type == SHT_DYNSYM)
patch_dynsym_undef(s1, s);
#endif
while (offset < s->sh_offset) {
fputc(0, f);
offset++;