summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf/rtld.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2014-09-12 16:22:01 +0000
committerkib <kib@FreeBSD.org>2014-09-12 16:22:01 +0000
commit7102c463391b21fea4e6679d5c6539bb04b7f528 (patch)
tree72dd52a692d6e0f484ed7d8de8de5fe8d9403512 /libexec/rtld-elf/rtld.c
parent306ae7f936713a7fcf65a414441afee1a31534c1 (diff)
downloadFreeBSD-src-7102c463391b21fea4e6679d5c6539bb04b7f528.zip
FreeBSD-src-7102c463391b21fea4e6679d5c6539bb04b7f528.tar.gz
MFC r270798:
Process STT_GNU_IFUNC when doing non-plt relocations. MFC r270802: Only do the second pass over non-plt relocations when the first pass found IFUNCs. Approved by: re (gjb)
Diffstat (limited to 'libexec/rtld-elf/rtld.c')
-rw-r--r--libexec/rtld-elf/rtld.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 344a6d9..06eecb7 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -2475,7 +2475,7 @@ relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj,
}
}
- /* Process the non-PLT relocations. */
+ /* Process the non-PLT non-IFUNC relocations. */
if (reloc_non_plt(obj, rtldobj, flags, lockstate))
return (-1);
@@ -2488,7 +2488,6 @@ relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj,
}
}
-
/* Set the special PLT or GOT entries. */
init_pltgot(obj);
@@ -2500,6 +2499,16 @@ relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj,
if (reloc_jmpslots(obj, flags, lockstate) == -1)
return (-1);
+ /*
+ * Process the non-PLT IFUNC relocations. The relocations are
+ * processed in two phases, because IFUNC resolvers may
+ * reference other symbols, which must be readily processed
+ * before resolvers are called.
+ */
+ if (obj->non_plt_gnu_ifunc &&
+ reloc_non_plt(obj, rtldobj, flags | SYMLOOK_IFUNC, lockstate))
+ return (-1);
+
if (obj->relro_size > 0) {
if (mprotect(obj->relro_page, obj->relro_size,
PROT_READ) == -1) {
OpenPOWER on IntegriCloud