This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [binutils-gdb] Fix the linker so that it will not silently generate ELF binaries with invalid program headers. Fix


On Sat, Dec 10, 2016 at 12:13:46AM +0000, Maciej W. Rozycki wrote:
>  Thanks for your and Nick's effort; I'll be looking into these patches 
> once I have offloaded my immediately pending queue, which has to take 

I should note that the patch I posted was just a quick hack to
experiment with removing the PT_PHDR header.  A proper patch minus
testsuite tweaking is more like the following, due to elf-nacl.c
fiddling with segments.

diff --git a/bfd/elf.c b/bfd/elf.c
index 678c043..9c8a167 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4483,6 +4483,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
   asection **sections = NULL;
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
   bfd_boolean no_user_phdrs;
+  bfd_boolean phdr_in_segment = TRUE;
 
   no_user_phdrs = elf_seg_map (abfd) == NULL;
 
@@ -4500,14 +4501,12 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
       unsigned int phdr_index;
       bfd_vma maxpagesize;
       asection **hdrpp;
-      bfd_boolean phdr_in_segment = TRUE;
       bfd_boolean writable;
       int tls_count = 0;
       asection *first_tls = NULL;
       asection *dynsec, *eh_frame_hdr;
       bfd_size_type amt;
       bfd_vma addr_mask, wrap_to = 0;
-      bfd_boolean linker_created_pt_phdr_segment = FALSE;
 
       /* Select the allocated sections, and sort them.  */
 
@@ -4560,7 +4559,6 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
 	  m->p_flags = PF_R | PF_X;
 	  m->p_flags_valid = 1;
 	  m->includes_phdrs = 1;
-	  linker_created_pt_phdr_segment = TRUE;
 	  *pm = m;
 	  pm = &m->next;
 
@@ -4611,19 +4609,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
 	      || ((sections[0]->lma & addr_mask) % maxpagesize
 		  < phdr_size % maxpagesize)
 	      || (sections[0]->lma & addr_mask & -maxpagesize) < wrap_to)
-	    {
-	      /* PR 20815: The ELF standard says that a PT_PHDR segment, if
-		 present, must be included as part of the memory image of the
-		 program.  Ie it must be part of a PT_LOAD segment as well.
-		 If we have had to create our own PT_PHDR segment, but it is
-		 not going to be covered by the first PT_LOAD segment, then
-		 force the inclusion if we can...  */
-	      if ((abfd->flags & D_PAGED) != 0
-		  && linker_created_pt_phdr_segment)
-		phdr_in_segment = TRUE;
-	      else
-		phdr_in_segment = FALSE;
-	    }
+	    phdr_in_segment = FALSE;
 	}
 
       for (i = 0, hdrpp = sections; i < count; i++, hdrpp++)
@@ -4965,8 +4951,26 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
   if (!elf_modify_segment_map (abfd, info, no_user_phdrs))
     return FALSE;
 
+  phdr_in_segment = FALSE;
   for (count = 0, m = elf_seg_map (abfd); m != NULL; m = m->next)
-    ++count;
+    {
+      if (m->p_type == PT_LOAD && m->includes_phdrs)
+	phdr_in_segment = TRUE;
+      ++count;
+    }
+  if (no_user_phdrs && !phdr_in_segment && count != 0)
+    {
+      /* PR 20815: The ELF standard says that a PT_PHDR segment, if
+	 present, must be included as part of the memory image of the
+	 program.  Ie it must be part of a PT_LOAD segment as well.
+	 If PHDR won't be part of the memory image, remove it.  */
+      m = elf_seg_map (abfd);
+      if (m->p_type == PT_PHDR)
+	{
+	  elf_seg_map (abfd) = m->next;
+	  --count;
+	}
+    }
   elf_program_header_size (abfd) = count * bed->s->sizeof_phdr;
 
   return TRUE;

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]