64 bit support for MIPS rtld.
- Handle the case where pltgot[1] is 64 bit. - use 'ifdef __mips_n64' instead of 'ELFSIZE == 64' to detect 64 bit compile.
This commit is contained in:
parent
3d3063c0b3
commit
4c4a1ce8f8
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=210629
@ -41,13 +41,19 @@ __FBSDID("$FreeBSD$");
|
||||
#include "debug.h"
|
||||
#include "rtld.h"
|
||||
|
||||
#ifdef __mips_n64
|
||||
#define GOT1_MASK 0x8000000000000000UL
|
||||
#else
|
||||
#define GOT1_MASK 0x80000000UL
|
||||
#endif
|
||||
|
||||
void
|
||||
init_pltgot(Obj_Entry *obj)
|
||||
{
|
||||
if (obj->pltgot != NULL) {
|
||||
obj->pltgot[0] = (Elf_Addr) &_rtld_bind_start;
|
||||
/* XXX only if obj->pltgot[1] & 0x80000000 ?? */
|
||||
obj->pltgot[1] |= (Elf_Addr) obj;
|
||||
if (obj->pltgot[1] & 0x80000000)
|
||||
obj->pltgot[1] = (Elf_Addr) obj | GOT1_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
@ -64,7 +70,7 @@ void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);
|
||||
* It is possible for the compiler to emit relocations for unaligned data.
|
||||
* We handle this situation with these inlines.
|
||||
*/
|
||||
#if ELFSIZE == 64
|
||||
#ifdef __mips_n64
|
||||
/*
|
||||
* ELF64 MIPS encodes the relocs uniquely. The first 32-bits of info contain
|
||||
* the symbol index. The top 32-bits contain three relocation types encoded
|
||||
@ -90,7 +96,7 @@ load_ptr(void *where, size_t len)
|
||||
Elf_Sxword val;
|
||||
|
||||
if (__predict_true(((uintptr_t)where & (len - 1)) == 0)) {
|
||||
#if ELFSIZE == 64
|
||||
#ifdef __mips_n64
|
||||
if (len == sizeof(Elf_Sxword))
|
||||
return *(Elf_Sxword *)where;
|
||||
#endif
|
||||
@ -111,7 +117,7 @@ static __inline void
|
||||
store_ptr(void *where, Elf_Sxword val, size_t len)
|
||||
{
|
||||
if (__predict_true(((uintptr_t)where & (len - 1)) == 0)) {
|
||||
#if ELFSIZE == 64
|
||||
#ifdef __mips_n64
|
||||
if (len == sizeof(Elf_Sxword)) {
|
||||
*(Elf_Sxword *)where = val;
|
||||
return;
|
||||
@ -165,7 +171,7 @@ _rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
|
||||
}
|
||||
}
|
||||
|
||||
i = (got[1] & 0x80000000) ? 2 : 1;
|
||||
i = (got[1] & GOT1_MASK) ? 2 : 1;
|
||||
/* Relocate the local GOT entries */
|
||||
got += i;
|
||||
for (; i < local_gotno; i++) {
|
||||
@ -197,7 +203,7 @@ _rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
|
||||
: sizeof(Elf_Sword);
|
||||
Elf_Sxword old = load_ptr(where, rlen);
|
||||
Elf_Sxword val = old;
|
||||
#if ELFSIZE == 64
|
||||
#ifdef __mips_n64
|
||||
assert(r_type == R_TYPE(REL32)
|
||||
|| r_type == (R_TYPE(REL32)|(R_TYPE(64) << 8)));
|
||||
#endif
|
||||
@ -272,7 +278,7 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
|
||||
dbg("%s: broken=%d", obj->path, broken);
|
||||
#endif
|
||||
|
||||
i = (got[1] & 0x80000000) ? 2 : 1;
|
||||
i = (got[1] & GOT1_MASK) ? 2 : 1;
|
||||
|
||||
/* Relocate the local GOT entries */
|
||||
got += i;
|
||||
|
@ -130,11 +130,12 @@ _rtld_bind_start:
|
||||
/* .got = $gp - 0x7ff0 */
|
||||
/* Simple math as you can see. */
|
||||
#if defined(__mips_n64)
|
||||
ld a0, 8(a0) /* object = pltgot[1] & 0x7fffffff */
|
||||
ld a0, 8(a0) /* object = pltgot[1] */
|
||||
and a0, a0, 0x7fffffffffffffff
|
||||
#else
|
||||
lw a0, 4(a0) /* object = pltgot[1] & 0x7fffffff */
|
||||
#endif
|
||||
and a0, a0, 0x7fffffff
|
||||
#endif
|
||||
move a1, t8 /* symbol index */
|
||||
|
||||
PTR_LA t9, _C_LABEL(_mips_rtld_bind)
|
||||
|
Loading…
Reference in New Issue
Block a user