about summary refs log tree commit diff
path: root/elf/rtld.c
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2022-01-13 17:58:00 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2022-02-10 09:16:12 -0300
commit6628c742b2c16e785d3c884d9deeda5adb30ca12 (patch)
tree493580e40aef171896584e1d3d32bbe14c15140b /elf/rtld.c
parent8c8510ab2790039e58995ef3a22309582413d3ff (diff)
downloadglibc-6628c742b2c16e785d3c884d9deeda5adb30ca12.tar.gz
glibc-6628c742b2c16e785d3c884d9deeda5adb30ca12.tar.xz
glibc-6628c742b2c16e785d3c884d9deeda5adb30ca12.zip
elf: Remove prelink support
Prelinked binaries and libraries still work, the dynamic tags
DT_GNU_PRELINKED, DT_GNU_LIBLIST, DT_GNU_CONFLICT just ignored
(meaning the process is reallocated as default).

The loader environment variable TRACE_PRELINKING is also removed,
since it used solely on prelink.

Checked on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu.

Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Diffstat (limited to 'elf/rtld.c')
-rw-r--r--elf/rtld.c250
1 files changed, 50 insertions, 200 deletions
diff --git a/elf/rtld.c b/elf/rtld.c
index 8dafaf61f4..5f089038e1 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -565,7 +565,7 @@ _dl_start (void *arg)
   ELF_MACHINE_BEFORE_RTLD_RELOC (&bootstrap_map, bootstrap_map.l_info);
 #endif
 
-  if (bootstrap_map.l_addr || ! bootstrap_map.l_info[VALIDX(DT_GNU_PRELINKED)])
+  if (bootstrap_map.l_addr)
     {
       /* Relocate ourselves so we can do normal function calls and
 	 data access using the global offset table.  */
@@ -1322,7 +1322,6 @@ dl_main (const ElfW(Phdr) *phdr,
   size_t file_size;
   char *file;
   unsigned int i;
-  bool prelinked = false;
   bool rtld_is_main = false;
   void *tcbp = NULL;
 
@@ -2055,37 +2054,7 @@ dl_main (const ElfW(Phdr) *phdr,
 	 after relocation.  */
       struct link_map *l;
 
-      if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
-	{
-	  struct r_scope_elem *scope = &main_map->l_searchlist;
-
-	  for (i = 0; i < scope->r_nlist; i++)
-	    {
-	      l = scope->r_list [i];
-	      if (l->l_faked)
-		{
-		  _dl_printf ("\t%s => not found\n", l->l_libname->name);
-		  continue;
-		}
-	      if (_dl_name_match_p (GLRO(dl_trace_prelink), l))
-		GLRO(dl_trace_prelink_map) = l;
-	      _dl_printf ("\t%s => %s (0x%0*Zx, 0x%0*Zx)",
-			  DSO_FILENAME (l->l_libname->name),
-			  DSO_FILENAME (l->l_name),
-			  (int) sizeof l->l_map_start * 2,
-			  (size_t) l->l_map_start,
-			  (int) sizeof l->l_addr * 2,
-			  (size_t) l->l_addr);
-
-	      if (l->l_tls_modid)
-		_dl_printf (" TLS(0x%Zx, 0x%0*Zx)\n", l->l_tls_modid,
-			    (int) sizeof l->l_tls_offset * 2,
-			    (size_t) l->l_tls_offset);
-	      else
-		_dl_printf ("\n");
-	    }
-	}
-      else if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)
+      if (GLRO(dl_debug_mask) & DL_DEBUG_UNUSED)
 	{
 	  /* Look through the dependencies of the main executable
 	     and determine which of them is not actually
@@ -2193,14 +2162,6 @@ dl_main (const ElfW(Phdr) *phdr,
 		    }
 		}
 
-	      if ((GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
-		  && rtld_multiple_ref)
-		{
-		  /* 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, __RTLD_NOIFUNC, 0);
-		}
 	    }
 #define VERNEEDTAG (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (DT_VERNEED))
 	  if (state.version_info)
@@ -2277,61 +2238,6 @@ dl_main (const ElfW(Phdr) *phdr,
       _exit (0);
     }
 
-  if (main_map->l_info[ADDRIDX (DT_GNU_LIBLIST)]
-      && ! __builtin_expect (GLRO(dl_profile) != NULL, 0)
-      && ! __builtin_expect (GLRO(dl_dynamic_weak), 0))
-    {
-      ElfW(Lib) *liblist, *liblistend;
-      struct link_map **r_list, **r_listend, *l;
-      const char *strtab = (const void *) D_PTR (main_map, l_info[DT_STRTAB]);
-
-      assert (main_map->l_info[VALIDX (DT_GNU_LIBLISTSZ)] != NULL);
-      liblist = (ElfW(Lib) *)
-		main_map->l_info[ADDRIDX (DT_GNU_LIBLIST)]->d_un.d_ptr;
-      liblistend = (ElfW(Lib) *)
-		   ((char *) liblist
-		    + main_map->l_info[VALIDX (DT_GNU_LIBLISTSZ)]->d_un.d_val);
-      r_list = main_map->l_searchlist.r_list;
-      r_listend = r_list + main_map->l_searchlist.r_nlist;
-
-      for (; r_list < r_listend && liblist < liblistend; r_list++)
-	{
-	  l = *r_list;
-
-	  if (l == main_map)
-	    continue;
-
-	  /* If the library is not mapped where it should, fail.  */
-	  if (l->l_addr)
-	    break;
-
-	  /* Next, check if checksum matches.  */
-	  if (l->l_info [VALIDX(DT_CHECKSUM)] == NULL
-	      || l->l_info [VALIDX(DT_CHECKSUM)]->d_un.d_val
-		 != liblist->l_checksum)
-	    break;
-
-	  if (l->l_info [VALIDX(DT_GNU_PRELINKED)] == NULL
-	      || l->l_info [VALIDX(DT_GNU_PRELINKED)]->d_un.d_val
-		 != liblist->l_time_stamp)
-	    break;
-
-	  if (! _dl_name_match_p (strtab + liblist->l_name, l))
-	    break;
-
-	  ++liblist;
-	}
-
-
-      if (r_list == r_listend && liblist == liblistend)
-	prelinked = true;
-
-      if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS))
-	_dl_debug_printf ("\nprelink checking: %s\n",
-			  prelinked ? "ok" : "failed");
-    }
-
-
   /* Now set up the variable which helps the assembler startup code.  */
   GL(dl_ns)[LM_ID_BASE]._ns_main_searchlist = &main_map->l_searchlist;
 
