diff options
author | Stan Shebs <stanshebs@google.com> | 2018-09-14 10:21:15 -0700 |
---|---|---|
committer | Stan Shebs <stanshebs@google.com> | 2019-04-24 09:10:20 -0700 |
commit | 7c44a0bf9c14fe15a1543ab1cca5da2a66d969e2 (patch) | |
tree | 8dc6b7b360973344cf413797d17e481b4f2d88c0 | |
parent | 868fc27ff4c37ae6e30ffc4ee78e5d2594998658 (diff) | |
download | glibc-7c44a0bf9c14fe15a1543ab1cca5da2a66d969e2.tar.gz glibc-7c44a0bf9c14fe15a1543ab1cca5da2a66d969e2.tar.xz glibc-7c44a0bf9c14fe15a1543ab1cca5da2a66d969e2.zip |
Change de-nesting fix to use added argument instead of globals
-rw-r--r-- | elf/dl-conflict.c | 6 | ||||
-rw-r--r-- | elf/dl-reloc.c | 6 | ||||
-rw-r--r-- | elf/do-rel.h | 30 | ||||
-rw-r--r-- | elf/dynamic-link.h | 90 | ||||
-rw-r--r-- | elf/rtld.c | 13 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc64/dl-machine.h | 10 | ||||
-rw-r--r-- | sysdeps/x86_64/dl-machine.h | 10 |
7 files changed, 152 insertions, 13 deletions
diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c index 4178641e9a..e581b85301 100644 --- a/elf/dl-conflict.c +++ b/elf/dl-conflict.c @@ -95,7 +95,11 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict, for (; conflict < conflictend; ++conflict) elf_machine_rela (l, conflict, NULL, NULL, (void *) conflict->r_offset, - 0); + 0 +#ifndef NESTING + , NULL +#endif + ); } #endif } diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c index 8e7986f112..34a5507177 100644 --- a/elf/dl-reloc.c +++ b/elf/dl-reloc.c @@ -295,7 +295,11 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[], #endif /* NESTING */ - ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc); + ELF_DYNAMIC_RELOCATE (l, lazy, consider_profiling, skip_ifunc +#ifndef NESTING + , NULL +#endif + ); #ifndef PROF if (__glibc_unlikely (consider_profiling) diff --git a/elf/do-rel.h b/elf/do-rel.h index 242ef95be2..548d99450c 100644 --- a/elf/do-rel.h +++ b/elf/do-rel.h @@ -41,7 +41,11 @@ auto inline void __attribute__ ((always_inline)) elf_dynamic_do_Rel (struct link_map *map, ElfW(Addr) reladdr, ElfW(Addr) relsize, __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative, - int lazy, int skip_ifunc) + int lazy, int skip_ifunc +#ifndef NESTING + , struct link_map *boot_map +#endif + ) { const ElfW(Rel) *r = (const void *) reladdr; const ElfW(Rel) *end = (const void *) (reladdr + relsize); @@ -136,7 +140,11 @@ elf_dynamic_do_Rel (struct link_map *map, ElfW(Half) ndx = version[ELFW(R_SYM) (r->r_info)] & 0x7fff; elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], &map->l_versions[ndx], - (void *) (l_addr + r->r_offset), skip_ifunc); + (void *) (l_addr + r->r_offset), skip_ifunc +#ifndef NESTING + , boot_map +#endif + ); } #if defined ELF_MACHINE_IRELATIVE && !defined RTLD_BOOTSTRAP @@ -150,7 +158,11 @@ elf_dynamic_do_Rel (struct link_map *map, &symtab[ELFW(R_SYM) (r2->r_info)], &map->l_versions[ndx], (void *) (l_addr + r2->r_offset), - skip_ifunc); + skip_ifunc +#ifndef NESTING + , boot_map +#endif + ); } #endif } @@ -168,7 +180,11 @@ elf_dynamic_do_Rel (struct link_map *map, else # endif elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL, - (void *) (l_addr + r->r_offset), skip_ifunc); + (void *) (l_addr + r->r_offset), skip_ifunc +#ifndef NESTING + , boot_map +#endif + ); # ifdef ELF_MACHINE_IRELATIVE if (r2 != NULL) @@ -176,7 +192,11 @@ elf_dynamic_do_Rel (struct link_map *map, if (ELFW(R_TYPE) (r2->r_info) == ELF_MACHINE_IRELATIVE) elf_machine_rel (map, r2, &symtab[ELFW(R_SYM) (r2->r_info)], NULL, (void *) (l_addr + r2->r_offset), - skip_ifunc); + skip_ifunc +#ifndef NESTING + , boot_map +#endif + ); # endif } #endif diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h index 240ab4ad8e..56e28d152f 100644 --- a/elf/dynamic-link.h +++ b/elf/dynamic-link.h @@ -74,7 +74,11 @@ elf_machine_rel_relative (ElfW(Addr) l_addr, const ElfW(Rel) *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, int skip_ifunc); + void *const reloc_addr, int skip_ifunc +#ifndef NESTING + , struct link_map *boot_map +#endif + ); auto inline void __attribute__((always_inline)) elf_machine_rela_relative (ElfW(Addr) l_addr, const ElfW(Rela) *reloc, void *const reloc_addr); @@ -117,6 +121,60 @@ 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. */ +#ifndef NESTING +# define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel, boot_map) \ + do { \ + struct { ElfW(Addr) start, size; \ + __typeof (((ElfW(Dyn) *) 0)->d_un.d_val) nrelative; int lazy; } \ + ranges[2] = { { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }; \ + \ + if ((map)->l_info[DT_##RELOC]) \ + { \ + ranges[0].start = D_PTR ((map), l_info[DT_##RELOC]); \ + ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val; \ + if (map->l_info[VERSYMIDX (DT_##RELOC##COUNT)] != NULL) \ + ranges[0].nrelative \ + = map->l_info[VERSYMIDX (DT_##RELOC##COUNT)]->d_un.d_val; \ + } \ + if ((map)->l_info[DT_PLTREL] \ + && (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \ + { \ + ElfW(Addr) start = D_PTR ((map), l_info[DT_JMPREL]); \ + ElfW(Addr) size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val; \ + \ + if (ranges[0].start + ranges[0].size == (start + size)) \ + ranges[0].size -= size; \ + if (ELF_DURING_STARTUP \ + || (!(do_lazy) \ + && (ranges[0].start + ranges[0].size) == start)) \ + { \ + /* Combine processing the sections. */ \ + ranges[0].size += size; \ + } \ + else \ + { \ + ranges[1].start = start; \ + ranges[1].size = size; \ + ranges[1].lazy = (do_lazy); \ + } \ + } \ + \ + if (ELF_DURING_STARTUP) \ + elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, \ + ranges[0].nrelative, 0, skip_ifunc, boot_map); \ + else \ + { \ + int ranges_index; \ + for (ranges_index = 0; ranges_index < 2; ++ranges_index) \ + elf_dynamic_do_##reloc ((map), \ + ranges[ranges_index].start, \ + ranges[ranges_index].size, \ + ranges[ranges_index].nrelative, \ + ranges[ranges_index].lazy, \ + skip_ifunc, boot_map); \ + } \ + } while (0) +#else /* NESTING */ # define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, skip_ifunc, test_rel) \ do { \ struct { ElfW(Addr) start, size; \ @@ -169,6 +227,7 @@ elf_machine_lazy_rel (struct link_map *map, skip_ifunc); \ } \ } while (0) +#endif /* NESTING */ # if ELF_MACHINE_NO_REL || ELF_MACHINE_NO_RELA # define _ELF_CHECK_REL 0 @@ -176,6 +235,34 @@ elf_machine_lazy_rel (struct link_map *map, # define _ELF_CHECK_REL 1 # endif +#ifndef NESTING +# if ! ELF_MACHINE_NO_REL +# include "do-rel.h" +# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc, boot_map) \ + _ELF_DYNAMIC_DO_RELOC (REL, Rel, map, lazy, skip_ifunc, _ELF_CHECK_REL, boot_map) +# else +# define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc, boot_map) /* 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, boot_map) \ + _ELF_DYNAMIC_DO_RELOC (RELA, Rela, map, lazy, skip_ifunc, _ELF_CHECK_REL, boot_map) +# else +# define ELF_DYNAMIC_DO_RELA(map, lazy, skip_ifunc, boot_map) /* 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, boot_map) \ + do { \ + int edr_lazy = elf_machine_runtime_setup ((map), (lazy), \ + (consider_profile)); \ + ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc, boot_map); \ + ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc, boot_map); \ + } while (0) +#else /* NESTING */ # if ! ELF_MACHINE_NO_REL # include "do-rel.h" # define ELF_DYNAMIC_DO_REL(map, lazy, skip_ifunc) \ @@ -202,5 +289,6 @@ elf_machine_lazy_rel (struct link_map *map, ELF_DYNAMIC_DO_REL ((map), edr_lazy, skip_ifunc); \ ELF_DYNAMIC_DO_RELA ((map), edr_lazy, skip_ifunc); \ } while (0) +#endif /* NESTING */ #endif diff --git a/elf/rtld.c b/elf/rtld.c index 75c740e34e..631021d73e 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -444,7 +444,6 @@ _dl_start_final (void *arg, struct dl_start_final_info *info) #ifdef DONT_USE_BOOTSTRAP_MAP # define bootstrap_map GL(dl_rtld_map) #else -struct dl_start_final_info info; # define bootstrap_map info.l #endif @@ -460,7 +459,11 @@ struct dl_start_final_info info; static ElfW(Addr) __attribute_used__ _dl_start (void *arg) { -#ifdef NESTING +#ifndef NESTING +#ifndef DONT_USE_BOOTSTRAP_MAP + struct dl_start_final_info info; +#endif /* DUBM */ +#else /* NESTING */ #ifdef DONT_USE_BOOTSTRAP_MAP # define bootstrap_map GL(dl_rtld_map) #else @@ -522,7 +525,11 @@ _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, 0, 0, 0 +#ifndef NESTING + , &bootstrap_map +#endif + ); } bootstrap_map.l_relocated = 1; diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h index bc8bd0230e..20e045bdb0 100644 --- a/sysdeps/powerpc/powerpc64/dl-machine.h +++ b/sysdeps/powerpc/powerpc64/dl-machine.h @@ -684,7 +684,11 @@ elf_machine_rela (struct link_map *map, const Elf64_Sym *sym, const struct r_found_version *version, void *const reloc_addr_arg, - int skip_ifunc) + int skip_ifunc +#ifndef NESTING + , struct link_map *boot_map +#endif + ) { Elf64_Addr *const reloc_addr = reloc_addr_arg; const int r_type = ELF64_R_TYPE (reloc->r_info); @@ -707,7 +711,11 @@ 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. */ +#if !defined NESTING && defined RTLD_BOOTSTRAP + struct link_map *sym_map = boot_map; +#else struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); +#endif Elf64_Addr value = SYMBOL_ADDRESS (sym_map, sym, true) + reloc->r_addend; if (sym != NULL diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h index d10e08a87d..c26d1b6481 100644 --- a/sysdeps/x86_64/dl-machine.h +++ b/sysdeps/x86_64/dl-machine.h @@ -267,7 +267,11 @@ 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) + void *const reloc_addr_arg, int skip_ifunc +#ifndef NESTING + , struct link_map *boot_map +#endif + ) { ElfW(Addr) *const reloc_addr = reloc_addr_arg; const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info); @@ -305,7 +309,11 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc, # ifndef RTLD_BOOTSTRAP const ElfW(Sym) *const refsym = sym; # endif +#if !defined NESTING && defined RTLD_BOOTSTRAP + struct link_map *sym_map = boot_map; +#else struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type); +#endif ElfW(Addr) value = SYMBOL_ADDRESS (sym_map, sym, true); if (sym != NULL |