svn commit: r358142 - in stable/12/libexec/rtld-elf: . aarch64 amd64 arm i386 mips powerpc powerpc64 riscv sparc64
Konstantin Belousov
kib at FreeBSD.org
Thu Feb 20 01:27:38 UTC 2020
Author: kib
Date: Thu Feb 20 01:27:35 2020
New Revision: 358142
URL: https://svnweb.freebsd.org/changeset/base/358142
Log:
MFC r357895, r357910:
Handle non-plt IRELATIVE relocations, at least for x86.
Modified:
stable/12/libexec/rtld-elf/aarch64/reloc.c
stable/12/libexec/rtld-elf/amd64/reloc.c
stable/12/libexec/rtld-elf/arm/reloc.c
stable/12/libexec/rtld-elf/i386/reloc.c
stable/12/libexec/rtld-elf/mips/reloc.c
stable/12/libexec/rtld-elf/powerpc/reloc.c
stable/12/libexec/rtld-elf/powerpc64/reloc.c
stable/12/libexec/rtld-elf/riscv/reloc.c
stable/12/libexec/rtld-elf/rtld.c
stable/12/libexec/rtld-elf/rtld.h
stable/12/libexec/rtld-elf/sparc64/reloc.c
Directory Properties:
stable/12/ (props changed)
Modified: stable/12/libexec/rtld-elf/aarch64/reloc.c
==============================================================================
--- stable/12/libexec/rtld-elf/aarch64/reloc.c Thu Feb 20 01:24:45 2020 (r358141)
+++ stable/12/libexec/rtld-elf/aarch64/reloc.c Thu Feb 20 01:27:35 2020 (r358142)
@@ -258,31 +258,56 @@ reloc_jmpslots(Obj_Entry *obj, int flags, RtldLockStat
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 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int
*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",
Modified: stable/12/libexec/rtld-elf/amd64/reloc.c
==============================================================================
--- stable/12/libexec/rtld-elf/amd64/reloc.c Thu Feb 20 01:24:45 2020 (r358141)
+++ stable/12/libexec/rtld-elf/amd64/reloc.c Thu Feb 20 01:27:35 2020 (r358142)
@@ -303,6 +303,10 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int
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 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
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
Modified: stable/12/libexec/rtld-elf/arm/reloc.c
==============================================================================
--- stable/12/libexec/rtld-elf/arm/reloc.c Thu Feb 20 01:24:45 2020 (r358141)
+++ stable/12/libexec/rtld-elf/arm/reloc.c Thu Feb 20 01:27:35 2020 (r358142)
@@ -452,6 +452,15 @@ reloc_iresolve(Obj_Entry *obj __unused,
}
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)
{
Modified: stable/12/libexec/rtld-elf/i386/reloc.c
==============================================================================
--- stable/12/libexec/rtld-elf/i386/reloc.c Thu Feb 20 01:24:45 2020 (r358141)
+++ stable/12/libexec/rtld-elf/i386/reloc.c Thu Feb 20 01:27:35 2020 (r358142)
@@ -259,6 +259,9 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int
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,
@@ -361,29 +364,51 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
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_IRELATIVE)
+ 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
Modified: stable/12/libexec/rtld-elf/mips/reloc.c
==============================================================================
--- stable/12/libexec/rtld-elf/mips/reloc.c Thu Feb 20 01:24:45 2020 (r358141)
+++ stable/12/libexec/rtld-elf/mips/reloc.c Thu Feb 20 01:27:35 2020 (r358142)
@@ -723,6 +723,15 @@ reloc_iresolve(Obj_Entry *obj __unused,
}
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)
{
Modified: stable/12/libexec/rtld-elf/powerpc/reloc.c
==============================================================================
--- stable/12/libexec/rtld-elf/powerpc/reloc.c Thu Feb 20 01:24:45 2020 (r358141)
+++ stable/12/libexec/rtld-elf/powerpc/reloc.c Thu Feb 20 01:27:35 2020 (r358142)
@@ -540,6 +540,13 @@ reloc_iresolve(Obj_Entry *obj __unused,
}
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)
{
Modified: stable/12/libexec/rtld-elf/powerpc64/reloc.c
==============================================================================
--- stable/12/libexec/rtld-elf/powerpc64/reloc.c Thu Feb 20 01:24:45 2020 (r358141)
+++ stable/12/libexec/rtld-elf/powerpc64/reloc.c Thu Feb 20 01:27:35 2020 (r358142)
@@ -513,6 +513,13 @@ reloc_gnu_ifunc(Obj_Entry *obj __unused, int flags __u
return (0);
}
+int
+reloc_iresolve_nonplt(Obj_Entry *obj __unused,
+ struct Struct_RtldLockState *lockstate __unused)
+{
+ return (0);
+}
+
void
init_pltgot(Obj_Entry *obj)
{
Modified: stable/12/libexec/rtld-elf/riscv/reloc.c
==============================================================================
--- stable/12/libexec/rtld-elf/riscv/reloc.c Thu Feb 20 01:24:45 2020 (r358141)
+++ stable/12/libexec/rtld-elf/riscv/reloc.c Thu Feb 20 01:27:35 2020 (r358142)
@@ -212,6 +212,15 @@ reloc_iresolve(Obj_Entry *obj __unused,
}
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)
{
Modified: stable/12/libexec/rtld-elf/rtld.c
==============================================================================
--- stable/12/libexec/rtld-elf/rtld.c Thu Feb 20 01:24:45 2020 (r358141)
+++ stable/12/libexec/rtld-elf/rtld.c Thu Feb 20 01:27:35 2020 (r358142)
@@ -2987,10 +2987,13 @@ resolve_object_ifunc(Obj_Entry *obj, bool bind_now, in
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)
Modified: stable/12/libexec/rtld-elf/rtld.h
==============================================================================
--- stable/12/libexec/rtld-elf/rtld.h Thu Feb 20 01:24:45 2020 (r358141)
+++ stable/12/libexec/rtld-elf/rtld.h Thu Feb 20 01:27:35 2020 (r358142)
@@ -265,6 +265,7 @@ typedef struct Struct_Obj_Entry {
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_non_plt(Obj_Entry *, Obj_Entry *, int flags,
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);
Modified: stable/12/libexec/rtld-elf/sparc64/reloc.c
==============================================================================
--- stable/12/libexec/rtld-elf/sparc64/reloc.c Thu Feb 20 01:24:45 2020 (r358141)
+++ stable/12/libexec/rtld-elf/sparc64/reloc.c Thu Feb 20 01:27:35 2020 (r358142)
@@ -570,6 +570,15 @@ reloc_iresolve(Obj_Entry *obj __unused,
}
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)
{
More information about the svn-src-stable-12
mailing list