diff options
author | jchandra <jchandra@FreeBSD.org> | 2010-07-29 20:18:52 +0000 |
---|---|---|
committer | jchandra <jchandra@FreeBSD.org> | 2010-07-29 20:18:52 +0000 |
commit | a25f240d5cbd2d3f4bf9d6373bea1d8b02e5fd80 (patch) | |
tree | 3ca90817280644a30a1614b467cd765206ba97ec /libexec/rtld-elf/mips | |
parent | f97655c71d3a04cdaa9c9f7095274469365ed771 (diff) | |
download | FreeBSD-src-a25f240d5cbd2d3f4bf9d6373bea1d8b02e5fd80.zip FreeBSD-src-a25f240d5cbd2d3f4bf9d6373bea1d8b02e5fd80.tar.gz |
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.
Diffstat (limited to 'libexec/rtld-elf/mips')
-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 b58e3fe..fa0534d 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 630e5e5..354db13 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) |