@@ -2356,103 +2262,59 @@ dl_main (const ElfW(Phdr) *phdr,
 
   _rtld_main_check (main_map, _dl_argv[0]);
 
-  if (prelinked)
-    {
-      if (main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)] != NULL)
-	{
-	  ElfW(Rela) *conflict, *conflictend;
+  /* Now we have all the objects loaded.  Relocate them all except for
+     the dynamic linker itself.  We do this in reverse order so that copy
+     relocs of earlier objects overwrite the data written by later
+     objects.  We do not re-relocate the dynamic linker itself in this
+     loop because that could result in the GOT entries for functions we
+     call being changed, and that would break us.  It is safe to relocate
+     the dynamic linker out of order because it has no copy relocs (we
+     know that because it is self-contained).  */
 
-	  RTLD_TIMING_VAR (start);
-	  rtld_timer_start (&start);
+  int consider_profiling = GLRO(dl_profile) != NULL;
 
-	  assert (main_map->l_info [VALIDX (DT_GNU_CONFLICTSZ)] != NULL);
-	  conflict = (ElfW(Rela) *)
-	    main_map->l_info [ADDRIDX (DT_GNU_CONFLICT)]->d_un.d_ptr;
-	  conflictend = (ElfW(Rela) *)
-	    ((char *) conflict
-	     + main_map->l_info [VALIDX (DT_GNU_CONFLICTSZ)]->d_un.d_val);
-	  _dl_resolve_conflicts (main_map, conflict, conflictend);
-
-	  rtld_timer_stop (&relocate_time, start);
-	}
+  /* If we are profiling we also must do lazy reloaction.  */
+  GLRO(dl_lazy) |= consider_profiling;
 
