summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libexec/rtld-elf/amd64/reloc.c4
-rw-r--r--libexec/rtld-elf/i386/reloc.c4
-rw-r--r--libexec/rtld-elf/rtld.c3
-rw-r--r--libexec/rtld-elf/rtld.h1
4 files changed, 9 insertions, 3 deletions
diff --git a/libexec/rtld-elf/amd64/reloc.c b/libexec/rtld-elf/amd64/reloc.c
index fa501a1..35f33cc 100644
--- a/libexec/rtld-elf/amd64/reloc.c
+++ b/libexec/rtld-elf/amd64/reloc.c
@@ -176,8 +176,10 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
case R_X86_64_64:
case R_X86_64_PC32:
case R_X86_64_GLOB_DAT:
- if ((flags & SYMLOOK_IFUNC) == 0)
+ if ((flags & SYMLOOK_IFUNC) == 0) {
+ obj->non_plt_gnu_ifunc = true;
continue;
+ }
symval = (Elf_Addr)rtld_resolve_ifunc(
defobj, def);
break;
diff --git a/libexec/rtld-elf/i386/reloc.c b/libexec/rtld-elf/i386/reloc.c
index c2bb246..c1e0a39 100644
--- a/libexec/rtld-elf/i386/reloc.c
+++ b/libexec/rtld-elf/i386/reloc.c
@@ -161,8 +161,10 @@ reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld, int flags,
case R_386_32:
case R_386_PC32:
case R_386_GLOB_DAT:
- if ((flags & SYMLOOK_IFUNC) == 0)
+ if ((flags & SYMLOOK_IFUNC) == 0) {
+ obj->non_plt_gnu_ifunc = true;
continue;
+ }
symval = (Elf_Addr)rtld_resolve_ifunc(
defobj, def);
break;
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index cbcf513..b1337c0 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -2576,7 +2576,8 @@ relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj,
* reference other symbols, which must be readily processed
* before resolvers are called.
*/
- if (reloc_non_plt(obj, rtldobj, flags | SYMLOOK_IFUNC, lockstate))
+ if (obj->non_plt_gnu_ifunc &&
+ reloc_non_plt(obj, rtldobj, flags | SYMLOOK_IFUNC, lockstate))
return (-1);
if (obj->relro_size > 0) {
diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h
index a0f24cc..ace229f 100644
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -271,6 +271,7 @@ typedef struct Struct_Obj_Entry {
bool filtees_loaded : 1; /* Filtees loaded */
bool irelative : 1; /* Object has R_MACHDEP_IRELATIVE 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 crt_no_init : 1; /* Object' crt does not call _init/_fini */
bool valid_hash_sysv : 1; /* A valid System V hash hash tag is available */
bool valid_hash_gnu : 1; /* A valid GNU hash tag is available */
OpenPOWER on IntegriCloud