diff options
author | Fangrui Song <maskray@google.com> | 2021-09-24 13:44:48 -0700 |
---|---|---|
committer | Fangrui Song <maskray@google.com> | 2021-09-24 13:44:48 -0700 |
commit | 23381aebf2576115acac23690af6081544fc80eb (patch) | |
tree | 12b19a2907794d5833cff7818792c5d49effef0a /sysdeps/aarch64/dl-machine.h | |
parent | 4ae2b8a42338f6adba7817539d05ad347154cda3 (diff) | |
download | glibc-maskray/unnest.tar.gz |
elf: Avoid nested functions in the loader (all ports) [BZ #27220]maskray/unnest
[Alternative to https://sourceware.org/pipermail/libc-alpha/2021-August/130340.html
This version fixes all ports and doesn't add NESTING dispatches.]
[Available at
https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/maskray/unnest ]
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 CC=clang (which doesn't support the
feature).
The key idea for unnesting is to add extra parameters (link_map * and
r_scope_elm *[]) to RESOLVE_MAP, ELF_MACHINE_BEFORE_RTLD_RELOC,
ELF_DYNAMIC_RELOCATE, elf_machine_rela?, 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 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-linux-gnu, powerpc64le-linux-gnu and x86_64-linux-gnu.
Tested build-many-glibcs.py glibcs with
{alpha,arc,csky,hppa,ia64,microblaze,nios2,s390x,sh4,sparc64,sparc64}-linux-gnu,
arm-linux-gnueabi, csky-linux-gnuabiv2, mips64-linux-gnu-n64, and riscv64-linux-gnu-rv64imafdc-lp64.
Diffstat (limited to 'sysdeps/aarch64/dl-machine.h')
-rw-r--r-- | sysdeps/aarch64/dl-machine.h | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h index 3e10cb462f..e30e81c902 100644 --- a/sysdeps/aarch64/dl-machine.h +++ b/sysdeps/aarch64/dl-machine.h @@ -59,7 +59,8 @@ elf_machine_dynamic (void) entries will jump to the on-demand fixup code in dl-runtime.c. */ static inline int __attribute__ ((unused)) -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) { if (l->l_info[DT_JMPREL] && lazy) { @@ -237,10 +238,11 @@ elf_machine_plt_value (struct link_map *map, #ifdef RESOLVE_MAP -auto inline void +static 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, +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; @@ -253,7 +255,8 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, else { const ElfW(Sym) *const refsym = sym; - 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 @@ -377,9 +380,9 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, *reloc_addr = l_addr + reloc->r_addend; } -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) @@ -406,7 +409,7 @@ elf_machine_lazy_rel (struct link_map *map, (const void *)D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]); version = &map->l_versions[vernum[symndx] & 0x7fff]; } - elf_machine_rela (map, reloc, sym, version, reloc_addr, + elf_machine_rela (map, scope, reloc, sym, version, reloc_addr, skip_ifunc); return; } @@ -433,7 +436,8 @@ elf_machine_lazy_rel (struct link_map *map, /* Always initialize TLS descriptors completely, because lazy initialization requires synchronization at every TLS access. */ - 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 == AARCH64_R(IRELATIVE))) { |