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
This commit is contained in:
Konstantin Belousov 2014-08-29 10:43:56 +00:00
parent ff21e856ec
commit 74b0daf4f9
4 changed files with 9 additions and 3 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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 */