diff mbox series

[v2,1/4] elf: rtld_multiple_ref is always true

Message ID 761b0a8ec6b348c0c8524990d956639867b22183.1730374087.git.fweimer@redhat.com
State New
Headers show
Series elf: More careful placement of the main malloc switch | expand

Commit Message

Florian Weimer Oct. 31, 2024, 4:09 p.m. UTC
For a long time, libc.so.6 has dependend on ld.so, which
means that there is a reference to ld.so in all processes,
and rtld_multiple_ref is always true.  In fact, if
rtld_multiple_ref were false, some of the ld.so setup code
would not run.

Reviewed-by: DJ Delorie <dj@redhat.com>
---
 elf/rtld.c | 104 +++++++++++++++++++++++++----------------------------
 1 file changed, 48 insertions(+), 56 deletions(-)
diff mbox series

Patch

diff --git a/elf/rtld.c b/elf/rtld.c
index cb6199aa61..dcd0f4cdc6 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -1963,43 +1963,37 @@  dl_main (const ElfW(Phdr) *phdr,
     if (main_map->l_searchlist.r_list[i] == &GL(dl_rtld_map))
       break;
 
-  bool rtld_multiple_ref = false;
-  if (__glibc_likely (i < main_map->l_searchlist.r_nlist))
-    {
-      /* Some DT_NEEDED entry referred to the interpreter object itself, so
-	 put it back in the list of visible objects.  We insert it into the
-	 chain in symbol search order because gdb uses the chain's order as
-	 its symbol search order.  */
-      rtld_multiple_ref = true;
+  /* Insert the link map for the dynamic loader into the chain in
+     symbol search order because gdb uses the chain's order as its
+     symbol search order.  */
 
-      GL(dl_rtld_map).l_prev = main_map->l_searchlist.r_list[i - 1];
-      if (__glibc_likely (state.mode == rtld_mode_normal))
-	{
-	  GL(dl_rtld_map).l_next = (i + 1 < main_map->l_searchlist.r_nlist
-				    ? main_map->l_searchlist.r_list[i + 1]
-				    : NULL);
+  GL(dl_rtld_map).l_prev = main_map->l_searchlist.r_list[i - 1];
+  if (__glibc_likely (state.mode == rtld_mode_normal))
+    {
+      GL(dl_rtld_map).l_next = (i + 1 < main_map->l_searchlist.r_nlist
+				? main_map->l_searchlist.r_list[i + 1]
+				: NULL);
 #ifdef NEED_DL_SYSINFO_DSO
-	  if (GLRO(dl_sysinfo_map) != NULL
-	      && GL(dl_rtld_map).l_prev->l_next == GLRO(dl_sysinfo_map)
-	      && GL(dl_rtld_map).l_next != GLRO(dl_sysinfo_map))
-	    GL(dl_rtld_map).l_prev = GLRO(dl_sysinfo_map);
+      if (GLRO(dl_sysinfo_map) != NULL
+	  && GL(dl_rtld_map).l_prev->l_next == GLRO(dl_sysinfo_map)
+	  && GL(dl_rtld_map).l_next != GLRO(dl_sysinfo_map))
+	GL(dl_rtld_map).l_prev = GLRO(dl_sysinfo_map);
 #endif
-	}
-      else
-	/* In trace mode there might be an invisible object (which we
-	   could not find) after the previous one in the search list.
-	   In this case it doesn't matter much where we put the
-	   interpreter object, so we just initialize the list pointer so
-	   that the assertion below holds.  */
-	GL(dl_rtld_map).l_next = GL(dl_rtld_map).l_prev->l_next;
-
-      assert (GL(dl_rtld_map).l_prev->l_next == GL(dl_rtld_map).l_next);
-      GL(dl_rtld_map).l_prev->l_next = &GL(dl_rtld_map);
-      if (GL(dl_rtld_map).l_next != NULL)
-	{
-	  assert (GL(dl_rtld_map).l_next->l_prev == GL(dl_rtld_map).l_prev);
-	  GL(dl_rtld_map).l_next->l_prev = &GL(dl_rtld_map);
-	}
+    }
+  else
+    /* In trace mode there might be an invisible object (which we
+       could not find) after the previous one in the search list.
+       In this case it doesn't matter much where we put the
+       interpreter object, so we just initialize the list pointer so
+       that the assertion below holds.  */
+    GL(dl_rtld_map).l_next = GL(dl_rtld_map).l_prev->l_next;
+
+  assert (GL(dl_rtld_map).l_prev->l_next == GL(dl_rtld_map).l_next);
+  GL(dl_rtld_map).l_prev->l_next = &GL(dl_rtld_map);
+  if (GL(dl_rtld_map).l_next != NULL)
+    {
+      assert (GL(dl_rtld_map).l_next->l_prev == GL(dl_rtld_map).l_prev);
+      GL(dl_rtld_map).l_next->l_prev = &GL(dl_rtld_map);
     }
 
   /* Now let us see whether all libraries are available in the
@@ -2327,35 +2321,33 @@  dl_main (const ElfW(Phdr) *phdr,
   /* Make sure no new search directories have been added.  */
   assert (GLRO(dl_init_all_dirs) == GL(dl_all_dirs));
 
-  if (rtld_multiple_ref)
-    {
-      /* There was an explicit ref to the dynamic linker as a shared lib.
-	 Re-relocate ourselves with user-controlled symbol definitions.
+  /* Re-relocate ourselves with user-controlled symbol definitions.
 
-	 We must do this after TLS initialization in case after this
-	 re-relocation, we might call a user-supplied function
-	 (e.g. calloc from _dl_relocate_object) that uses TLS data.  */
+     We must do this after TLS initialization in case after this
+     re-relocation, we might call a user-supplied function
+     (e.g. calloc from _dl_relocate_object) that uses TLS data.  */
 
-      /* Set up the object lookup structures.  */
-      _dl_find_object_init ();
+  /* Set up the object lookup structures.  */
+  _dl_find_object_init ();
 
-      /* The malloc implementation has been relocated, so resolving
-	 its symbols (and potentially calling IFUNC resolvers) is safe
-	 at this point.  */
-      __rtld_malloc_init_real (main_map);
+  /* The malloc implementation has been relocated, so resolving
+     its symbols (and potentially calling IFUNC resolvers) is safe
+     at this point.  */
+  __rtld_malloc_init_real (main_map);
 
-      /* Likewise for the locking implementation.  */
-      __rtld_mutex_init ();
+  /* Likewise for the locking implementation.  */
+  __rtld_mutex_init ();
 
-      RTLD_TIMING_VAR (start);
-      rtld_timer_start (&start);
+  {
+    RTLD_TIMING_VAR (start);
+    rtld_timer_start (&start);
 
-      /* Mark the link map as not yet relocated again.  */
-      GL(dl_rtld_map).l_relocated = 0;
-      _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0);
+    /* Mark the link map as not yet relocated again.  */
+    GL(dl_rtld_map).l_relocated = 0;
+    _dl_relocate_object (&GL(dl_rtld_map), main_map->l_scope, 0, 0);
 
-      rtld_timer_accum (&relocate_time, start);
-    }
+    rtld_timer_accum (&relocate_time, start);
+  }
 
   /* Relocation is complete.  Perform early libc initialization.  This
      is the initial libc, even if audit modules have been loaded with