about summary refs log tree commit diff
path: root/elf/get-dynamic-info.h
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2021-09-16 08:15:29 -0700
committerH.J. Lu <hjl.tools@gmail.com>2021-09-22 11:12:43 -0700
commitb413280cfb16834450f66f554bc0d618bb513851 (patch)
treefda69976f225c3085c1da42c9b9ab191fae6f61f /elf/get-dynamic-info.h
parent4eff749e8f06d8f6c5fc8b37299e9e0409ed80ec (diff)
downloadglibc-b413280cfb16834450f66f554bc0d618bb513851.tar.gz
glibc-b413280cfb16834450f66f554bc0d618bb513851.tar.xz
glibc-b413280cfb16834450f66f554bc0d618bb513851.zip
ld.so: Replace DL_RO_DYN_SECTION with dl_relocate_ld [BZ #28340]
We can't relocate entries in dynamic section if it is readonly:

1. Add a l_ld_readonly field to struct link_map to indicate if dynamic
section is readonly and set it based on p_flags of PT_DYNAMIC segment.
2. Replace DL_RO_DYN_SECTION with dl_relocate_ld to decide if dynamic
section should be relocated.
3. Remove DL_RO_DYN_TEMP_CNT.
4. Don't use a static dynamic section to make readonly dynamic section
in vDSO writable.
5. Remove the temp argument from elf_get_dynamic_info.

This fixes BZ #28340.

Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Diffstat (limited to 'elf/get-dynamic-info.h')
-rw-r--r--elf/get-dynamic-info.h21
1 files changed, 3 insertions, 18 deletions
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
index d8ec32377d..4aa2058abf 100644
--- a/elf/get-dynamic-info.h
+++ b/elf/get-dynamic-info.h
@@ -28,7 +28,7 @@ static
 auto
 #endif
 inline void __attribute__ ((unused, always_inline))
-elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
+elf_get_dynamic_info (struct link_map *l)
 {
 #if __ELF_NATIVE_CLASS == 32
   typedef Elf32_Word d_tag_utype;
@@ -69,28 +69,15 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
       info[i] = dyn;
     }
 
-#define DL_RO_DYN_TEMP_CNT	8
-
-#ifndef DL_RO_DYN_SECTION
   /* Don't adjust .dynamic unnecessarily.  */
-  if (l->l_addr != 0)
+  if (l->l_addr != 0 && dl_relocate_ld (l))
     {
       ElfW(Addr) l_addr = l->l_addr;
-      int cnt = 0;
 
 # define ADJUST_DYN_INFO(tag) \
       do								      \
 	if (info[tag] != NULL)						      \
-	  {								      \
-	    if (temp)							      \
-	      {								      \
-		temp[cnt].d_tag = info[tag]->d_tag;			      \
-		temp[cnt].d_un.d_ptr = info[tag]->d_un.d_ptr + l_addr;	      \
-		info[tag] = temp + cnt++;				      \
-	      }								      \
-	    else							      \
-	      info[tag]->d_un.d_ptr += l_addr;				      \
-	  }								      \
+         info[tag]->d_un.d_ptr += l_addr;				      \
       while (0)
 
       ADJUST_DYN_INFO (DT_HASH);
@@ -107,9 +94,7 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
       ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
       ADJUST_DYN_INFO (ADDRIDX (DT_GNU_HASH));
 # undef ADJUST_DYN_INFO
-      assert (cnt <= DL_RO_DYN_TEMP_CNT);
     }
-#endif
   if (info[DT_PLTREL] != NULL)
     {
 #if ELF_MACHINE_NO_RELA