about summary refs log tree commit diff
path: root/elf/dynamic-link.h
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-09-01 14:31:49 +0000
committerUlrich Drepper <drepper@redhat.com>1998-09-01 14:31:49 +0000
commit052b6a6c94cc330dfbc09ff7b5f03c943deb7ca2 (patch)
tree0ef4d2730e6e20141e3b669b8a3614193200f3fc /elf/dynamic-link.h
parent85c165befc61d049abe3cc443c275a210c569338 (diff)
downloadglibc-052b6a6c94cc330dfbc09ff7b5f03c943deb7ca2.tar.gz
glibc-052b6a6c94cc330dfbc09ff7b5f03c943deb7ca2.tar.xz
glibc-052b6a6c94cc330dfbc09ff7b5f03c943deb7ca2.zip
Update.
1998-08-09  Geoff Keating  <geoffk@ozemail.com.au>

	* sysdeps/powerpc/Makefile [subdir=elf]: Add new files split out of
	dl-machine.h.
	* sysdeps/powerpc/dl-machine.c: New file.
	* sysdeps/powerpc/dl-machine.h: Move much stuff into separate
	files.  Revise ELF_PREFERRED_ADDRESS to take account of
	the new mapping information (fixes bug involving huge bloated
	web browser).  Set ELF_MACHINE_PLTREL_OVERLAP.
	* sysdeps/powerpc/dl-start.S: New file.

	* elf/dl-load.c (_dl_map_object_from_fd): Initialise l_map_start,
	l_map_end.
	* elf/do-rel.h: Call elf_machine_rel only once (to save space).
	* elf/dynamic-link.h: Allow PLT relocs to be in the middle of the
	others.  Call elf_dynamic_do_##reloc only once (to save even more
	space).
	* elf/link.h: Add new members l_map_start and l_map_end to keep
	track of the memory map.
	* elf/rtld.c (_dl_start): Initialise l_map_start for ld.so and
	the executable.

1998-09-01 11:53  Ulrich Drepper  <drepper@cygnus.com>

	* debug/Makefile (catchsegv): We need not rewrite SOVER anymore.
	Reported by Andreas Jaeger.

	* posix/glob.h: Use __size_t instead of size_t in definitions and
	make sure this is defined.

	* manual/locale.texi: Almost complete rewrite.  Document more functions
