Changeset View
Changeset View
Standalone View
Standalone View
libexec/rtld-elf/i386/reloc.c
Show First 20 Lines • Show All 257 Lines • ▼ Show 20 Lines | case R_386_TLS_TPOFF32: | ||||
*where -= add; | *where -= add; | ||||
break; | break; | ||||
case R_386_TLS_DTPMOD32: | case R_386_TLS_DTPMOD32: | ||||
*where += (Elf_Addr)defobj->tlsindex; | *where += (Elf_Addr)defobj->tlsindex; | ||||
break; | break; | ||||
case R_386_TLS_DTPOFF32: | case R_386_TLS_DTPOFF32: | ||||
*where += (Elf_Addr) def->st_value; | *where += (Elf_Addr) def->st_value; | ||||
break; | break; | ||||
case R_I386_IRELATIVE: | |||||
obj->irelative_nonplt = true; | |||||
break; | |||||
default: | default: | ||||
_rtld_error("%s: Unsupported relocation type %d" | _rtld_error("%s: Unsupported relocation type %d" | ||||
" in non-PLT relocations\n", obj->path, | " in non-PLT relocations\n", obj->path, | ||||
ELF_R_TYPE(rel->r_info)); | ELF_R_TYPE(rel->r_info)); | ||||
goto done; | goto done; | ||||
} | } | ||||
} | } | ||||
r = 0; | r = 0; | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | |||||
#ifdef dbg | #ifdef dbg | ||||
dbg("reloc_jmpslot: *%p = %p", where, (void *)target); | dbg("reloc_jmpslot: *%p = %p", where, (void *)target); | ||||
#endif | #endif | ||||
if (!ld_bind_not) | if (!ld_bind_not) | ||||
*where = target; | *where = target; | ||||
return (target); | return (target); | ||||
} | } | ||||
static void | |||||
reloc_iresolve_one(Obj_Entry *obj, const Elf_Rela *rel, | |||||
RtldLockState *lockstate) | |||||
{ | |||||
Elf_Addr *where, target; | |||||
where = (Elf_Addr *)(obj->relocbase + rel->r_offset); | |||||
lock_release(rtld_bind_lock, lockstate); | |||||
target = call_ifunc_resolver(obj->relocbase + *where); | |||||
wlock_acquire(rtld_bind_lock, lockstate); | |||||
*where = target; | |||||
} | |||||
int | int | ||||
reloc_iresolve(Obj_Entry *obj, RtldLockState *lockstate) | reloc_iresolve(Obj_Entry *obj, RtldLockState *lockstate) | ||||
{ | { | ||||
const Elf_Rel *rellim; | const Elf_Rel *rellim; | ||||
const Elf_Rel *rel; | const Elf_Rel *rel; | ||||
Elf_Addr *where, target; | |||||
if (!obj->irelative) | if (!obj->irelative) | ||||
return (0); | return (0); | ||||
obj->irelative = false; | |||||
rellim = (const Elf_Rel *)((const char *)obj->pltrel + obj->pltrelsize); | rellim = (const Elf_Rel *)((const char *)obj->pltrel + obj->pltrelsize); | ||||
for (rel = obj->pltrel; rel < rellim; rel++) { | for (rel = obj->pltrel; rel < rellim; rel++) { | ||||
switch (ELF_R_TYPE(rel->r_info)) { | if (ELF_R_TYPE(rel->r_info) == R_386_IRELATIVE) | ||||
case R_386_IRELATIVE: | reloc_iresolve_one(obj, rel, lockstate); | ||||
where = (Elf_Addr *)(obj->relocbase + rel->r_offset); | |||||
lock_release(rtld_bind_lock, lockstate); | |||||
target = call_ifunc_resolver(obj->relocbase + *where); | |||||
wlock_acquire(rtld_bind_lock, lockstate); | |||||
*where = target; | |||||
break; | |||||
} | } | ||||
return (0); | |||||
} | } | ||||
obj->irelative = false; | |||||
int | |||||
reloc_iresolve_nonplt(Obj_Entry *obj, RtldLockState *lockstate) | |||||
{ | |||||
const Elf_Rel *rellim; | |||||
const Elf_Rel *rel; | |||||
if (!obj->irelative_nonplt) | |||||
return (0); | |||||
obj->irelative_nonplt = false; | |||||
rellim = (const Elf_Rel *)((const char *)obj->rel + obj->relsize); | |||||
for (rel = obj->rel; rel < rellim; rel++) { | |||||
if (ELF_R_TYPE(rel->r_info) == R_I386_IRELATIVE) | |||||
reloc_iresolve_one(obj, rel, lockstate); | |||||
} | |||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
reloc_gnu_ifunc(Obj_Entry *obj, int flags, RtldLockState *lockstate) | reloc_gnu_ifunc(Obj_Entry *obj, int flags, RtldLockState *lockstate) | ||||
{ | { | ||||
const Elf_Rel *rellim; | const Elf_Rel *rellim; | ||||
const Elf_Rel *rel; | const Elf_Rel *rel; | ||||
▲ Show 20 Lines • Show All 122 Lines • Show Last 20 Lines |