- With the addition of TLS support binutils started to make the addend

values for resolved symbols relative to relocbase instead of sections
  so detect this case and handle as appropriate, which allows using
  kernel modules linked with affected versions of binutils. Actually I
  think this is a bug in binutils but given that apparently nobody
  complained for nearly six years and powerpc has basically the same
  workaround I decided to put it in for the sparc64 kernel, too.
- Fix R_SPARC_HIX22 relocations. Apparently these are hardly ever used.
This commit is contained in:
Marius Strobl 2011-03-06 15:20:11 +00:00
parent d374d11285
commit 25b31a9496
2 changed files with 14 additions and 1 deletions

View File

@ -355,6 +355,9 @@ reloc_nonplt_object(Obj_Entry *obj, const Elf_Rela *rela, SymCache *cache,
if (type == R_SPARC_OLO10)
value = (value & 0x3ff) + ELF64_R_TYPE_DATA(rela->r_info);
if (type == R_SPARC_HIX22)
value ^= 0xffffffffffffffff;
if (RELOC_PC_RELATIVE(type))
value -= (Elf_Addr)where;

View File

@ -332,7 +332,14 @@ elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
addr = lookup(lf, symidx, 1);
if (addr == 0)
return (-1);
value += addr;
/*
* With the addition of TLS support binutils started to make
* addend values relative to relocbase instead of sections.
*/
if (addr > relocbase && addr <= relocbase + value)
value += relocbase;
else
value += addr;
if (RELOC_BARE_SYMBOL(rtype))
value = elf_relocaddr(lf, value);
}
@ -340,6 +347,9 @@ elf_reloc(linker_file_t lf, Elf_Addr relocbase, const void *data, int type,
if (rtype == R_SPARC_OLO10)
value = (value & 0x3ff) + ELF64_R_TYPE_DATA(rela->r_info);
if (rtype == R_SPARC_HIX22)
value ^= 0xffffffffffffffff;
if (RELOC_PC_RELATIVE(rtype))
value -= (Elf_Addr)where;