Changeset View
Changeset View
Standalone View
Standalone View
head/libexec/rtld-elf/mips/reloc.c
Show First 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | |||||
#include "rtld.h" | #include "rtld.h" | ||||
#ifdef __mips_n64 | #ifdef __mips_n64 | ||||
#define GOT1_MASK 0x8000000000000000UL | #define GOT1_MASK 0x8000000000000000UL | ||||
#else | #else | ||||
#define GOT1_MASK 0x80000000UL | #define GOT1_MASK 0x80000000UL | ||||
#endif | #endif | ||||
/* | |||||
* Determine if the second GOT entry is reserved for rtld or if it is | |||||
* the first "real" GOT entry. | |||||
* | |||||
* This must be a macro rather than a function so that | |||||
* _rtld_relocate_nonplt_self doesn't trigger a GOT invocation trying | |||||
* to use it before the local GOT entries in rtld are adjusted. | |||||
*/ | |||||
#ifdef __mips_n64 | |||||
/* Old binutils uses the 32-bit GOT1 mask value for N64. */ | |||||
#define GOT1_RESERVED_FOR_RTLD(got) \ | |||||
(((got)[1] == 0x80000000) || (got)[1] & GOT1_MASK) | |||||
#else | |||||
#define GOT1_RESERVED_FOR_RTLD(got) ((got)[1] & GOT1_MASK) | |||||
#endif | |||||
void | void | ||||
init_pltgot(Obj_Entry *obj) | init_pltgot(Obj_Entry *obj) | ||||
{ | { | ||||
if (obj->pltgot != NULL) { | if (obj->pltgot != NULL) { | ||||
obj->pltgot[0] = (Elf_Addr) &_rtld_bind_start; | obj->pltgot[0] = (Elf_Addr) &_rtld_bind_start; | ||||
if (obj->pltgot[1] & 0x80000000) | if (GOT1_RESERVED_FOR_RTLD(obj->pltgot)) | ||||
obj->pltgot[1] = (Elf_Addr) obj | GOT1_MASK; | obj->pltgot[1] = (Elf_Addr) obj | GOT1_MASK; | ||||
} | } | ||||
} | } | ||||
int | int | ||||
do_copy_relocations(Obj_Entry *dstobj) | do_copy_relocations(Obj_Entry *dstobj) | ||||
{ | { | ||||
/* Do nothing */ | /* Do nothing */ | ||||
▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | case DT_MIPS_SYMTABNO: | ||||
symtabno = dynp->d_un.d_val; | symtabno = dynp->d_un.d_val; | ||||
break; | break; | ||||
case DT_MIPS_GOTSYM: | case DT_MIPS_GOTSYM: | ||||
gotsym = dynp->d_un.d_val; | gotsym = dynp->d_un.d_val; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
i = (got[1] & GOT1_MASK) ? 2 : 1; | i = GOT1_RESERVED_FOR_RTLD(got) ? 2 : 1; | ||||
/* Relocate the local GOT entries */ | /* Relocate the local GOT entries */ | ||||
got += i; | got += i; | ||||
for (; i < local_gotno; i++) { | for (; i < local_gotno; i++) { | ||||
*got++ += relocbase; | *got++ += relocbase; | ||||
} | } | ||||
sym = symtab + gotsym; | sym = symtab + gotsym; | ||||
/* Now do the global GOT entries */ | /* Now do the global GOT entries */ | ||||
▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | #ifdef SUPPORT_OLD_BROKEN_LD | ||||
broken = 0; | broken = 0; | ||||
sym = obj->symtab; | sym = obj->symtab; | ||||
for (i = 1; i < 12; i++) | for (i = 1; i < 12; i++) | ||||
if (sym[i].st_info == ELF_ST_INFO(STB_LOCAL, STT_NOTYPE)) | if (sym[i].st_info == ELF_ST_INFO(STB_LOCAL, STT_NOTYPE)) | ||||
broken = 1; | broken = 1; | ||||
dbg("%s: broken=%d", obj->path, broken); | dbg("%s: broken=%d", obj->path, broken); | ||||
#endif | #endif | ||||
i = (got[1] & GOT1_MASK) ? 2 : 1; | i = GOT1_RESERVED_FOR_RTLD(got) ? 2 : 1; | ||||
/* Relocate the local GOT entries */ | /* Relocate the local GOT entries */ | ||||
got += i; | got += i; | ||||
dbg("got:%p for %d entries adding %p", | dbg("got:%p for %d entries adding %p", | ||||
got, obj->local_gotno, obj->relocbase); | got, obj->local_gotno, obj->relocbase); | ||||
for (; i < obj->local_gotno; i++) { | for (; i < obj->local_gotno; i++) { | ||||
*got += (Elf_Addr)obj->relocbase; | *got += (Elf_Addr)obj->relocbase; | ||||
got++; | got++; | ||||
▲ Show 20 Lines • Show All 408 Lines • Show Last 20 Lines |