public inbox for glibc-cvs@sourceware.org
help / color / mirror / Atom feed
* [glibc/maskray/nesting] elf: Avoid nested functions in the loader (aarch64, x86-64) [BZ #27220]
@ 2021-08-22 23:29 Fangrui Song
  0 siblings, 0 replies; only message in thread
From: Fangrui Song @ 2021-08-22 23:29 UTC (permalink / raw)
  To: glibc-cvs

https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=5544862ebedb02e75b6b333c2d44ad9eb51ea36e

commit 5544862ebedb02e75b6b333c2d44ad9eb51ea36e
Author: Fangrui Song <maskray@google.com>
Date:   Sun Aug 22 16:29:16 2021 -0700

    elf: Avoid nested functions in the loader (aarch64, x86-64) [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 CC=clang (which doesn't support the
    feature).
    
    To un-nest elf_machine_rela, the key idea is to pass the variable in
    the containing scope as an extra argument.
    Stan Shebs implemented this in the google/grte/v5-2.27/master branch.
    This patch squashes and cleans up the commits.
    
    This patch just fixes aarch64 and x86-64: they use the `#ifndef NESTING`
    branch to avoid nested functions. The `#ifdef NESTING` branch is used by
    all other ports whose dl-machine.h files haven't been migrated.
    
    For the time being, there is some duplicated code. `#ifdef NESTING`
    dispatches can be removed in the future when all arches are migrated.
    
    I can fix powerpc64, riscv, and other arches subsequently.
    Migrating all ports at once is just too risky. Also, appreciate help
    from arch maintainers.
    
    Tested on {aarch64,x86_64}-linux-gnu (!NESTING) and
    powerpc64le-linux-gnu (NESTING).

Diff:
---
 elf/dl-conflict.c            | 31 +++++++++++++-
 elf/dl-reloc-static-pie.c    | 15 ++++++-
 elf/dl-reloc.c               | 52 +++++++++++++++++++++++-
 elf/do-rel.h                 | 30 +++++++++++---
 elf/dynamic-link.h           | 97 +++++++++++++++++++++++++++++++++++++++++++-
 elf/get-dynamic-info.h       |  4 ++
 elf/rtld.c                   | 25 +++++++++++-
 sysdeps/aarch64/dl-machine.h |  6 ++-
 sysdeps/x86_64/dl-machine.h  |  9 +++-
 9 files changed, 256 insertions(+), 13 deletions(-)

diff --git a/elf/dl-conflict.c b/elf/dl-conflict.c
index 31a2f90770..24266b6029 100644
--- a/elf/dl-conflict.c
+++ b/elf/dl-conflict.c
@@ -27,6 +27,23 @@
 #include <sys/types.h>
 #include "dynamic-link.h"
 
+#ifndef NESTING
+    /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
+#define RESOLVE_MAP(ref, version, flags) (*ref = NULL, NULL)
+#define RESOLVE(ref, version, flags) (*ref = NULL, 0)
+#define RESOLVE_CONFLICT_FIND_MAP(map, r_offset) \
+  do {									      \
+    while ((resolve_conflict_map->l_map_end < (ElfW(Addr)) (r_offset))	      \
+	   || (resolve_conflict_map->l_map_start > (ElfW(Addr)) (r_offset)))  \
+      resolve_conflict_map = resolve_conflict_map->l_next;		      \
+									      \
+    (map) = resolve_conflict_map;					      \
+  } while (0)
+
+#include "dynamic-link.h"
+
+#endif /* NESTING */
+
 void
 _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
 		       ElfW(Rela) *conflictend)
@@ -39,6 +56,8 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
     /* Do the conflict relocation of the object and library GOT and other
        data.  */
 
+#ifdef NESTING
+
     /* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
 #define RESOLVE_MAP(ref, version, flags) (*ref = NULL, NULL)
 #define RESOLVE(ref, version, flags) (*ref = NULL, 0)
@@ -51,13 +70,19 @@ _dl_resolve_conflicts (struct link_map *l, ElfW(Rela) *conflict,
     (map) = resolve_conflict_map;					      \
   } while (0)
 
+#endif /* NESTING */
+
     /* Prelinking makes no sense for anything but the main namespace.  */
     assert (l->l_ns == LM_ID_BASE);
     struct link_map *resolve_conflict_map __attribute__ ((__unused__))
       = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
 
+#ifdef NESTING
+
 #include "dynamic-link.h"
 
+#endif /* NESTING */
+
     /* Override these, defined in dynamic-link.h.  */
 #undef CHECK_STATIC_TLS
 #define CHECK_STATIC_TLS(ref_map, sym_map) ((void) 0)
@@ -68,7 +93,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-static-pie.c b/elf/dl-reloc-static-pie.c
index d5bd2f31e9..0ab4613021 100644
--- a/elf/dl-reloc-static-pie.c
+++ b/elf/dl-reloc-static-pie.c
@@ -23,6 +23,13 @@
 #include <ldsodefs.h>
 #include "dynamic-link.h"
 
+#ifndef NESTING
+# define STATIC_PIE_BOOTSTRAP
+# define BOOTSTRAP_MAP (main_map)
+# define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
+# include "dynamic-link.h"
+#endif /* n NESTING */
+
 /* Relocate static executable with PIE.  */
 
 void
@@ -30,10 +37,12 @@ _dl_relocate_static_pie (void)
 {
   struct link_map *main_map = _dl_get_dl_main_map ();
 
+#ifdef NESTING
 # define STATIC_PIE_BOOTSTRAP
 # define BOOTSTRAP_MAP (main_map)
 # define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
 # include "dynamic-link.h"
+#endif /* NESTING */
 
   /* Figure out the run-time load address of static PIE.  */
   main_map->l_addr = elf_machine_load_address ();
@@ -48,7 +57,11 @@ _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, 0, 0, 0
+#ifndef NESTING
+                        , main_map
+#endif
+                        );
   main_map->l_relocated = 1;
 
   /* Initialize _r_debug.  */
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
index e13a672ade..1439858177 100644
--- a/elf/dl-reloc.c
+++ b/elf/dl-reloc.c
@@ -162,6 +162,42 @@ _dl_nothread_init_static_tls (struct link_map *map)
 }
 #endif /* !THREAD_GSCOPE_IN_TCB */
 
