summaryrefslogtreecommitdiffstats
path: root/libexec
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2014-08-29 10:43:56 +0000
committerkib <kib@FreeBSD.org>2014-08-29 10:43:56 +0000
commit359d218e65e5695b87547571338929698168a4e6 (patch)
tree3d89274ac7e90307459bc43b453f825a8587e9fe /libexec
parent4c00c0c1925cf1b8653b0e0a139fa987a4f5528b (diff)
downloadFreeBSD-src-359d218e65e5695b87547571338929698168a4e6.zip
FreeBSD-src-359d218e65e5695b87547571338929698168a4e6.tar.gz
Optimize r270798, only do the second pass over non-plt relocations
when the first pass found IFUNCs. Sponsored by: The FreeBSD Foundation MFC after: 2 weeks
Diffstat (limited to 'libexec')
-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