Generate a PT_PHDR entry for static PIE binaries. Modern GDB needs this to
authorkettenis <kettenis@openbsd.org>
Tue, 13 Jan 2015 20:05:01 +0000 (20:05 +0000)
committerkettenis <kettenis@openbsd.org>
Tue, 13 Jan 2015 20:05:01 +0000 (20:05 +0000)
do some sanity checking while it determines the load base.

ok kurt@

gnu/usr.bin/binutils/bfd/elf-bfd.h
gnu/usr.bin/binutils/bfd/elf.c
gnu/usr.bin/binutils/bfd/elflink.c

index 110dd69..db4d986 100644 (file)
@@ -1235,6 +1235,9 @@ struct elf_obj_tdata
 
   /* Used to determine if the e_flags field has been initialized */
   bfd_boolean flags_init;
+
+  /* Used to determine if we are creating an executable.  */
+  bfd_boolean executable;
 };
 
 #define elf_tdata(bfd)         ((bfd) -> tdata.elf_obj_data)
index 901fd2c..efef5f9 100644 (file)
@@ -3234,11 +3234,13 @@ map_sections_to_segments (bfd *abfd)
   mfirst = NULL;
   pm = &mfirst;
 
-  /* If we have a .interp section, then create a PT_PHDR segment for
-     the program headers and a PT_INTERP segment for the .interp
-     section.  */
+  /* If we have a .interp section, or are creating an executable and
+     have a .dynamic section, then create a PT_PHDR segment for the
+     program headers.  */
   s = bfd_get_section_by_name (abfd, ".interp");
-  if (s != NULL && (s->flags & SEC_LOAD) != 0)
+  if ((s != NULL && (s->flags & SEC_LOAD) != 0) ||
+      (bfd_get_section_by_name (abfd, ".dynamic") &&
+       elf_tdata (abfd)->executable))
     {
       amt = sizeof (struct elf_segment_map);
       m = bfd_zalloc (abfd, amt);
@@ -3253,7 +3255,12 @@ map_sections_to_segments (bfd *abfd)
 
       *pm = m;
       pm = &m->next;
+    }      
 
+  /* If we have a .interp section, then create a PT_INTERP segment for
+     the .interp section.  */
+  if (s != NULL && (s->flags & SEC_LOAD) != 0)
+    {
       amt = sizeof (struct elf_segment_map);
       m = bfd_zalloc (abfd, amt);
       if (m == NULL)
@@ -4134,13 +4141,20 @@ get_program_header_size (bfd *abfd)
   segs = 7;
 
   s = bfd_get_section_by_name (abfd, ".interp");
+  s = bfd_get_section_by_name (abfd, ".interp");
+  if ((s != NULL && (s->flags & SEC_LOAD) != 0) ||
+      (bfd_get_section_by_name (abfd, ".dynamic") &&
+       elf_tdata (abfd)->executable))
+    {
+      /* We need a PT_PHDR segment.  */
+      ++segs;
+    }
+
   if (s != NULL && (s->flags & SEC_LOAD) != 0)
     {
       /* If we have a loadable interpreter section, we need a
-        PT_INTERP segment.  In this case, assume we also need a
-        PT_PHDR segment, although that may not be true for all
-        targets.  */
-      segs += 2;
+        PT_INTERP segment.  */
+      ++segs;
     }
 
   if (bfd_get_section_by_name (abfd, ".dynamic") != NULL)
index 73a8a47..d6db608 100644 (file)
@@ -4626,6 +4626,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
   if (!is_elf_hash_table (info->hash))
     return TRUE;
 
+  elf_tdata (output_bfd)->executable = info->executable;
   if (info->execstack)
     elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;
   else if (info->noexecstack)