summary refs log tree commit diff
path: root/elf/dynamic-link.h
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2003-05-20 22:36:38 +0000
committerUlrich Drepper <drepper@redhat.com>2003-05-20 22:36:38 +0000
commit479aa8ecb2e64cb2bd70be3c258d42541d916291 (patch)
treed2aea9ae224c07dfe9580ba7069207103e1997e3 /elf/dynamic-link.h
parentfddfebbd1064dec313891ad91dd9ca6e92e622ec (diff)
downloadglibc-479aa8ecb2e64cb2bd70be3c258d42541d916291.tar.gz
glibc-479aa8ecb2e64cb2bd70be3c258d42541d916291.tar.xz
glibc-479aa8ecb2e64cb2bd70be3c258d42541d916291.zip
Update.Update.
2003-05-20  Jakub Jelinek  <jakub@redhat.com>

	* elf/dynamic-link.h (elf_get_dynamic_info): Add temp argument.
	If temp != NULL, copy dynamic entries which need relocation to temp
	array before relocating.
	(DL_RO_DYN_TEMP_CNT): Define.
	* elf/dl-load.c (_dl_map_object_from_fd): Adjust caller.
	* elf/rtld.c (_dl_start): Likewise.
	(dl_main): Likewise.  Add dyn_temp static variable.
Diffstat (limited to 'elf/dynamic-link.h')
-rw-r--r--elf/dynamic-link.h47
1 files changed, 30 insertions, 17 deletions
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index 63adfcb802..5bf3f6f0f6 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -56,7 +56,7 @@ elf_machine_lazy_rel (struct link_map *map,
 /* Read the dynamic section at DYN and fill in INFO with indices DT_*.  */
 
 static inline void __attribute__ ((unused, always_inline))
-elf_get_dynamic_info (struct link_map *l)
+elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
 {
   ElfW(Dyn) *dyn = l->l_ld;
   ElfW(Dyn) **info;
@@ -88,32 +88,45 @@ elf_get_dynamic_info (struct link_map *l)
 	     + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn;
       ++dyn;
     }
+
+#define DL_RO_DYN_TEMP_CNT	8
+
 #ifndef DL_RO_DYN_SECTION
   /* Don't adjust .dynamic unnecessarily.  */
   if (l->l_addr != 0)
     {
       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;				      \
+	  }								      \
+      while (0)
 
-      if (info[DT_HASH] != NULL)
-	info[DT_HASH]->d_un.d_ptr += l_addr;
-      if (info[DT_PLTGOT] != NULL)
-	info[DT_PLTGOT]->d_un.d_ptr += l_addr;
-      if (info[DT_STRTAB] != NULL)
-	info[DT_STRTAB]->d_un.d_ptr += l_addr;
-      if (info[DT_SYMTAB] != NULL)
-	info[DT_SYMTAB]->d_un.d_ptr += l_addr;
+      ADJUST_DYN_INFO (DT_HASH);
+      ADJUST_DYN_INFO (DT_PLTGOT);
+      ADJUST_DYN_INFO (DT_STRTAB);
+      ADJUST_DYN_INFO (DT_SYMTAB);
 # if ! ELF_MACHINE_NO_RELA
-      if (info[DT_RELA] != NULL)
-	info[DT_RELA]->d_un.d_ptr += l_addr;
+      ADJUST_DYN_INFO (DT_RELA);
 # endif
 # if ! ELF_MACHINE_NO_REL
-      if (info[DT_REL] != NULL)
-	info[DT_REL]->d_un.d_ptr += l_addr;
+      ADJUST_DYN_INFO (DT_REL);
 # endif
-      if (info[DT_JMPREL] != NULL)
-	info[DT_JMPREL]->d_un.d_ptr += l_addr;
-      if (info[VERSYMIDX (DT_VERSYM)] != NULL)
-	info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr += l_addr;
+      ADJUST_DYN_INFO (DT_JMPREL);
+      ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
+# undef ADJUST_DYN_INFO
+      assert (cnt <= DL_RO_DYN_TEMP_CNT);
     }
 #endif
   if (info[DT_PLTREL] != NULL)