about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--elf/do-rel.h7
-rw-r--r--elf/dynamic-link.h43
3 files changed, 40 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index ad0ff35235..cfedf5d48a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,12 @@
 2002-02-01  Ulrich Drepper  <drepper@redhat.com>
 
+	* elf/do-rel.h (elf_dynamic_do_rel): Help the compiler recognize
+	code which is never used when relocating ld.so itself.
+
 	* elf/dynamic-link.h (elf_get_dynamic_info): Optimize a bit for
 	starting ld.so itself.  Move l_addr variable initialization closer
 	to use.
+	(_ELF_DYNAMIC_DO_RELOC): Help the compiler optimize a bit.
 
 2002-02-01  Jakub Jelinek  <jakub@redhat.com>
 
diff --git a/elf/do-rel.h b/elf/do-rel.h
index 3968937093..5f07544369 100644
--- a/elf/do-rel.h
+++ b/elf/do-rel.h
@@ -98,7 +98,12 @@ elf_dynamic_do_rel (struct link_map *map,
 	    elf_machine_rel_relative (l_addr, relative,
 				      (void *) (l_addr + relative->r_offset));
 
+#ifdef RTLD_BOOTSTRAP
+      /* The dynamic linker always uses versioning.  */
+      assert (map->l_info[VERSYMIDX (DT_VERSYM)] != NULL);
+#else
       if (map->l_info[VERSYMIDX (DT_VERSYM)])
+#endif
 	{
 	  const ElfW(Half) *const version =
 	    (const void *) D_PTR (map, l_info[VERSYMIDX (DT_VERSYM)]);
@@ -111,10 +116,12 @@ elf_dynamic_do_rel (struct link_map *map,
 			       (void *) (l_addr + r->r_offset));
 	    }
 	}
+#ifndef RTLD_BOOTSTRAP
       else
 	for (; r < end; ++r)
 	  elf_machine_rel (map, r, &symtab[ELFW(R_SYM) (r->r_info)], NULL,
 			   (void *) (l_addr + r->r_offset));
+#endif
     }
 }
 
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index b0baa901fd..f3529970a1 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -141,6 +141,12 @@ elf_get_dynamic_info (struct link_map *l)
 
 #ifdef RESOLVE
 
+# ifdef RTLD_BOOTSTRAP
+#  define ELF_DURING_STARTUP (1)
+# else
+#  define ELF_DURING_STARTUP (0)
+# endif
+
 /* Get the definitions of `elf_dynamic_do_rel' and `elf_dynamic_do_rela'.
    These functions are almost identical, so we use cpp magic to avoid
    duplicating their code.  It cannot be done in a more general function
@@ -167,7 +173,7 @@ elf_get_dynamic_info (struct link_map *l)
 	ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val;	      \
       }									      \
 									      \
-     if ((do_lazy)							      \
+    if ((do_lazy)							      \
 	&& (map)->l_info[DT_PLTREL]					      \
 	&& (!test_rel || (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)) \
       {									      \
@@ -188,7 +194,6 @@ elf_get_dynamic_info (struct link_map *l)
 #  define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, do_lazy, test_rel) \
   do {									      \
     struct { ElfW(Addr) start, size; int lazy; } ranges[2];		      \
-    int ranges_index;							      \
     ranges[0].lazy = 0;							      \
     ranges[0].size = ranges[1].size = 0;				      \
     ranges[0].start = 0;						      \
@@ -203,26 +208,36 @@ elf_get_dynamic_info (struct link_map *l)
       {									      \
 	ElfW(Addr) start = D_PTR ((map), l_info[DT_JMPREL]);		      \
 									      \
-	if ((do_lazy)							      \
-	    /* This test does not only detect whether the relocation	      \
-	       sections are in the right order, it also checks whether	      \
-	       there is a DT_REL/DT_RELA section.  */			      \
-	    || ranges[0].start + ranges[0].size != start)		      \
+	if (! ELF_DURING_STARTUP					      \
+	    && ((do_lazy)						      \
+		/* This test does not only detect whether the relocation      \
+		   sections are in the right order, it also checks whether    \
+		   there is a DT_REL/DT_RELA section.  */		      \
+		|| ranges[0].start + ranges[0].size != start))		      \
 	  {								      \
 	    ranges[1].start = start;					      \
 	    ranges[1].size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val;	      \
 	    ranges[1].lazy = (do_lazy);					      \
 	  }								      \
 	else								      \
-	  /* Combine processing the sections.  */			      \
-	  ranges[0].size += (map)->l_info[DT_PLTRELSZ]->d_un.d_val;	      \
+	  {								      \
+	    /* Combine processing the sections.  */			      \
+	    assert (ranges[0].start + ranges[0].size == start);		      \
+	    ranges[0].size += (map)->l_info[DT_PLTRELSZ]->d_un.d_val;	      \
+	  }								      \
       }									      \
 									      \
-    for (ranges_index = 0; ranges_index < 2; ++ranges_index)		      \
-      elf_dynamic_do_##reloc ((map),					      \
-			      ranges[ranges_index].start,		      \
-			      ranges[ranges_index].size,		      \
-			      ranges[ranges_index].lazy);		      \
+    if (ELF_DURING_STARTUP)						      \
+      elf_dynamic_do_##reloc ((map), ranges[0].start, ranges[0].size, 0);     \
+    else								      \
+      {									      \
+	int ranges_index;						      \
+	for (ranges_index = 0; ranges_index < 2; ++ranges_index)	      \
+	  elf_dynamic_do_##reloc ((map),				      \
+				  ranges[ranges_index].start,		      \
+				  ranges[ranges_index].size,		      \
+				  ranges[ranges_index].lazy);		      \
+      }									      \
   } while (0)
 # endif