Make PT_DYNAMIC just include .dynamic on non-SGI MIPS targets

Richard Sandiford richard@codesourcery.com
Thu Oct 19 21:23:00 GMT 2006


On most targets PT_DYNAMIC just includes .dynamic, but for IRIX
compatibility, o32 MIPS targets have traditionally included .hash,
.dynsym and .dynstr as well.

Unfortunately, putting extra sections in PT_DYNAMIC causes problems if
the prelinker moves one of those extra sections to a writable segment.
PT_DYNAMIC can't in general span two PT_LOAD segments (for one thing,
the file and memory gaps might not be equal) so we would either have to
(a) stop the prelinker moving those sections or (b) shrink PT_DYNAMIC to
its normal size.  (b) is of course preferable if it's safe to do.  And I
believe it is safe on non-SGI tarets.  However, if we take that attitude,
we might as well stop binutils from extending PT_DYNAMIC in the first
place.

While checking whether glibc's dynamic linker would be affected by this
change, I noticed that it sometimes alloca()s an array derived from
PT_DYNAMIC's p_filesz.  In that case, making PT_DYNMAIC bigger than it
needs to be can be actively harmful.

Tested on mips{,64}{,el}-{elf,linux-gnu} and mips-sgi-irix6.5.
OK to install?

Richard


bfd/
	* elfxx-mips.c (_bfd_mips_elf_modify_segment_map): Don't extend
	PT_DYNAMIC on GNU/Linux targets.

diff -udpr ../src.1/bfd/elfxx-mips.c ./bfd/elfxx-mips.c
--- ./bfd/elfxx-mips.c	2006-10-19 09:21:12.000000000 -0700
+++ ./bfd/elfxx-mips.c	2006-10-19 09:33:12.000000000 -0700
@@ -9329,8 +9329,18 @@ _bfd_mips_elf_modify_segment_map (bfd *a
 	      m->p_flags_valid = 1;
 	    }
 	}
-      if (m != NULL
-	  && m->count == 1 && strcmp (m->sections[0]->name, ".dynamic") == 0)
+      /* GNU/Linux binaries do not need the extended PT_DYNAMIC section.
+	 glibc's dynamic linker has traditionally derived the number of
+	 tags from the p_filesz field, and sometimes allocates stack
+	 arrays of that size.  An overly-big PT_DYNAMIC segment can
+	 be actively harmful in such cases.  Making PT_DYNAMIC contain
+	 other sections can also make life hard for the prelinker,
+	 which might move one of the other sections to a different
+	 PT_LOAD segment.  */
+      if (SGI_COMPAT (abfd)
+	  && m != NULL
+	  && m->count == 1
+	  && strcmp (m->sections[0]->name, ".dynamic") == 0)
 	{
 	  static const char *sec_names[] =
 	  {



More information about the Binutils mailing list