diff options
-rw-r--r-- | libexec/rtld-elf/sparc64/reloc.c | 3 | ||||
-rw-r--r-- | sys/sparc64/sparc64/elf_machdep.c | 12 |
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; |