]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Change de-nesting fix to use added argument instead of globals
authorStan Shebs <stanshebs@google.com>
Fri, 14 Sep 2018 17:21:15 +0000 (10:21 -0700)
committerFangrui Song <i@maskray.me>
Sat, 28 Aug 2021 00:23:12 +0000 (17:23 -0700)
elf/dl-conflict.c
elf/dl-reloc.c
elf/do-rel.h
elf/dynamic-link.h
elf/rtld.c
sysdeps/powerpc/powerpc64/dl-machine.h
sysdeps/x86_64/dl-machine.h

index 18e8f2edbc2c8724d32f06322e980d1239eea2eb..be2a4e5545d7694513dff53fa047edd706423c18 100644 (file)
@@ -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
 }
index 1625f35d1bf6813e908fc838adfdc5d5834a1d28..9f743f56f051b17abb6a5869ef845d03f6ce8140 100644 (file)
@@ -349,7 +349,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)
index 19cb5d236ee306986b32593e02038d64cb2377d5..e87bd4c4c2e0e1bafdad2b4b8de773ad7820bbe2 100644 (file)
@@ -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
index 628df10739074046f3f70772a38da194413a236a..f576d787e3c9bf9bf47684cacaf8577c2cbc47ed 100644 (file)
@@ -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
index f4e382d9c7afe20234289dacf894f4a651bfd977..9468cd60d9496c9130d50e2e1e402c710e223171 100644 (file)
@@ -458,7 +458,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
 
@@ -474,7 +473,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
@@ -536,7 +539,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;
 
index 7ca81f3e7029e70aa99a8f5dd07cc2d0bd6538e4..da07609778282b07f3cbb58ddbad4b09e74cc405 100644 (file)
@@ -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 = ((sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value)
                      + reloc->r_addend);
 
index f525600071f0693fc11ee0c7891a5302c8dc3a35..ea9a2366b2c2782c1a388c7e0fb5913d1257550a 100644 (file)
@@ -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 = (sym == NULL ? 0
                          : (ElfW(Addr)) sym_map->l_addr + sym->st_value);