-      /* Set up the object lookup structures.  */
-      _dl_find_object_init ();
-
-      /* The library defining malloc has already been relocated due to
-	 prelinking.  Resolve the malloc symbols for the dynamic
-	 loader.  */
-      __rtld_malloc_init_real (main_map);
-
-      /* Likewise for the locking implementation.  */
-      __rtld_mutex_init ();
-
-      /* Mark all the objects so we know they have been already relocated.  */
-      for (struct link_map *l = main_map; l != NULL; l = l->l_next)
-	{
-	  l->l_relocated = 1;
-	  if (l->l_relro_size)
-	    _dl_protect_relro (l);
-
-	  /* Add object to slot information data if necessasy.  */
-	  if (l->l_tls_blocksize != 0 && tls_init_tp_called)
-	    _dl_add_to_slotinfo (l, true);
-	}
-    }
-  else
-    {
-      /* Now we have all the objects loaded.  Relocate them all except for
-	 the dynamic linker itself.  We do this in reverse order so that copy
-	 relocs of earlier objects overwrite the data written by later
-	 objects.  We do not re-relocate the dynamic linker itself in this
-	 loop because that could result in the GOT entries for functions we
-	 call being changed, and that would break us.  It is safe to relocate
-	 the dynamic linker out of order because it has no copy relocs (we
-	 know that because it is self-contained).  */
-
-      int consider_profiling = GLRO(dl_profile) != NULL;
-
-      /* If we are profiling we also must do lazy reloaction.  */
-      GLRO(dl_lazy) |= consider_profiling;
+  RTLD_TIMING_VAR (start);
+  rtld_timer_start (&start);
+  {
+    unsigned i = main_map->l_searchlist.r_nlist;
+    while (i-- > 0)
+      {
+	struct link_map *l = main_map->l_initfini[i];
 
-      RTLD_TIMING_VAR (start);
-      rtld_timer_start (&start);
-      unsigned i = main_map->l_searchlist.r_nlist;
-      while (i-- > 0)
-	{
-	  struct link_map *l = main_map->l_initfini[i];
+	/* While we are at it, help the memory handling a bit.  We have to
+	   mark some data structures as allocated with the fake malloc()
+	   implementation in ld.so.  */
+	struct libname_list *lnp = l->l_libname->next;
 
-	  /* While we are at it, help the memory handling a bit.  We have to
-	     mark some data structures as allocated with the fake malloc()
-	     implementation in ld.so.  */
-	  struct libname_list *lnp = l->l_libname->next;
+	while (__builtin_expect (lnp != NULL, 0))
+	  {
+	    lnp->dont_free = 1;
+	    lnp = lnp->next;
+	  }
+	/* Also allocated with the fake malloc().  */
+	l->l_free_initfini = 0;
 
-	  while (__builtin_expect (lnp != NULL, 0))
-	    {
-	      lnp->dont_free = 1;
-	      lnp = lnp->next;
-	    }
-	  /* Also allocated with the fake malloc().  */
-	  l->l_free_initfini = 0;
+	if (l != &GL(dl_rtld_map))
+	  _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy) ? RTLD_LAZY : 0,
+			       consider_profiling);
 
-	  if (l != &GL(dl_rtld_map))
-	    _dl_relocate_object (l, l->l_scope, GLRO(dl_lazy) ? RTLD_LAZY : 0,
-				 consider_profiling);
+	/* Add object to slot information data if necessasy.  */
+	if (l->l_tls_blocksize != 0 && tls_init_tp_called)
+	  _dl_add_to_slotinfo (l, true);
+      }
+  }
+  rtld_timer_stop (&relocate_time, start);
 
-	  /* Add object to slot information data if necessasy.  */
-	  if (l->l_tls_blocksize != 0 && tls_init_tp_called)
-	    _dl_add_to_slotinfo (l, true);
-	}
-      rtld_timer_stop (&relocate_time, start);
-
-      /* Now enable profiling if needed.  Like the previous call,
-	 this has to go here because the calls it makes should use the
-	 rtld versions of the functions (particularly calloc()), but it
-	 needs to have _dl_profile_map set up by the relocator.  */
-      if (__glibc_unlikely (GL(dl_profile_map) != NULL))
-	/* We must prepare the profiling.  */
-	_dl_start_profile ();
-    }
+  /* Now enable profiling if needed.  Like the previous call,
+     this has to go here because the calls it makes should use the
+     rtld versions of the functions (particularly calloc()), but it
+     needs to have _dl_profile_map set up by the relocator.  */
+  if (__glibc_unlikely (GL(dl_profile_map) != NULL))
+    /* We must prepare the profiling.  */
+    _dl_start_profile ();
 
   if ((!was_tls_init_tp_called && GL(dl_tls_max_dtv_idx) > 0)
       || count_modids != _dl_count_modids ())
@@ -2478,7 +2340,7 @@ 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 (! prelinked && rtld_multiple_ref)
+  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.
@@ -2811,17 +2673,6 @@ process_envvars (struct dl_main_state *state)
 	    GLRO(dl_profile_output) = &envline[15];
 	  break;
 
-	case 16:
-	  /* The mode of the dynamic linker can be set.  */
-	  if (memcmp (envline, "TRACE_PRELINKING", 16) == 0)
-	    {
-	      state->mode = rtld_mode_trace;
-	      GLRO(dl_verbose) = 1;
-	      GLRO(dl_debug_mask) |= DL_DEBUG_PRELINK;
-	      GLRO(dl_trace_prelink) = &envline[17];
-	    }
-	  break;
-
 	case 20:
 	  /* The mode of the dynamic linker can be set.  */
 	  if (memcmp (envline, "TRACE_LOADED_OBJECTS", 20) == 0)
@@ -2955,9 +2806,8 @@ print_statistics (const hp_timing_t *rtld_total_timep)
 	      += l->l_info[VERSYMIDX (DT_RELCOUNT)]->d_un.d_val;
 #ifndef ELF_MACHINE_REL_RELATIVE
 	  /* Relative relocations are processed on these architectures if
-	     library is loaded to different address than p_vaddr or
-	     if not prelinked.  */
-	  if ((l->l_addr != 0 || !l->l_info[VALIDX(DT_GNU_PRELINKED)])
+	     library is loaded to different address than p_vaddr.  */
+	  if ((l->l_addr != 0)
 	      && l->l_info[VERSYMIDX (DT_RELACOUNT)])
 #else
 	  /* On e.g. IA-64 or Alpha, relative relocations are processed