diff options
author | Jayachandran C. <jchandra@FreeBSD.org> | 2010-07-29 20:18:52 +0000 |
---|---|---|
committer | Jayachandran C. <jchandra@FreeBSD.org> | 2010-07-29 20:18:52 +0000 |
commit | 4c4a1ce8f8c43bc1e996fe67baf0483a0eeef138 (patch) | |
tree | 3ca90817280644a30a1614b467cd765206ba97ec /libexec | |
parent | 3d3063c0b3ef4b82e06f662ff4fd717b123e5218 (diff) | |
download | src-4c4a1ce8f8c43bc1e996fe67baf0483a0eeef138.tar.gz src-4c4a1ce8f8c43bc1e996fe67baf0483a0eeef138.zip |
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.
Notes
Notes:
svn path=/head/; revision=210629
Diffstat (limited to 'libexec')
-rw-r--r-- | libexec/rtld-elf/mips/reloc.c | 22 | ||||
-rw-r--r-- | libexec/rtld-elf/mips/rtld_start.S | 5 |
2 files changed, 17 insertions, 10 deletions
diff --git a/libexec/rtld-elf/mips/reloc.c b/libexec/rtld-elf/mips/reloc.c index b58e3fe00cd3..fa0534d2180b 100644 --- a/libexec/rtld-elf/mips/reloc.c +++ b/libexec/rtld-elf/mips/reloc.c @@ -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; diff --git a/libexec/rtld-elf/mips/rtld_start.S b/libexec/rtld-elf/mips/rtld_start.S index 630e5e5734cc..354db13eee5b 100644 --- a/libexec/rtld-elf/mips/rtld_start.S +++ b/libexec/rtld-elf/mips/rtld_start.S @@ -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) |