+#ifndef NESTING
+/* Used by RESOLVE_MAP. _dl_relocate_object is either called at init time or
+ * by dlopen with a global lock, so the variables cannot be accessed
+ * concurrently.  */
+static struct link_map *cur_l;
+static struct r_scope_elem **cur_scope;
+static const char *cur_strtab;
+
+/* This macro is used as a callback from the ELF_DYNAMIC_RELOCATE code.  */
+#define RESOLVE_MAP(ref, version, r_type) \
+    ({ struct link_map *l = cur_l;					      \
+      (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)		      \
+	 && elf_machine_type_class (r_type) == l->l_lookup_cache.type_class)  \
+	? (bump_num_cache_relocations (),				      \
+	   (*ref) = l->l_lookup_cache.ret,				      \
+	   l->l_lookup_cache.value)					      \
+	: ({ lookup_t _lr;						      \
+	     int _tc = elf_machine_type_class (r_type);			      \
+	     l->l_lookup_cache.type_class = _tc;			      \
+	     l->l_lookup_cache.sym = (*ref);				      \
+	     const struct r_found_version *v = NULL;			      \
+	     if ((version) != NULL && (version)->hash != 0)		      \
+	       v = (version);						      \
+	     _lr = _dl_lookup_symbol_x (cur_strtab + (*ref)->st_name, l,      \
+					(ref), cur_scope, v, _tc,	      \
+					DL_LOOKUP_ADD_DEPENDENCY, NULL);      \
+	     l->l_lookup_cache.ret = (*ref);				      \
+	     l->l_lookup_cache.value = _lr; }))				      \
+     : l; })
+
+#include "dynamic-link.h"
+
+#endif /* n NESTING */
+
 void
 _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
 		     int reloc_mode, int consider_profiling)
