about summary refs log tree commit diff
path: root/elf/rtld.c
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2023-11-27 11:28:13 +0100
committerFlorian Weimer <fweimer@redhat.com>2023-11-27 11:28:13 +0100
commit78ca44da0160a0b442f0ca1f253e3360f044b2ec (patch)
tree248cff1b3dc9e22595ad4d9871598bf6bd389c74 /elf/rtld.c
parenta74c2e1cbc8673dd7e97aae2f2705392e2ccc3f6 (diff)
downloadglibc-78ca44da0160a0b442f0ca1f253e3360f044b2ec.tar.gz
glibc-78ca44da0160a0b442f0ca1f253e3360f044b2ec.tar.xz
glibc-78ca44da0160a0b442f0ca1f253e3360f044b2ec.zip
elf: Relocate libc.so early during startup and dlmopen (bug 31083)
This makes it more likely that objects without dependencies can
use IFUNC resolvers in libc.so.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>
Diffstat (limited to 'elf/rtld.c')
-rw-r--r--elf/rtld.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/elf/rtld.c b/elf/rtld.c
index 0553c05edb..19bedcd4a6 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -2272,11 +2272,17 @@ dl_main (const ElfW(Phdr) *phdr,
      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).  */
+     the dynamic linker out of order because it has no copy relocations.
+     Likewise for libc, which is relocated early to ensure that IFUNC
+     resolvers in libc work.  */
 
   int consider_profiling = GLRO(dl_profile) != NULL;
 
+  if (GL(dl_ns)[LM_ID_BASE].libc_map != NULL)
+    _dl_relocate_object (GL(dl_ns)[LM_ID_BASE].libc_map,
+			 GL(dl_ns)[LM_ID_BASE].libc_map->l_scope,
+			 GLRO(dl_lazy) ? RTLD_LAZY : 0, consider_profiling);
+
   /* If we are profiling we also must do lazy reloaction.  */
   GLRO(dl_lazy) |= consider_profiling;