summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libexec/rtld-elf/sparc64/reloc.c3
-rw-r--r--sys/sparc64/sparc64/elf_machdep.c12
2 files changed, 14 insertions, 1 deletions
diff --git a/libexec/rtld-elf/sparc64/reloc.c b/libexec/rtld-elf/sparc64/reloc.c
index 6249fb0..b58e3e5 100644
--- a/libexec/rtld-elf/sparc64/reloc.c
+++ b/libexec/rtld-elf/sparc64/reloc.c
@@ -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;
diff --git a/sys/sparc64/sparc64/elf_machdep.c b/sys/sparc64/sparc64/elf_machdep.c
index a1c14ee..2e58c8c 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;
OpenPOWER on IntegriCloud