Diffstat (limited to 'elf/dynamic-link.h')
-rw-r--r--elf/dynamic-link.h91
1 files changed, 53 insertions, 38 deletions
diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
index 9d7ae3d3fa..9e2ca03543 100644
--- a/elf/dynamic-link.h
+++ b/elf/dynamic-link.h
@@ -83,60 +83,75 @@ elf_get_dynamic_info (ElfW(Dyn) *dyn,
 #ifdef ELF_MACHINE_PLTREL_OVERLAP
 #define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, lazy) \
   do {									      \
-    ElfW(Addr) r_addr, r_size, p_addr, p_size;				      \
+    struct { ElfW(Addr) start, size;  int lazy; } ranges[3];		      \
+    int ranges_index;							      \
+									      \
+    ranges[0].lazy = ranges[2].lazy = 0;				      \
+    ranges[1].lazy = 1;							      \
+    ranges[0].size = ranges[1].size = ranges[2].size = 0;		      \
+									      \
     if ((map)->l_info[DT_##RELOC])					      \
       {									      \
-        r_addr = (map)->l_info[DT_##RELOC]->d_un.d_ptr;			      \
-        r_size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val;		      \
-        if ((map)->l_info[DT_PLTREL] &&					      \
-            (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)		      \
-	  {								      \
-	    p_addr = (map)->l_info[DT_JMPREL]->d_un.d_ptr;		      \
-	    p_size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val;		      \
-	    if (r_addr <= p_addr && r_addr+r_size > p_addr)		      \
-	      {								      \
-		ElfW(Addr) r2_addr, r2_size;				      \
-		r2_addr = p_addr + p_size;				      \
-		if (r2_addr < r_addr + r_size)				      \
-		  {							      \
-		    r2_size = r_addr + r_size - r2_addr;		      \
-		    elf_dynamic_do_##reloc ((map), r2_addr, r2_size, 0);      \
-		  }							      \
-		r_size = p_addr - r_addr;				      \
-	      }								      \
-	  }								      \
-									      \
-	elf_dynamic_do_##reloc ((map), r_addr, r_size, 0);		      \
-	if (p_addr)							      \
-	  elf_dynamic_do_##reloc ((map), p_addr, p_size, (lazy));	      \
+	ranges[0].start = (map)->l_info[DT_##RELOC]->d_un.d_ptr;	      \
+	ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val;	      \
       }									      \
-    else if ((map)->l_info[DT_PLTREL] &&				      \
-	     (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)	      \
-      {									      \
-	p_addr = (map)->l_info[DT_JMPREL]->d_un.d_ptr;			      \
-	p_size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val;		      \
 									      \
-	elf_dynamic_do_##reloc ((map), p_addr, p_size, (lazy));		      \
+     if ((lazy)								      \
+	&& (map)->l_info[DT_PLTREL]					      \
+	&& (map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)		      \
+      {									      \
+	ranges[1].start = (map)->l_info[DT_JMPREL]->d_un.d_ptr;		      \
+	ranges[1].size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val;	      \
+	ranges[2].start = ranges[1].start + ranges[1].size;		      \
+	ranges[2].size = ranges[0].start + ranges[0].size - ranges[2].start;  \
+	ranges[0].size = ranges[1].start - ranges[0].start;		      \
       }									      \
+									      \
+    for (ranges_index = 0; ranges_index < 3; ++ranges_index)		      \
+      elf_dynamic_do_##reloc ((map),					      \
+			      ranges[ranges_index].start,		      \
+			      ranges[ranges_index].size,		      \
+			      ranges[ranges_index].lazy);		      \
   } while (0)
 #else
 #define _ELF_DYNAMIC_DO_RELOC(RELOC, reloc, map, lazy) \
   do {									      \
+    struct { ElfW(Addr) start, size;  int lazy; } ranges[2];		      \
+    int ranges_index;							      \
+    ranges[0].lazy = 0;							      \
+    ranges[1].lazy = 1;							      \
+    ranges[0].size = ranges[1].size = 0;				      \
+    ranges[0].start = 0;						      \
+									      \
     if ((map)->l_info[DT_##RELOC])					      \
       {									      \
-	ElfW(Addr) r_addr, r_size;					      \
-        r_addr = (map)->l_info[DT_##RELOC]->d_un.d_ptr;			      \
-        r_size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val;		      \
-	elf_dynamic_do_##reloc ((map), r_addr, r_size, 0);		      \
+        ranges[0].start = (map)->l_info[DT_##RELOC]->d_un.d_ptr;	      \
+        ranges[0].size = (map)->l_info[DT_##RELOC##SZ]->d_un.d_val;	      \
       }									      \
     if ((map)->l_info[DT_PLTREL] &&					      \
 	(map)->l_info[DT_PLTREL]->d_un.d_val == DT_##RELOC)		      \
       {									      \
-	ElfW(Addr) p_addr, p_size;					      \
-	p_addr = (map)->l_info[DT_JMPREL]->d_un.d_ptr;			      \
-	p_size = (map)->l_info[DT_PLTRELSZ]->d_un.d_val;		      \
-	elf_dynamic_do_##reloc ((map), p_addr, p_size, (lazy));		      \
+	ElfW(Addr) start = (map)->l_info[DT_JMPREL]->d_un.d_ptr;	      \
+									      \
+	if (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;	      \
+	  }								      \
+	else								      \
+	  /* Combine processing the sections.  */			      \
+	  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);		      \
   } while (0)
 #endif