Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109959031
D23652.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D23652.diff
View Options
Index: head/libexec/rtld-elf/aarch64/reloc.c
===================================================================
--- head/libexec/rtld-elf/aarch64/reloc.c
+++ head/libexec/rtld-elf/aarch64/reloc.c
@@ -258,31 +258,56 @@
return (0);
}
+static void
+reloc_iresolve_one(Obj_Entry *obj, const Elf_Rela *rela,
+ RtldLockState *lockstate)
+{
+ Elf_Addr *where, target, *ptr;
+
+ ptr = (Elf_Addr *)(obj->relocbase + rela->r_addend);
+ where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+ lock_release(rtld_bind_lock, lockstate);
+ target = call_ifunc_resolver(ptr);
+ wlock_acquire(rtld_bind_lock, lockstate);
+ *where = target;
+}
+
int
reloc_iresolve(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
{
const Elf_Rela *relalim;
const Elf_Rela *rela;
- Elf_Addr *where, target, *ptr;
if (!obj->irelative)
return (0);
- relalim = (const Elf_Rela *)((const char *)obj->pltrela + obj->pltrelasize);
+ obj->irelative = false;
+ relalim = (const Elf_Rela *)((const char *)obj->pltrela +
+ obj->pltrelasize);
for (rela = obj->pltrela; rela < relalim; rela++) {
- if (ELF_R_TYPE(rela->r_info) == R_AARCH64_IRELATIVE) {
- ptr = (Elf_Addr *)(obj->relocbase + rela->r_addend);
- where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
- lock_release(rtld_bind_lock, lockstate);
- target = call_ifunc_resolver(ptr);
- wlock_acquire(rtld_bind_lock, lockstate);
- *where = target;
- }
+ if (ELF_R_TYPE(rela->r_info) == R_AARCH64_IRELATIVE)
+ reloc_iresolve_one(obj, rela, lockstate);
}
- obj->irelative = false;
return (0);
}
int
+reloc_iresolve_nonplt(Obj_Entry *obj, struct Struct_RtldLockState *lockstate)
+{
+ const Elf_Rela *relalim;
+ const Elf_Rela *rela;
+
+ if (!obj->irelative_nonplt)
+ return (0);
+ obj->irelative_nonplt = false;
+ relalim = (const Elf_Rela *)((const char *)obj->rela + obj->relasize);
+ for (rela = obj->rela; rela < relalim; rela++) {
+ if (ELF_R_TYPE(rela->r_info) == R_AARCH64_IRELATIVE)
+ reloc_iresolve_one(obj, rela, lockstate);
+ }
+ return (0);
+}
+
+int
reloc_gnu_ifunc(Obj_Entry *obj, int flags,
struct Struct_RtldLockState *lockstate)
{
@@ -497,6 +522,9 @@
*where = (Elf_Addr)(obj->relocbase + rela->r_addend);
break;
case R_AARCH64_NONE:
+ break;
+ case R_AARCH64_IRELATIVE:
+ obj->irelative_nonplt = true;
break;
default:
rtld_printf("%s: Unhandled relocation %lu\n",
Index: head/libexec/rtld-elf/amd64/reloc.c
===================================================================
--- head/libexec/rtld-elf/amd64/reloc.c
+++ head/libexec/rtld-elf/amd64/reloc.c
@@ -303,6 +303,10 @@
case R_X86_64_RELATIVE:
*where = (Elf_Addr)(obj->relocbase + rela->r_addend);
break;
+ case R_X86_64_IRELATIVE:
+ obj->irelative_nonplt = true;
+ break;
+
/*
* missing:
* R_X86_64_GOTPCREL, R_X86_64_32, R_X86_64_32S, R_X86_64_16,
@@ -410,34 +414,53 @@
return (target);
}
+static void
+reloc_iresolve_one(Obj_Entry *obj, const Elf_Rela *rela,
+ RtldLockState *lockstate)
+{
+ Elf_Addr *where, target, *ptr;
+
+ ptr = (Elf_Addr *)(obj->relocbase + rela->r_addend);
+ where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
+ lock_release(rtld_bind_lock, lockstate);
+ target = call_ifunc_resolver(ptr);
+ wlock_acquire(rtld_bind_lock, lockstate);
+ *where = target;
+}
+
int
reloc_iresolve(Obj_Entry *obj, RtldLockState *lockstate)
{
- const Elf_Rela *relalim;
- const Elf_Rela *rela;
+ const Elf_Rela *relalim;
+ const Elf_Rela *rela;
- if (!obj->irelative)
+ if (!obj->irelative)
+ return (0);
+ obj->irelative = false;
+ relalim = (const Elf_Rela *)((const char *)obj->pltrela +
+ obj->pltrelasize);
+ for (rela = obj->pltrela; rela < relalim; rela++) {
+ if (ELF_R_TYPE(rela->r_info) == R_X86_64_IRELATIVE)
+ reloc_iresolve_one(obj, rela, lockstate);
+ }
return (0);
- relalim = (const Elf_Rela *)((const char *)obj->pltrela + obj->pltrelasize);
- for (rela = obj->pltrela; rela < relalim; rela++) {
- Elf_Addr *where, target, *ptr;
+}
- switch (ELF_R_TYPE(rela->r_info)) {
- case R_X86_64_JMP_SLOT:
- break;
+int
+reloc_iresolve_nonplt(Obj_Entry *obj, RtldLockState *lockstate)
+{
+ const Elf_Rela *relalim;
+ const Elf_Rela *rela;
- case R_X86_64_IRELATIVE:
- ptr = (Elf_Addr *)(obj->relocbase + rela->r_addend);
- where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
- lock_release(rtld_bind_lock, lockstate);
- target = call_ifunc_resolver(ptr);
- wlock_acquire(rtld_bind_lock, lockstate);
- *where = target;
- break;
+ if (!obj->irelative_nonplt)
+ return (0);
+ obj->irelative_nonplt = false;
+ relalim = (const Elf_Rela *)((const char *)obj->rela + obj->relasize);
+ for (rela = obj->rela; rela < relalim; rela++) {
+ if (ELF_R_TYPE(rela->r_info) == R_X86_64_IRELATIVE)
+ reloc_iresolve_one(obj, rela, lockstate);
}
- }
- obj->irelative = false;
- return (0);
+ return (0);
}
int
Index: head/libexec/rtld-elf/arm/reloc.c
===================================================================
--- head/libexec/rtld-elf/arm/reloc.c
+++ head/libexec/rtld-elf/arm/reloc.c
@@ -452,6 +452,15 @@
}
int
+reloc_iresolve_nonplt(Obj_Entry *obj __unused,
+ struct Struct_RtldLockState *lockstate __unused)
+{
+
+ /* XXX not implemented */
+ return (0);
+}
+
+int
reloc_gnu_ifunc(Obj_Entry *obj __unused, int flags __unused,
struct Struct_RtldLockState *lockstate __unused)
{
Index: head/libexec/rtld-elf/i386/reloc.c
===================================================================
--- head/libexec/rtld-elf/i386/reloc.c
+++ head/libexec/rtld-elf/i386/reloc.c
@@ -263,6 +263,9 @@
case R_386_TLS_DTPOFF32:
*where += (Elf_Addr) def->st_value;
break;
+ case R_386_IRELATIVE:
+ obj->irelative_nonplt = true;
+ break;
default:
_rtld_error("%s: Unsupported relocation type %d"
" in non-PLT relocations\n", obj->path,
@@ -365,29 +368,51 @@
return (target);
}
+static void
+reloc_iresolve_one(Obj_Entry *obj, const Elf_Rel *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
reloc_iresolve(Obj_Entry *obj, RtldLockState *lockstate)
{
- const Elf_Rel *rellim;
- const Elf_Rel *rel;
- Elf_Addr *where, target;
+ const Elf_Rel *rellim;
+ const Elf_Rel *rel;
- if (!obj->irelative)
+ if (!obj->irelative)
+ return (0);
+ obj->irelative = false;
+ rellim = (const Elf_Rel *)((const char *)obj->pltrel + obj->pltrelsize);
+ for (rel = obj->pltrel; rel < rellim; rel++) {
+ if (ELF_R_TYPE(rel->r_info) == R_386_RELATIVE)
+ reloc_iresolve_one(obj, rel, lockstate);
+ }
return (0);
- rellim = (const Elf_Rel *)((const char *)obj->pltrel + obj->pltrelsize);
- for (rel = obj->pltrel; rel < rellim; rel++) {
- switch (ELF_R_TYPE(rel->r_info)) {
- case R_386_IRELATIVE:
- 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;
+}
+
+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_386_IRELATIVE)
+ reloc_iresolve_one(obj, rel, lockstate);
}
- }
- obj->irelative = false;
- return (0);
+ return (0);
}
int
Index: head/libexec/rtld-elf/mips/reloc.c
===================================================================
--- head/libexec/rtld-elf/mips/reloc.c
+++ head/libexec/rtld-elf/mips/reloc.c
@@ -723,6 +723,15 @@
}
int
+reloc_iresolve_nonplt(Obj_Entry *obj __unused,
+ struct Struct_RtldLockState *lockstate __unused)
+{
+
+ /* XXX not implemented */
+ return (0);
+}
+
+int
reloc_gnu_ifunc(Obj_Entry *obj __unused, int flags __unused,
struct Struct_RtldLockState *lockstate __unused)
{
Index: head/libexec/rtld-elf/powerpc/reloc.c
===================================================================
--- head/libexec/rtld-elf/powerpc/reloc.c
+++ head/libexec/rtld-elf/powerpc/reloc.c
@@ -653,6 +653,13 @@
}
int
+reloc_iresolve_nonplt(Obj_Entry *obj __unused,
+ struct Struct_RtldLockState *lockstate __unused)
+{
+ return (0);
+}
+
+int
reloc_gnu_ifunc(Obj_Entry *obj __unused, int flags __unused,
struct Struct_RtldLockState *lockstate __unused)
{
Index: head/libexec/rtld-elf/powerpc64/reloc.c
===================================================================
--- head/libexec/rtld-elf/powerpc64/reloc.c
+++ head/libexec/rtld-elf/powerpc64/reloc.c
@@ -652,6 +652,13 @@
#endif
}
+int
+reloc_iresolve_nonplt(Obj_Entry *obj __unused,
+ struct Struct_RtldLockState *lockstate __unused)
+{
+ return (0);
+}
+
void
init_pltgot(Obj_Entry *obj)
{
Index: head/libexec/rtld-elf/riscv/reloc.c
===================================================================
--- head/libexec/rtld-elf/riscv/reloc.c
+++ head/libexec/rtld-elf/riscv/reloc.c
@@ -212,6 +212,15 @@
}
int
+reloc_iresolve_nonplt(Obj_Entry *obj __unused,
+ struct Struct_RtldLockState *lockstate __unused)
+{
+
+ /* XXX not implemented */
+ return (0);
+}
+
+int
reloc_gnu_ifunc(Obj_Entry *obj __unused, int flags __unused,
struct Struct_RtldLockState *lockstate __unused)
{
Index: head/libexec/rtld-elf/rtld.h
===================================================================
--- head/libexec/rtld-elf/rtld.h
+++ head/libexec/rtld-elf/rtld.h
@@ -264,6 +264,7 @@
bool dag_inited : 1; /* Object has its DAG initialized. */
bool filtees_loaded : 1; /* Filtees loaded */
bool irelative : 1; /* Object has R_MACHDEP_IRELATIVE relocs */
+ bool irelative_nonplt : 1; /* Object has R_MACHDEP_IRELATIVE non-plt relocs */
bool gnu_ifunc : 1; /* Object has references to STT_GNU_IFUNC */
bool non_plt_gnu_ifunc : 1; /* Object has non-plt IFUNC references */
bool ifuncs_resolved : 1; /* Object ifuncs were already resolved */
@@ -406,6 +407,7 @@
int reloc_plt(Obj_Entry *, int flags, struct Struct_RtldLockState *);
int reloc_jmpslots(Obj_Entry *, int flags, struct Struct_RtldLockState *);
int reloc_iresolve(Obj_Entry *, struct Struct_RtldLockState *);
+int reloc_iresolve_nonplt(Obj_Entry *, struct Struct_RtldLockState *);
int reloc_gnu_ifunc(Obj_Entry *, int flags, struct Struct_RtldLockState *);
void ifunc_init(Elf_Auxinfo[__min_size(AT_COUNT)]);
void pre_init(void);
Index: head/libexec/rtld-elf/rtld.c
===================================================================
--- head/libexec/rtld-elf/rtld.c
+++ head/libexec/rtld-elf/rtld.c
@@ -3034,10 +3034,13 @@
if (obj->ifuncs_resolved)
return (0);
obj->ifuncs_resolved = true;
- if (!obj->irelative && !((obj->bind_now || bind_now) && obj->gnu_ifunc))
+ if (!obj->irelative && !obj->irelative_nonplt &&
+ !((obj->bind_now || bind_now) && obj->gnu_ifunc))
return (0);
if (obj_disable_relro(obj) == -1 ||
(obj->irelative && reloc_iresolve(obj, lockstate) == -1) ||
+ (obj->irelative_nonplt && reloc_iresolve_nonplt(obj,
+ lockstate) == -1) ||
((obj->bind_now || bind_now) && obj->gnu_ifunc &&
reloc_gnu_ifunc(obj, flags, lockstate) == -1) ||
obj_enforce_relro(obj) == -1)
Index: head/libexec/rtld-elf/sparc64/reloc.c
===================================================================
--- head/libexec/rtld-elf/sparc64/reloc.c
+++ head/libexec/rtld-elf/sparc64/reloc.c
@@ -570,6 +570,15 @@
}
int
+reloc_iresolve_nonplt(Obj_Entry *obj __unused,
+ struct Struct_RtldLockState *lockstate __unused)
+{
+
+ /* XXX not implemented */
+ return (0);
+}
+
+int
reloc_gnu_ifunc(Obj_Entry *obj __unused, int flags __unused,
struct Struct_RtldLockState *lockstate __unused)
{
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Feb 12, 6:14 PM (21 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16614298
Default Alt Text
D23652.diff (11 KB)
Attached To
Mode
D23652: Handle non-plt IRELATIVE relocations.
Attached
Detach File
Event Timeline
Log In to Comment