@@ -243,6 +279,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
   {
     /* Do the actual relocation of the object's GOT and other data.  */
 
+#ifdef NESTING
+
     /* String table object symbols.  */
     const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
 
@@ -272,7 +310,19 @@ _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);
+#else /* n NESTING */
+
+    cur_l = l;
+    cur_scope = scope;
+    cur_strtab = (const void *) D_PTR (cur_l, l_info[DT_STRTAB]);
+
+#endif /* n NESTING */
+
+    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 321ac2b359..401a6340c8 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 3eb24ba3a6..2645d6e371 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -16,6 +16,13 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#if defined __aarch64__ || defined __x86_64__
+# define auto static
+#else
+/* Other arches use nested functions.  */
+# define NESTING
+#endif
+
 /* This macro is used as a callback from elf_machine_rel{a,} when a
    static TLS reloc is about to be performed.  Since (in dl-load.c) we
    permit dynamic loading of objects that might use such relocs, we
@@ -71,7 +78,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);
@@ -114,6 +125,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;					      \
@@ -166,6 +231,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
@@ -173,6 +239,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) \
@@ -199,5 +293,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/get-dynamic-info.h b/elf/get-dynamic-info.h
index d8ec32377d..546846cd9c 100644
--- a/elf/get-dynamic-info.h
+++ b/elf/get-dynamic-info.h
@@ -19,6 +19,7 @@
 /* This file is included multiple times and therefore lacks a header
    file inclusion guard.  */
 
+#if defined NESTING || !defined _GET_DYNAMIC_INFO_H
 #include <assert.h>
 #include <libc-diag.h>
 
@@ -180,3 +181,6 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
     info[DT_RPATH] = NULL;
 #endif
 }
+
+#define _GET_DYNAMIC_INFO_H
+#endif
diff --git a/elf/rtld.c b/elf/rtld.c
index 878e6480f4..2dc3f210e4 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -499,9 +499,26 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
   return start_addr;
 }
 
+#ifndef NESTING
+#ifdef DONT_USE_BOOTSTRAP_MAP
+# define bootstrap_map GL(dl_rtld_map)
+#else
+# define bootstrap_map info.l
+#endif
+
+  /* This #define produces dynamic linking inline functions for
+     bootstrap relocation instead of general-purpose relocation.
+     Since ld.so must not have any undefined symbols the result
+     is trivial: always the map of ld.so itself.  */
+#define RTLD_BOOTSTRAP
+#define RESOLVE_MAP(sym, version, flags) (&bootstrap_map)
+#include "dynamic-link.h"
+#endif /* n NESTING */
+
 static ElfW(Addr) __attribute_used__
 _dl_start (void *arg)
 {
+#ifdef NESTING
 #ifdef DONT_USE_BOOTSTRAP_MAP
 # define bootstrap_map GL(dl_rtld_map)
 #else
@@ -517,10 +534,12 @@ _dl_start (void *arg)
 #define BOOTSTRAP_MAP (&bootstrap_map)
 #define RESOLVE_MAP(sym, version, flags) BOOTSTRAP_MAP
 #include "dynamic-link.h"
+#endif /* NESTING */
 
 #ifdef DONT_USE_BOOTSTRAP_MAP
   rtld_timer_start (&start_time);
 #else
+  struct dl_start_final_info info;
   rtld_timer_start (&info.start_time);
 #endif
 
@@ -561,7 +580,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/aarch64/dl-machine.h b/sysdeps/aarch64/dl-machine.h
index 3e10cb462f..417633812b 100644
--- a/sysdeps/aarch64/dl-machine.h
+++ b/sysdeps/aarch64/dl-machine.h
@@ -241,7 +241,7 @@ 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, struct link_map *boot_map)
 {
   ElfW(Addr) *const reloc_addr = reloc_addr_arg;
   const unsigned int r_type = ELFW (R_TYPE) (reloc->r_info);
@@ -253,7 +253,11 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
   else
     {
       const ElfW(Sym) *const refsym = sym;
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_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
diff --git a/sysdeps/x86_64/dl-machine.h b/sysdeps/x86_64/dl-machine.h
index ceee50734e..95fd72c160 100644
--- a/sysdeps/x86_64/dl-machine.h
+++ b/sysdeps/x86_64/dl-machine.h
@@ -255,7 +255,7 @@ 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, struct link_map *boot_map)
 {
   ElfW(Addr) *const reloc_addr = reloc_addr_arg;
   const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info);
@@ -293,7 +293,11 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
 # ifndef RTLD_BOOTSTRAP
       const ElfW(Sym) *const refsym = sym;
 # endif
+#if defined RTLD_BOOTSTRAP || defined STATIC_PIE_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
@@ -573,7 +577,8 @@ 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, reloc, sym, version, reloc_addr, skip_ifunc,
+                        NULL);
     }
   else if (__glibc_unlikely (r_type == R_X86_64_IRELATIVE))
     {


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-08-22 23:29 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-22 23:29 [glibc/maskray/nesting] elf: Avoid nested functions in the loader (aarch64, x86-64) [BZ #27220] Fangrui Song

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).