diff options
author | kib <kib@FreeBSD.org> | 2014-09-12 16:22:01 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2014-09-12 16:22:01 +0000 |
commit | 7102c463391b21fea4e6679d5c6539bb04b7f528 (patch) | |
tree | 72dd52a692d6e0f484ed7d8de8de5fe8d9403512 /libexec/rtld-elf/rtld.c | |
parent | 306ae7f936713a7fcf65a414441afee1a31534c1 (diff) | |
download | FreeBSD-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.c | 13 |
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) { |