aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMarius Strobl <marius@FreeBSD.org>2011-03-06 15:20:11 +0000
committerMarius Strobl <marius@FreeBSD.org>2011-03-06 15:20:11 +0000
commit25b31a949680f1f6ad0965a8f514815e7c9ff7fb (patch)
tree5ae03a572be72e3fd0d851acb0f567c8119d6b93 /sys
parentd374d11285a46eb5d9d7666da4a89d12be630d37 (diff)
downloadsrc-25b31a949680f1f6ad0965a8f514815e7c9ff7fb.tar.gz
src-25b31a949680f1f6ad0965a8f514815e7c9ff7fb.zip
- 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.
Notes
Notes: svn path=/head/; revision=219340
Diffstat (limited to 'sys')
-rw-r--r--sys/sparc64/sparc64/elf_machdep.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/sys/sparc64/sparc64/elf_machdep.c b/sys/sparc64/sparc64/elf_machdep.c
index a1c14ee2623c..2e58c8c3ed83 100644
--- a/sys/sparc64/sparc64/elf_machdep.c
+++ b/sys/sparc64/sparc64/elf_machdep.c
@@ -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;