Changeset View
Changeset View
Standalone View
Standalone View
libexec/rtld-elf/powerpc/reloc.c
Show First 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | |||||
#define min(a,b) (((a) < (b)) ? (a) : (b)) | #define min(a,b) (((a) < (b)) ? (a) : (b)) | ||||
#define max(a,b) (((a) > (b)) ? (a) : (b)) | #define max(a,b) (((a) > (b)) ? (a) : (b)) | ||||
#define PLT_EXTENDED_BEGIN (1 << 13) | #define PLT_EXTENDED_BEGIN (1 << 13) | ||||
#define JMPTAB_BASE(N) (18 + N*2 + ((N > PLT_EXTENDED_BEGIN) ? \ | #define JMPTAB_BASE(N) (18 + N*2 + ((N > PLT_EXTENDED_BEGIN) ? \ | ||||
(N - PLT_EXTENDED_BEGIN)*2 : 0)) | (N - PLT_EXTENDED_BEGIN)*2 : 0)) | ||||
void _rtld_bind_secureplt_start(void); | |||||
/* | /* | ||||
* Process the R_PPC_COPY relocations | * Process the R_PPC_COPY relocations | ||||
*/ | */ | ||||
int | int | ||||
do_copy_relocations(Obj_Entry *dstobj) | do_copy_relocations(Obj_Entry *dstobj) | ||||
{ | { | ||||
const Elf_Rela *relalim; | const Elf_Rela *relalim; | ||||
const Elf_Rela *rela; | const Elf_Rela *rela; | ||||
▲ Show 20 Lines • Show All 288 Lines • ▼ Show 20 Lines | reloc_plt_object(Obj_Entry *obj, const Elf_Rela *rela) | ||||
int N = obj->pltrelasize / sizeof(Elf_Rela); | int N = obj->pltrelasize / sizeof(Elf_Rela); | ||||
int reloff; | int reloff; | ||||
reloff = rela - obj->pltrela; | reloff = rela - obj->pltrela; | ||||
if (reloff < 0) | if (reloff < 0) | ||||
return (-1); | return (-1); | ||||
if (obj->gotptr != NULL) { | |||||
*where += (Elf_Addr)obj->relocbase; | |||||
return (0); | |||||
} | |||||
pltlongresolve = obj->pltgot + 5; | pltlongresolve = obj->pltgot + 5; | ||||
pltresolve = pltlongresolve + 5; | pltresolve = pltlongresolve + 5; | ||||
distance = (Elf_Addr)pltresolve - (Elf_Addr)(where + 1); | distance = (Elf_Addr)pltresolve - (Elf_Addr)(where + 1); | ||||
dbg(" reloc_plt_object: where=%p,pltres=%p,reloff=%x,distance=%x", | dbg(" reloc_plt_object: where=%p,pltres=%p,reloff=%x,distance=%x", | ||||
(void *)where, (void *)pltresolve, reloff, distance); | (void *)where, (void *)pltresolve, reloff, distance); | ||||
▲ Show 20 Lines • Show All 124 Lines • ▼ Show 20 Lines | reloc_jmpslot(Elf_Addr *wherep, Elf_Addr target, | ||||
/* | /* | ||||
* At the PLT entry pointed at by `wherep', construct | * At the PLT entry pointed at by `wherep', construct | ||||
* a direct transfer to the now fully resolved function | * a direct transfer to the now fully resolved function | ||||
* address. | * address. | ||||
*/ | */ | ||||
offset = target - (Elf_Addr)wherep; | offset = target - (Elf_Addr)wherep; | ||||
if (obj->gotptr != NULL) { | |||||
assert(wherep >= (Elf_Word *)obj->pltgot); | |||||
assert(wherep < | |||||
(Elf_Word *)obj->pltgot + obj->pltrelasize); | |||||
*wherep = target; | |||||
goto out; | |||||
} | |||||
if (abs((int)offset) < 32*1024*1024) { /* inside 32MB? */ | if (abs((int)offset) < 32*1024*1024) { /* inside 32MB? */ | ||||
/* b value # branch directly */ | /* b value # branch directly */ | ||||
*wherep = 0x48000000 | (offset & 0x03fffffc); | *wherep = 0x48000000 | (offset & 0x03fffffc); | ||||
__syncicache(wherep, 4); | __syncicache(wherep, 4); | ||||
} else { | } else { | ||||
Elf_Addr *pltcall, *jmptab; | Elf_Addr *pltcall, *jmptab; | ||||
int distance; | int distance; | ||||
int N = obj->pltrelasize / sizeof(Elf_Rela); | int N = obj->pltrelasize / sizeof(Elf_Rela); | ||||
▲ Show 20 Lines • Show All 59 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
Elf_Word *pltcall, *pltresolve, *pltlongresolve; | Elf_Word *pltcall, *pltresolve, *pltlongresolve; | ||||
Elf_Word *jmptab; | Elf_Word *jmptab; | ||||
int N = obj->pltrelasize / sizeof(Elf_Rela); | int N = obj->pltrelasize / sizeof(Elf_Rela); | ||||
pltcall = obj->pltgot; | pltcall = obj->pltgot; | ||||
if (pltcall == NULL) { | if (pltcall == NULL) { | ||||
return; | |||||
} | |||||
/* Handle Secure-PLT first, if applicable. */ | |||||
if (obj->gotptr != NULL) { | |||||
obj->gotptr[1] = (Elf_Addr)_rtld_bind_secureplt_start; | |||||
obj->gotptr[2] = (Elf_Addr)obj; | |||||
dbg("obj %s secure-plt gotptr=%p start=%p obj=%p", | |||||
obj->path, obj->gotptr, | |||||
(void *)obj->gotptr[1], (void *)obj->gotptr[2]); | |||||
return; | return; | ||||
} | } | ||||
/* | /* | ||||
* From the SVR4 PPC ABI: | * From the SVR4 PPC ABI: | ||||
* | * | ||||
* 'The first 18 words (72 bytes) of the PLT are reserved for | * 'The first 18 words (72 bytes) of the PLT are reserved for | ||||
* use by the dynamic linker. | * use by the dynamic linker. | ||||
▲ Show 20 Lines • Show All 102 Lines • Show Last 20 Lines |