From 490e6c62aa31a8aa5c4a059f6e646ede121edf0a Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 7 Oct 2021 11:55:02 -0700 Subject: elf: Avoid nested functions in the loader [BZ #27220] dynamic-link.h is included more than once in some elf/ files (rtld.c, dl-conflict.c, dl-reloc.c, dl-reloc-static-pie.c) and uses GCC nested functions. This harms readability and the nested functions usage is the biggest obstacle prevents Clang build (Clang doesn't support GCC nested functions). The key idea for unnesting is to add extra parameters (struct link_map *and struct r_scope_elm *[]) to RESOLVE_MAP, ELF_MACHINE_BEFORE_RTLD_RELOC, ELF_DYNAMIC_RELOCATE, elf_machine_rel[a], elf_machine_lazy_rel, and elf_machine_runtime_setup. (This is inspired by Stan Shebs' ppc64/x86-64 implementation in the google/grte/v5-2.27/master which uses mixed extra parameters and static variables.) Future simplification: * If mips elf_machine_runtime_setup no longer needs RESOLVE_GOTSYM, elf_machine_runtime_setup can drop the `scope` parameter. * If TLSDESC no longer need to be in elf_machine_lazy_rel, elf_machine_lazy_rel can drop the `scope` parameter. Tested on aarch64, i386, x86-64, powerpc64le, powerpc64, powerpc32, sparc64, sparcv9, s390x, s390, hppa, ia64, armhf, alpha, and mips64. In addition, tested build-many-glibcs.py with {arc,csky,microblaze,nios2}-linux-gnu and riscv64-linux-gnu-rv64imafdc-lp64d. Reviewed-by: Adhemerval Zanella --- sysdeps/x86_64/dl-machine.h | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'sysdeps/x86_64') diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h index b3ed4dd467..9c0182d597 100644 --- a/sysdeps/x86_64/dl-machine.h +++ b/sysdeps/x86_64/dl-machine.h @@ -54,7 +54,8 @@ elf_machine_dynamic (void) entries will jump to the on-demand fixup code in dl-runtime.c. */ static inline int __attribute__ ((unused, always_inline)) -elf_machine_runtime_setup (struct link_map *l, int lazy, int profile) +elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[], + int lazy, int profile) { Elf64_Addr *got; extern void _dl_runtime_resolve_fxsave (ElfW(Word)) attribute_hidden; @@ -250,12 +251,11 @@ elf_machine_plt_value (struct link_map *map, const ElfW(Rela) *reloc, /* Perform the relocation specified by RELOC and SYM (which is fully resolved). MAP is the object containing the reloc. */ -auto inline void -__attribute__ ((always_inline)) -elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, - const ElfW(Sym) *sym, const struct r_found_version *version, - void *const reloc_addr_arg, int skip_ifunc) -{ +static inline void __attribute__((always_inline)) +elf_machine_rela(struct link_map *map, struct r_scope_elem *scope[], + const ElfW(Rela) *reloc, const ElfW(Sym) *sym, + const struct r_found_version *version, + void *const reloc_addr_arg, int skip_ifunc) { ElfW(Addr) *const reloc_addr = reloc_addr_arg; const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info); @@ -292,7 +292,8 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, # ifndef RTLD_BOOTSTRAP const ElfW(Sym) *const refsym = sym; # endif - struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); + struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, + r_type); ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true); if (sym != NULL @@ -517,7 +518,7 @@ and creates an unsatisfiable circular dependency.\n", } } -auto inline void +static inline void __attribute ((always_inline)) elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, void *const reloc_addr_arg) @@ -536,9 +537,9 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, } } -auto inline void +static inline void __attribute ((always_inline)) -elf_machine_lazy_rel (struct link_map *map, +elf_machine_lazy_rel (struct link_map *map, struct r_scope_elem *scope[], ElfW(Addr) l_addr, const ElfW(Rela) *reloc, int skip_ifunc) { @@ -572,7 +573,7 @@ elf_machine_lazy_rel (struct link_map *map, /* Always initialize TLS descriptors completely at load time, in case static TLS is allocated for it that requires locking. */ - elf_machine_rela (map, reloc, sym, version, reloc_addr, skip_ifunc); + elf_machine_rela (map, scope, reloc, sym, version, reloc_addr, skip_ifunc); } else if (__glibc_unlikely (r_type == R_X86_64_IRELATIVE)) { -- cgit 1.4.1