| This is a partial backport of this commit with only the 'scope' |
| refactoring required to have access to the outer scope value |
| to use with RESOLVE_MAP to implement la_symbind for BIND_NOW. |
| |
| We do not backport this entire patch because the nested function |
| changes have significant impact on code generation and would |
| require furhter backports to support and maintain. |
| |
| commit 490e6c62aa31a8aa5c4a059f6e646ede121edf0a |
| Author: Fangrui Song <maskray@google.com> |
| Date: Thu Oct 7 11:55:02 2021 -0700 |
| |
| 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 <adhemerval.zanella@linaro.org> |
| |
| diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c |
| index 70f14b04cd383048..31d87ac846427752 100644 |
| |
| |
| @@ -40,7 +40,7 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict, |
| data. */ |
| |
| /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */ |
| -#define RESOLVE_MAP(ref, version, flags) (*ref = NULL, NULL) |
| +#define RESOLVE_MAP(map, scope, ref, version, flags) (*ref = NULL, NULL) |
| #define RESOLVE(ref, version, flags) (*ref = NULL, 0) |
| #define RESOLVE_CONFLICT_FIND_MAP(map, r_offset) \ |
| do { \ |
| @@ -67,8 +67,8 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict, |
| GL(dl_num_cache_relocations) += conflictend - conflict; |
| |
| for (; conflict < conflictend; ++conflict) |
| - elf_machine_rela (l, conflict, NULL, NULL, (void *) conflict->r_offset, |
| - 0); |
| + elf_machine_rela (l, NULL, conflict, NULL, NULL, |
| + (void *) conflict->r_offset, 0); |
| } |
| #endif |
| } |
| diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c |
| index ab1ce0eacced9d2b..1efbf515c3c1c16d 100644 |
| |
| |
| @@ -30,7 +30,7 @@ _dl_relocate_static_pie (void) |
| |
| # define STATIC_PIE_BOOTSTRAP |
| # define BOOTSTRAP_MAP (main_map) |
| -# define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP |
| +# define RESOLVE_MAP(map, scope, sym, version, flags) BOOTSTRAP_MAP |
| # include "dynamic-link.h" |
| |
| /* Figure out the run-time load address of static PIE. */ |
| @@ -46,7 +46,7 @@ _dl_relocate_static_pie (void) |
| |
| /* Relocate ourselves so we can do normal function calls and |
| data access using the global offset table. */ |
| - ELF_DYNAMIC_RELOCATE (main_map, 0, 0, 0); |
| + ELF_DYNAMIC_RELOCATE (main_map, NULL, 0, 0, 0); |
| main_map->l_relocated = 1; |
| |
| /* Initialize _r_debug. */ |
| diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c |
| index c6139b89d4ecddc8..19de5de067a5ef07 100644 |
| |
| |
| @@ -250,7 +250,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], |
| const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]); |
| |
| /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code. */ |
| -#define RESOLVE_MAP(ref, version, r_type) \ |
| +#define RESOLVE_MAP(l, scope, ref, version, r_type) \ |
| ((ELFW(ST_BIND) ((*ref)->st_info) != STB_LOCAL \ |
| && __glibc_likely (!dl_symbol_visibility_binds_local_p (*ref))) \ |
| ? ((__builtin_expect ((*ref) == l->l_lookup_cache.sym, 0) \ |
| @@ -275,7 +275,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], |
| |
| #include "dynamic-link.h" |
| |
| - ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc); |
| + ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc); |
| |
| #ifndef PROF |
| if (__glibc_unlikely (consider_profiling) |
| diff --git a/elf/do-rel.h b/elf/do-rel.h |
| index 19cb5d236ee30698..0b04d1a0bf28b9f4 100644 |
| |
| |
| @@ -38,7 +38,7 @@ |
| than fully resolved now. */ |
| |
| auto inline void __attribute__ ((always_inline)) |
| -elf_dynamic_do_Rel (struct link_map *map, |
| +elf_dynamic_do_Rel (struct link_map *map, struct r_scope_elem *scope[], |
| ElfW(Addr) reladdr, ElfW(Addr) relsize, |
| __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative, |
| int lazy, int skip_ifunc) |
| @@ -68,13 +68,13 @@ elf_dynamic_do_Rel (struct link_map *map, |
| } |
| else |
| # endif |
| - elf_machine_lazy_rel (map, l_addr, r, skip_ifunc); |
| + elf_machine_lazy_rel (map, scope, l_addr, r, skip_ifunc); |
| |
| # ifdef ELF_MACHINE_IRELATIVE |
| if (r2 != NULL) |
| for (; r2 <= end2; ++r2) |
| if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE) |
| - elf_machine_lazy_rel (map, l_addr, r2, skip_ifunc); |
| + elf_machine_lazy_rel (map, scope, l_addr, r2, skip_ifunc); |
| # endif |
| } |
| else |
| @@ -134,7 +134,7 @@ elf_dynamic_do_Rel (struct link_map *map, |
| #endif |
| |
| ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; |
| - elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], |
| + elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], |
| &map->l_versions[ndx], |
| (void *) (l_addr + r->r_offset), skip_ifunc); |
| } |
| @@ -146,7 +146,7 @@ elf_dynamic_do_Rel (struct link_map *map, |
| { |
| ElfW(Half) ndx |
| = version[ELFW(R_SYM) (r2->r_info)] & 0x7fff; |
| - elf_machine_rel (map, r2, |
| + elf_machine_rel (map, scope, r2, |
| &symtab[ELFW(R_SYM) (r2->r_info)], |
| &map->l_versions[ndx], |
| (void *) (l_addr + r2->r_offset), |
| @@ -167,14 +167,14 @@ elf_dynamic_do_Rel (struct link_map *map, |
| } |
| else |
| # endif |
| - elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, |
| + elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, |
| (void *) (l_addr + r->r_offset), skip_ifunc); |
| |
| # ifdef ELF_MACHINE_IRELATIVE |
| if (r2 != NULL) |
| for (; r2 <= end2; ++r2) |
| if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE) |
| - elf_machine_rel (map, r2, &symtab[ELFW(R_SYM) (r2->r_info)], |
| + elf_machine_rel (map, scope, r2, &symtab[ELFW(R_SYM) (r2->r_info)], |
| NULL, (void *) (l_addr + r2->r_offset), |
| skip_ifunc); |
| # endif |
| diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h |
| index 2fc3c91b7defe84e..357a2e3c6825e0fc 100644 |
| |
| |
| @@ -60,8 +60,9 @@ int _dl_try_allocate_static_tls (struct link_map *map, bool optional) |
| unaligned cases. */ |
| # if ! ELF_MACHINE_NO_REL |
| auto inline void __attribute__((always_inline)) |
| -elf_machine_rel (struct link_map *map, const ElfW(Rel) *reloc, |
| - const ElfW(Sym) *sym, const struct r_found_version *version, |
| +elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[], |
| + const ElfW(Rel) *reloc, const ElfW(Sym) *sym, |
| + const struct r_found_version *version, |
| void *const reloc_addr, int skip_ifunc); |
| auto inline void __attribute__((always_inline)) |
| elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc, |
| @@ -69,8 +70,9 @@ elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *reloc, |
| # endif |
| # if ! ELF_MACHINE_NO_RELA |
| 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, |
| +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, int skip_ifunc); |
| auto inline void __attribute__((always_inline)) |
| elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, |
| @@ -78,12 +80,12 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, |
| # endif |
| # if ELF_MACHINE_NO_RELA || defined ELF_MACHINE_PLT_REL |
| auto 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(Rel) *reloc, |
| int skip_ifunc); |
| # else |
| auto 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); |
| # endif |
| @@ -114,7 +116,7 @@ elf_machine_lazy_rel (struct link_map *map, |
| consumes precisely the very end of the DT_REL*, or DT_JMPREL and DT_REL* |
| are completely separate and there is a gap between them. */ |
| |
| -# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \ |
| +# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, scope, do_lazy, skip_ifunc, test_rel) \ |
| do { \ |
| struct { ElfW(Addr) start, size; \ |
| __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; } \ |
| @@ -152,13 +154,13 @@ elf_machine_lazy_rel (struct link_map *map, |
| } \ |
| \ |
| if (ELF_DURING_STARTUP) \ |
| - elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, \ |
| + elf_dynamic_do_##reloc ((map), scope, ranges[0].start, ranges[0].size, \ |
| ranges[0].nrelative, 0, skip_ifunc); \ |
| else \ |
| { \ |
| int ranges_index; \ |
| for (ranges_index = 0; ranges_index < 2; ++ranges_index) \ |
| - elf_dynamic_do_##reloc ((map), \ |
| + elf_dynamic_do_##reloc ((map), scope, \ |
| ranges[ranges_index].start, \ |
| ranges[ranges_index].size, \ |
| ranges[ranges_index].nrelative, \ |
| @@ -175,29 +177,29 @@ elf_machine_lazy_rel (struct link_map *map, |
| |
| # if ! ELF_MACHINE_NO_REL |
| # include "do-rel.h" |
| -# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) \ |
| - _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, lazy, skip_ifunc, _ELF_CHECK_REL) |
| +# define ELF_DYNAMIC_DO_REL(map, scope, lazy, skip_ifunc) \ |
| + _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL) |
| # else |
| -# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) /* Nothing to do. */ |
| +# define ELF_DYNAMIC_DO_REL(map, scope, lazy, skip_ifunc) /* Nothing to do. */ |
| # endif |
| |
| # if ! ELF_MACHINE_NO_RELA |
| # define DO_RELA |
| # include "do-rel.h" |
| -# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) \ |
| - _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, lazy, skip_ifunc, _ELF_CHECK_REL) |
| +# define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc) \ |
| + _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, scope, lazy, skip_ifunc, _ELF_CHECK_REL) |
| # else |
| -# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc) /* Nothing to do. */ |
| +# define ELF_DYNAMIC_DO_RELA(map, scope, lazy, skip_ifunc) /* Nothing to do. */ |
| # endif |
| |
| /* This can't just be an inline function because GCC is too dumb |
| to inline functions containing inlines themselves. */ |
| -# define ELF_DYNAMIC_RELOCATE(map, lazy, consider_profile, skip_ifunc) \ |
| +# define ELF_DYNAMIC_RELOCATE(map, scope, lazy, consider_profile, skip_ifunc) \ |
| do { \ |
| - int edr_lazy = elf_machine_runtime_setup ((map), (lazy), \ |
| + int edr_lazy = elf_machine_runtime_setup ((map), (scope), (lazy), \ |
| (consider_profile)); \ |
| - ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc); \ |
| - ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc); \ |
| + ELF_DYNAMIC_DO_REL ((map), (scope), edr_lazy, skip_ifunc); \ |
| + ELF_DYNAMIC_DO_RELA ((map), (scope), edr_lazy, skip_ifunc); \ |
| } while (0) |
| |
| #endif |
| diff --git a/elf/rtld.c b/elf/rtld.c |
| index e107af4014d43777..f3836b8a78faaf27 100644 |
| |
| |
| @@ -514,7 +514,7 @@ _dl_start (void *arg) |
| is trivial: always the map of ld.so itself. */ |
| #define RTLD_BOOTSTRAP |
| #define BOOTSTRAP_MAP (&bootstrap_map) |
| -#define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP |
| +#define RESOLVE_MAP(map, scope, sym, version, flags) BOOTSTRAP_MAP |
| #include "dynamic-link.h" |
| |
| #ifdef DONT_USE_BOOTSTRAP_MAP |
| @@ -560,7 +560,7 @@ _dl_start (void *arg) |
| /* Relocate ourselves so we can do normal function calls and |
| data access using the global offset table. */ |
| |
| - ELF_DYNAMIC_RELOCATE (&bootstrap_map, 0, 0, 0); |
| + ELF_DYNAMIC_RELOCATE (&bootstrap_map, NULL, 0, 0, 0); |
| } |
| bootstrap_map.l_relocated = 1; |
| |
| diff --git a/sysdeps/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h |
| index 3fd3c8a265d012b1..5eab544afe2717f7 100644 |
| |
| |
| @@ -65,7 +65,8 @@ elf_machine_load_address (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) |
| { |
| @@ -242,8 +243,9 @@ elf_machine_plt_value (struct link_map *map, |
| |
| 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, |
| +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; |
| @@ -256,7 +258,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 |
| @@ -381,7 +384,7 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, |
| |
| 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) |
| @@ -408,7 +411,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; |
| } |
| @@ -435,7 +438,7 @@ 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))) |
| { |
| diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h |
| index 3a30671591284d79..5ba95b9e4af49942 100644 |
| |
| |
| @@ -61,7 +61,8 @@ elf_machine_load_address (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) |
| { |
| Elf32_Addr *got; |
| extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden; |
| @@ -293,8 +294,9 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rel *reloc, |
| |
| auto inline void |
| __attribute ((always_inline)) |
| -elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, |
| - const Elf32_Sym *sym, const struct r_found_version *version, |
| +elf_machine_rel (struct link_map *map, struct r_scope_elem *scope[], |
| + const Elf32_Rel *reloc, const Elf32_Sym *sym, |
| + const struct r_found_version *version, |
| void *const reloc_addr_arg, int skip_ifunc) |
| { |
| Elf32_Addr *const reloc_addr = reloc_addr_arg; |
| @@ -327,7 +329,8 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, |
| # ifndef RTLD_BOOTSTRAP |
| const Elf32_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); |
| Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); |
| |
| if (sym != NULL |
| @@ -493,8 +496,9 @@ elf_machine_rel (struct link_map *map, const Elf32_Rel *reloc, |
| # ifndef RTLD_BOOTSTRAP |
| auto inline void |
| __attribute__ ((always_inline)) |
| -elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, |
| - const Elf32_Sym *sym, const struct r_found_version *version, |
| +elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], |
| + const Elf32_Rela *reloc, const Elf32_Sym *sym, |
| + const struct r_found_version *version, |
| void *const reloc_addr_arg, int skip_ifunc) |
| { |
| Elf32_Addr *const reloc_addr = reloc_addr_arg; |
| @@ -507,7 +511,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc, |
| # ifndef RESOLVE_CONFLICT_FIND_MAP |
| const Elf32_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); |
| Elf32_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); |
| |
| if (sym != NULL |
| @@ -661,7 +666,7 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc, |
| |
| auto 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[], |
| Elf32_Addr l_addr, const Elf32_Rel *reloc, |
| int skip_ifunc) |
| { |
| @@ -696,13 +701,13 @@ elf_machine_lazy_rel (struct link_map *map, |
| const ElfW(Half) *const version = |
| (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]); |
| ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; |
| - elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], |
| + elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], |
| &map->l_versions[ndx], |
| (void *) (l_addr + r->r_offset), skip_ifunc); |
| } |
| # ifndef RTLD_BOOTSTRAP |
| else |
| - elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, |
| + elf_machine_rel (map, scope, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, |
| (void *) (l_addr + r->r_offset), skip_ifunc); |
| # endif |
| } |
| @@ -721,7 +726,7 @@ elf_machine_lazy_rel (struct link_map *map, |
| |
| auto inline void |
| __attribute__ ((always_inline)) |
| -elf_machine_lazy_rela (struct link_map *map, |
| +elf_machine_lazy_rela (struct link_map *map, struct r_scope_elem *scope[], |
| Elf32_Addr l_addr, const Elf32_Rela *reloc, |
| int skip_ifunc) |
| { |
| @@ -745,7 +750,8 @@ elf_machine_lazy_rela (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_386_IRELATIVE)) |
| { |
| diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h |
| index 99a83d0c82ea0a9c..35996bb9173da231 100644 |
| |
| |
| @@ -345,7 +345,8 @@ dl_platform_init (void) |
| /* Set up the loaded object described by MAP so its unrelocated PLT |
| entries will jump to the on-demand fixup code in dl-runtime.c. */ |
| static inline int __attribute__ ((always_inline)) |
| -elf_machine_runtime_setup (struct link_map *map, int lazy, int profile) |
| +elf_machine_runtime_setup (struct link_map *map, struct r_scope_elem *scope[], |
| + int lazy, int profile) |
| { |
| if (map->l_info[DT_JMPREL]) |
| { |
| @@ -679,7 +680,7 @@ resolve_ifunc (Elf64_Addr value, |
| /* 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, |
| +elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], |
| const Elf64_Rela *reloc, |
| const Elf64_Sym *sym, |
| const struct r_found_version *version, |
| @@ -707,7 +708,7 @@ elf_machine_rela (struct link_map *map, |
| |
| /* We need SYM_MAP even in the absence of TLS, for elf_machine_fixup_plt |
| and STT_GNU_IFUNC. */ |
| - struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); |
| + struct link_map *sym_map = RESOLVE_MAP (map, scope, &sym, version, r_type); |
| Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend; |
| |
| if (sym != NULL |
| @@ -1036,7 +1037,7 @@ elf_machine_rela (struct link_map *map, |
| } |
| |
| auto 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[], |
| Elf64_Addr l_addr, const Elf64_Rela *reloc, |
| int skip_ifunc) |
| { |
| diff --git a/sysdeps/s390/s390-64/dl-machine.h b/sysdeps/s390/s390-64/dl-machine.h |
| index f22db7860b4da3ec..36327c40a1972dd7 100644 |
| |
| |
| @@ -75,7 +75,8 @@ elf_machine_load_address (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) |
| { |
| extern void _dl_runtime_resolve (Elf64_Word); |
| extern void _dl_runtime_profile (Elf64_Word); |
| @@ -270,8 +271,9 @@ elf_machine_plt_value (struct link_map *map, const Elf64_Rela *reloc, |
| |
| auto inline void |
| __attribute__ ((always_inline)) |
| -elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, |
| - const Elf64_Sym *sym, const struct r_found_version *version, |
| +elf_machine_rela (struct link_map *map, struct r_scope_elem *scope[], |
| + const Elf64_Rela *reloc, const Elf64_Sym *sym, |
| + const struct r_found_version *version, |
| void *const reloc_addr_arg, int skip_ifunc) |
| { |
| Elf64_Addr *const reloc_addr = reloc_addr_arg; |
| @@ -304,7 +306,8 @@ elf_machine_rela (struct link_map *map, const Elf64_Rela *reloc, |
| /* Only needed for R_390_COPY below. */ |
| const Elf64_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); |
| Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true); |
| |
| if (sym != NULL |
| @@ -449,7 +452,7 @@ elf_machine_rela_relative (Elf64_Addr l_addr, const Elf64_Rela *reloc, |
| |
| auto 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[], |
| Elf64_Addr l_addr, const Elf64_Rela *reloc, |
| int skip_ifunc) |
| { |
| diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h |
| index b94d3b39ec1dca64..5262aa69c06aa8db 100644 |
| |
| |
| @@ -62,7 +62,8 @@ elf_machine_load_address (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; |
| @@ -260,8 +261,9 @@ elf_machine_plt_value (struct link_map *map, const ElfW(Rela) *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, |
| +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; |
| @@ -300,7 +302,7 @@ 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 |
| @@ -539,7 +541,7 @@ elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, |
| |
| auto 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) |
| { |
| @@ -573,7 +575,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)) |
| { |