elf_backend_modify_headers

Message ID 20191118115215.GB13199@bubble.grove.modra.org
State New
Headers show
Series
  • elf_backend_modify_headers
Related show

Commit Message

Alan Modra Nov. 18, 2019, 11:52 a.m.
This patch renames elf_backend_modify_program_headers and moves the
elf.c code tweaking the ELF file header for -pie -Ttext-segment to a
new function, _bfd_elf_modify_headers, which then becomes the default
elf_backed_modify_headers and is called from any other target
elf_backed_modify_headers.

	* elf-bfd.h (struct elf_backend_data <elf_backend_modify_headers>):
	Rename from elf_backend_modify_program_headers.
	(_bfd_elf_modify_headers): Declare.
	* elf.c (assign_file_positions_except_relocs): Set
	elf_program_header_size.  Always call elf_backend_modify_headers.
	Extract code modifying file header..
	(_bfd_elf_modify_headers): ..to here.  New function.
	* elf32-arm.c (elf_backend_modify_headers): Renamed from
	elf_backend_modify_program_headers.
	* elf32-i386.c: Similarly.
	* elf64-x86-64.c: Similarly.
	* elfxx-target.h: Similarly.  Default elf_backend_modify_headers
	to _bfd_elf_modify_headers.
	* elf-nacl.h (nacl_modify_headers): Rename from
	nacl_modify_program_headers.
	* elf-nacl.c (nacl_modify_headers): Rename from
	nacl_modify_program_headers and call _bfd_elf_modify_headers.
	* elf32-rx.c (elf32_rx_modify_headers): Similarly.
	* elf32-spu.c (spu_elf_modify_headers): Similarly.
	* elfnn-ia64.c (elfNN_ia64_modify_headers): Similarly.
	* elf32-sh.c (elf_backend_modify_program_headers): Don't undef.


-- 
Alan Modra
Australia Development Lab, IBM

Patch

diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 7309499119..09975c75fc 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1165,7 +1165,7 @@  struct elf_backend_data
 
   /* This function is called to modify program headers just before
      they are written.  */
-  bfd_boolean (*elf_backend_modify_program_headers)
+  bfd_boolean (*elf_backend_modify_headers)
     (bfd *, struct bfd_link_info *);
 
   /* This function is called to see if the PHDR header should be
@@ -2305,6 +2305,8 @@  extern bfd_boolean _bfd_elf_compute_section_file_positions
   (bfd *, struct bfd_link_info *);
 extern file_ptr _bfd_elf_assign_file_position_for_section
   (Elf_Internal_Shdr *, file_ptr, bfd_boolean);
+extern bfd_boolean _bfd_elf_modify_headers
+  (bfd *, struct bfd_link_info *);
 
 extern bfd_boolean _bfd_elf_validate_reloc
   (bfd *, arelent *);
diff --git a/bfd/elf-nacl.c b/bfd/elf-nacl.c
index ddac3b372b..d8d67f338f 100644
--- a/bfd/elf-nacl.c
+++ b/bfd/elf-nacl.c
@@ -235,90 +235,93 @@  nacl_modify_segment_map (bfd *abfd, struct bfd_link_info *info)
    proper order for the ELF rule that they must appear in ascending address
    order.  So find the two segments we swapped before, and swap them back.  */
 bfd_boolean
-nacl_modify_program_headers (bfd *abfd, struct bfd_link_info *info)
+nacl_modify_headers (bfd *abfd, struct bfd_link_info *info)
 {
-  struct elf_segment_map **m = &elf_seg_map (abfd);
-  Elf_Internal_Phdr *phdr = elf_tdata (abfd)->phdr;
-  Elf_Internal_Phdr *p = phdr;
-
   if (info != NULL && info->user_phdrs)
     /* The linker script used PHDRS explicitly, so don't change what the
        user asked for.  */
-    return TRUE;
-
-  /* Find the PT_LOAD that contains the headers (should be the first).  */
-  while (*m != NULL)
-    {
-      if ((*m)->p_type == PT_LOAD && (*m)->includes_filehdr)
-	break;
-
-      m = &(*m)->next;
-      ++p;
-    }
-
-  if (*m != NULL)
+    ;
+  else
     {
-      struct elf_segment_map **first_load_seg = m;
-      Elf_Internal_Phdr *first_load_phdr = p;
-      struct elf_segment_map **next_load_seg = NULL;
-      Elf_Internal_Phdr *next_load_phdr = NULL;
-
-      /* Now move past that first one and find the PT_LOAD that should be
-	 before it by address order.  */
-
-      m = &(*m)->next;
-      ++p;
+      struct elf_segment_map **m = &elf_seg_map (abfd);
+      Elf_Internal_Phdr *phdr = elf_tdata (abfd)->phdr;
+      Elf_Internal_Phdr *p = phdr;
 
+      /* Find the PT_LOAD that contains the headers (should be the first).  */
       while (*m != NULL)
 	{
-	  if (p->p_type == PT_LOAD && p->p_vaddr < first_load_phdr->p_vaddr)
-	    {
-	      next_load_seg = m;
-	      next_load_phdr = p;
-	      break;
-	    }
+	  if ((*m)->p_type == PT_LOAD && (*m)->includes_filehdr)
+	    break;
 
 	  m = &(*m)->next;
 	  ++p;
 	}
 
-      /* Swap their positions in the segment_map back to how they used to be.
-	 The phdrs have already been set up by now, so we have to slide up
-	 the earlier ones to insert the one that should be first.  */
-      if (next_load_seg != NULL)
+      if (*m != NULL)
 	{
-	  Elf_Internal_Phdr move_phdr;
-	  struct elf_segment_map *first_seg = *first_load_seg;
-	  struct elf_segment_map *next_seg = *next_load_seg;
-	  struct elf_segment_map *first_next = first_seg->next;
-	  struct elf_segment_map *next_next = next_seg->next;
+	  struct elf_segment_map **first_load_seg = m;
+	  Elf_Internal_Phdr *first_load_phdr = p;
+	  struct elf_segment_map **next_load_seg = NULL;
+	  Elf_Internal_Phdr *next_load_phdr = NULL;
+
+	  /* Now move past that first one and find the PT_LOAD that should be
+	     before it by address order.  */
 
-	  if (next_load_seg == &first_seg->next)
+	  m = &(*m)->next;
+	  ++p;
+
+	  while (*m != NULL)
 	    {
-	      *first_load_seg = next_seg;
-	      next_seg->next = first_seg;
-	      first_seg->next = next_next;
+	      if (p->p_type == PT_LOAD && p->p_vaddr < first_load_phdr->p_vaddr)
+		{
+		  next_load_seg = m;
+		  next_load_phdr = p;
+		  break;
+		}
+
+	      m = &(*m)->next;
+	      ++p;
 	    }
-	  else
+
+	  /* Swap their positions in the segment_map back to how they
+	     used to be.  The phdrs have already been set up by now,
+	     so we have to slide up the earlier ones to insert the one
+	     that should be first.  */
+	  if (next_load_seg != NULL)
 	    {
-	      *first_load_seg = first_next;
-	      *next_load_seg = next_next;
+	      Elf_Internal_Phdr move_phdr;
+	      struct elf_segment_map *first_seg = *first_load_seg;
+	      struct elf_segment_map *next_seg = *next_load_seg;
+	      struct elf_segment_map *first_next = first_seg->next;
+	      struct elf_segment_map *next_next = next_seg->next;
 
-	      first_seg->next = *next_load_seg;
-	      *next_load_seg = first_seg;
+	      if (next_load_seg == &first_seg->next)
+		{
+		  *first_load_seg = next_seg;
+		  next_seg->next = first_seg;
+		  first_seg->next = next_next;
+		}
+	      else
+		{
+		  *first_load_seg = first_next;
+		  *next_load_seg = next_next;
 
-	      next_seg->next = *first_load_seg;
-	      *first_load_seg = next_seg;
-	    }
+		  first_seg->next = *next_load_seg;
+		  *next_load_seg = first_seg;
 
-	  move_phdr = *next_load_phdr;
-	  memmove (first_load_phdr + 1, first_load_phdr,
-		   (next_load_phdr - first_load_phdr) * sizeof move_phdr);
-	  *first_load_phdr = move_phdr;
+		  next_seg->next = *first_load_seg;
+		  *first_load_seg = next_seg;
+		}
+
+	      move_phdr = *next_load_phdr;
+	      memmove (first_load_phdr + 1, first_load_phdr,
+		       (next_load_phdr - first_load_phdr) * sizeof move_phdr);
+	      *first_load_phdr = move_phdr;
+	    }
 	}
     }
 
-  return TRUE;
+  return _bfd_elf_modify_headers (abfd, info);
 }
 
 bfd_boolean
diff --git a/bfd/elf-nacl.h b/bfd/elf-nacl.h
index ba28c570f9..0b151d1436 100644
--- a/bfd/elf-nacl.h
+++ b/bfd/elf-nacl.h
@@ -17,5 +17,5 @@ 
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 bfd_boolean nacl_modify_segment_map (bfd *, struct bfd_link_info *);
-bfd_boolean nacl_modify_program_headers (bfd *, struct bfd_link_info *);
+bfd_boolean nacl_modify_headers (bfd *, struct bfd_link_info *);
 bfd_boolean nacl_final_write_processing (bfd *);
diff --git a/bfd/elf.c b/bfd/elf.c
index e10099842b..d1815e1526 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -6313,6 +6313,7 @@  assign_file_positions_except_relocs (bfd *abfd,
   struct elf_obj_tdata *tdata = elf_tdata (abfd);
   Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+  unsigned int alloc;
 
   if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0
       && bfd_get_format (abfd) != bfd_core)
@@ -6355,11 +6356,10 @@  assign_file_positions_except_relocs (bfd *abfd,
 	}
 
       elf_next_file_pos (abfd) = off;
+      elf_program_header_size (abfd) = 0;
     }
   else
     {
-      unsigned int alloc;
-
       /* Assign file positions for the loaded sections based on the
 	 assignment of sections to segments.  */
       if (!assign_file_positions_for_load_sections (abfd, link_info))
@@ -6368,41 +6368,15 @@  assign_file_positions_except_relocs (bfd *abfd,
       /* And for non-load sections.  */
       if (!assign_file_positions_for_non_load_sections (abfd, link_info))
 	return FALSE;
+    }
 
-      if (bed->elf_backend_modify_program_headers != NULL)
-	{
-	  if (!(*bed->elf_backend_modify_program_headers) (abfd, link_info))
-	    return FALSE;
-	}
-
-      /* Set e_type in ELF header to ET_EXEC for -pie -Ttext-segment=.  */
-      if (link_info != NULL && bfd_link_pie (link_info))
-	{
-	  unsigned int num_segments = i_ehdrp->e_phnum;
-	  Elf_Internal_Phdr *segment = tdata->phdr;
-	  Elf_Internal_Phdr *end_segment = &segment[num_segments];
-
-	  /* Find the lowest p_vaddr in PT_LOAD segments.  */
-	  bfd_vma p_vaddr = (bfd_vma) -1;
-	  for (; segment < end_segment; segment++)
-	    if (segment->p_type == PT_LOAD && p_vaddr > segment->p_vaddr)
-	      p_vaddr = segment->p_vaddr;
-
-	  /* Set e_type to ET_EXEC if the lowest p_vaddr in PT_LOAD
-	     segments is non-zero.  */
-	  if (p_vaddr)
-	    i_ehdrp->e_type = ET_EXEC;
-	}
-
-      /* Write out the program headers.
-	 FIXME: We used to have code here to sort the PT_LOAD segments into
-	 ascending order, as per the ELF spec.  But this breaks some programs,
-	 including the Linux kernel.  But really either the spec should be
-	 changed or the programs updated.  */
-      alloc = i_ehdrp->e_phnum;
-      if (alloc == 0)
-	return TRUE;
+  if (!(*bed->elf_backend_modify_headers) (abfd, link_info))
+    return FALSE;
 
+  /* Write out the program headers.  */
+  alloc = i_ehdrp->e_phnum;
+  if (alloc != 0)
+    {
       if (bfd_seek (abfd, i_ehdrp->e_phoff, SEEK_SET) != 0
 	  || bed->s->write_out_phdrs (abfd, tdata->phdr, alloc) != 0)
 	return FALSE;
@@ -6499,6 +6473,38 @@  prep_headers (bfd *abfd)
   return TRUE;
 }
 
+/* Set e_type in ELF header to ET_EXEC for -pie -Ttext-segment=.
+
+   FIXME: We used to have code here to sort the PT_LOAD segments into
+   ascending order, as per the ELF spec.  But this breaks some programs,
+   including the Linux kernel.  But really either the spec should be
+   changed or the programs updated.  */
+
+bfd_boolean
+_bfd_elf_modify_headers (bfd *obfd, struct bfd_link_info *link_info)
+{
+  if (link_info != NULL && bfd_link_pie (link_info))
+    {
+      Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (obfd);
+      unsigned int num_segments = i_ehdrp->e_phnum;
+      struct elf_obj_tdata *tdata = elf_tdata (obfd);
+      Elf_Internal_Phdr *segment = tdata->phdr;
+      Elf_Internal_Phdr *end_segment = &segment[num_segments];
+
+      /* Find the lowest p_vaddr in PT_LOAD segments.  */
+      bfd_vma p_vaddr = (bfd_vma) -1;
+      for (; segment < end_segment; segment++)
+	if (segment->p_type == PT_LOAD && p_vaddr > segment->p_vaddr)
+	  p_vaddr = segment->p_vaddr;
+
+      /* Set e_type to ET_EXEC if the lowest p_vaddr in PT_LOAD
+	 segments is non-zero.  */
+      if (p_vaddr)
+	i_ehdrp->e_type = ET_EXEC;
+    }
+  return TRUE;
+}
+
 /* Assign file positions for all the reloc sections which are not part
    of the loadable file image, and the file position of section headers.  */
 
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 3aa7de8fee..8fb2b47378 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -20624,8 +20624,8 @@  elf32_arm_nacl_plt_sym_val (bfd_vma i, const asection *plt,
 #define elf_backend_plt_alignment		4
 #undef	elf_backend_modify_segment_map
 #define	elf_backend_modify_segment_map		elf32_arm_nacl_modify_segment_map
-#undef	elf_backend_modify_program_headers
-#define	elf_backend_modify_program_headers	nacl_modify_program_headers
+#undef	elf_backend_modify_headers
+#define	elf_backend_modify_headers		nacl_modify_headers
 #undef  elf_backend_final_write_processing
 #define elf_backend_final_write_processing	elf32_arm_nacl_final_write_processing
 #undef bfd_elf32_get_synthetic_symtab
@@ -20643,7 +20643,7 @@  elf32_arm_nacl_plt_sym_val (bfd_vma i, const asection *plt,
 #undef	elf_backend_plt_alignment
 #undef	elf_backend_modify_segment_map
 #define elf_backend_modify_segment_map		elf32_arm_modify_segment_map
-#undef	elf_backend_modify_program_headers
+#undef	elf_backend_modify_headers
 #undef  elf_backend_final_write_processing
 #define elf_backend_final_write_processing	elf32_arm_final_write_processing
 #undef	ELF_MINPAGESIZE
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 9248ef5a41..2afd4f6766 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -4774,8 +4774,8 @@  elf32_i386_nacl_elf_object_p (bfd *abfd)
 #define elf_backend_object_p			elf32_i386_nacl_elf_object_p
 #undef	elf_backend_modify_segment_map
 #define	elf_backend_modify_segment_map		nacl_modify_segment_map
-#undef	elf_backend_modify_program_headers
-#define	elf_backend_modify_program_headers	nacl_modify_program_headers
+#undef	elf_backend_modify_headers
+#define	elf_backend_modify_headers		nacl_modify_headers
 #undef	elf_backend_final_write_processing
 #define elf_backend_final_write_processing	nacl_final_write_processing
 
@@ -4784,7 +4784,7 @@  elf32_i386_nacl_elf_object_p (bfd *abfd)
 /* Restore defaults.  */
 #undef	elf_backend_object_p
 #undef	elf_backend_modify_segment_map
-#undef	elf_backend_modify_program_headers
+#undef	elf_backend_modify_headers
 #undef	elf_backend_final_write_processing
 
 /* VxWorks support.  */
diff --git a/bfd/elf32-rx.c b/bfd/elf32-rx.c
index 7978244f1e..a1a5ce11be 100644
--- a/bfd/elf32-rx.c
+++ b/bfd/elf32-rx.c
@@ -3684,8 +3684,7 @@  rx_final_link (bfd * abfd, struct bfd_link_info * info)
 }
 
 static bfd_boolean
-elf32_rx_modify_program_headers (bfd * abfd ATTRIBUTE_UNUSED,
-				 struct bfd_link_info * info ATTRIBUTE_UNUSED)
+elf32_rx_modify_headers (bfd *abfd, struct bfd_link_info *info)
 {
   const struct elf_backend_data * bed;
   struct elf_obj_tdata * tdata;
@@ -3717,7 +3716,7 @@  elf32_rx_modify_program_headers (bfd * abfd ATTRIBUTE_UNUSED,
 #endif
 	}
 
-  return TRUE;
+  return _bfd_elf_modify_headers (abfd, info);
 }
 
 /* The default literal sections should always be marked as "code" (i.e.,
@@ -4037,7 +4036,7 @@  rx_additional_link_map_text (bfd *obfd, struct bfd_link_info *info, FILE *mapfil
 #define elf_backend_relocate_section		rx_elf_relocate_section
 #define elf_symbol_leading_char			('_')
 #define elf_backend_can_gc_sections		1
-#define elf_backend_modify_program_headers	elf32_rx_modify_program_headers
+#define elf_backend_modify_headers		elf32_rx_modify_headers
 
 #define bfd_elf32_bfd_reloc_type_lookup		rx_reloc_type_lookup
 #define bfd_elf32_bfd_reloc_name_lookup		rx_reloc_name_lookup
diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
index c572f709f2..c10691e422 100644
--- a/bfd/elf32-sh.c
+++ b/bfd/elf32-sh.c
@@ -6847,8 +6847,6 @@  sh_elf_encode_eh_address (bfd *abfd,
 
 #include "elf32-target.h"
 
-#undef elf_backend_modify_program_headers
-
 /* VxWorks support.  */
 #undef	TARGET_BIG_SYM
 #define	TARGET_BIG_SYM			sh_elf32_vxworks_vec
diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c
index b557c865b3..aa1510596f 100644
--- a/bfd/elf32-spu.c
+++ b/bfd/elf32-spu.c
@@ -2128,7 +2128,7 @@  spu_elf_build_stubs (struct bfd_link_info *info)
 	      bfd_put_32 (htab->ovtab->owner, s->vma, p + off);
 	      bfd_put_32 (htab->ovtab->owner, (s->size + 15) & -16,
 			  p + off + 4);
-	      /* file_off written later in spu_elf_modify_program_headers.  */
+	      /* file_off written later in spu_elf_modify_headers.  */
 	      bfd_put_32 (htab->ovtab->owner, ovl_buf, p + off + 12);
 	    }
 	}
@@ -5344,96 +5344,99 @@  spu_elf_fake_sections (bfd *obfd ATTRIBUTE_UNUSED,
 /* Tweak phdrs before writing them out.  */
 
 static int
-spu_elf_modify_program_headers (bfd *abfd, struct bfd_link_info *info)
+spu_elf_modify_headers (bfd *abfd, struct bfd_link_info *info)
 {
-  const struct elf_backend_data *bed;
-  struct elf_obj_tdata *tdata;
-  Elf_Internal_Phdr *phdr, *last;
-  struct spu_link_hash_table *htab;
-  unsigned int count;
-  unsigned int i;
-
-  if (info == NULL)
-    return TRUE;
-
-  bed = get_elf_backend_data (abfd);
-  tdata = elf_tdata (abfd);
-  phdr = tdata->phdr;
-  count = elf_program_header_size (abfd) / bed->s->sizeof_phdr;
-  htab = spu_hash_table (info);
-  if (htab->num_overlays != 0)
+  if (info != NULL)
     {
-      struct elf_segment_map *m;
-      unsigned int o;
-
-      for (i = 0, m = elf_seg_map (abfd); m; ++i, m = m->next)
-	if (m->count != 0
-	    && (o = spu_elf_section_data (m->sections[0])->u.o.ovl_index) != 0)
-	  {
-	    /* Mark this as an overlay header.  */
-	    phdr[i].p_flags |= PF_OVERLAY;
+      const struct elf_backend_data *bed;
+      struct elf_obj_tdata *tdata;
+      Elf_Internal_Phdr *phdr, *last;
+      struct spu_link_hash_table *htab;
+      unsigned int count;
+      unsigned int i;
+
+      bed = get_elf_backend_data (abfd);
+      tdata = elf_tdata (abfd);
+      phdr = tdata->phdr;
+      count = elf_program_header_size (abfd) / bed->s->sizeof_phdr;
+      htab = spu_hash_table (info);
+      if (htab->num_overlays != 0)
+	{
+	  struct elf_segment_map *m;
+	  unsigned int o;
 
-	    if (htab->ovtab != NULL && htab->ovtab->size != 0
-		&& htab->params->ovly_flavour != ovly_soft_icache)
+	  for (i = 0, m = elf_seg_map (abfd); m; ++i, m = m->next)
+	    if (m->count != 0
+		&& ((o = spu_elf_section_data (m->sections[0])->u.o.ovl_index)
+		    != 0))
 	      {
-		bfd_byte *p = htab->ovtab->contents;
-		unsigned int off = o * 16 + 8;
+		/* Mark this as an overlay header.  */
+		phdr[i].p_flags |= PF_OVERLAY;
 
-		/* Write file_off into _ovly_table.  */
-		bfd_put_32 (htab->ovtab->owner, phdr[i].p_offset, p + off);
+		if (htab->ovtab != NULL && htab->ovtab->size != 0
+		    && htab->params->ovly_flavour != ovly_soft_icache)
+		  {
+		    bfd_byte *p = htab->ovtab->contents;
+		    unsigned int off = o * 16 + 8;
+
+		    /* Write file_off into _ovly_table.  */
+		    bfd_put_32 (htab->ovtab->owner, phdr[i].p_offset, p + off);
+		  }
 	      }
-	  }
-      /* Soft-icache has its file offset put in .ovl.init.  */
-      if (htab->init != NULL && htab->init->size != 0)
-	{
-	  bfd_vma val = elf_section_data (htab->ovl_sec[0])->this_hdr.sh_offset;
+	  /* Soft-icache has its file offset put in .ovl.init.  */
+	  if (htab->init != NULL && htab->init->size != 0)
+	    {
+	      bfd_vma val
+		= elf_section_data (htab->ovl_sec[0])->this_hdr.sh_offset;
 
-	  bfd_put_32 (htab->init->owner, val, htab->init->contents + 4);
+	      bfd_put_32 (htab->init->owner, val, htab->init->contents + 4);
+	    }
 	}
-    }
 
-  /* Round up p_filesz and p_memsz of PT_LOAD segments to multiples
-     of 16.  This should always be possible when using the standard
-     linker scripts, but don't create overlapping segments if
-     someone is playing games with linker scripts.  */
-  last = NULL;
-  for (i = count; i-- != 0; )
-    if (phdr[i].p_type == PT_LOAD)
-      {
-	unsigned adjust;
+      /* Round up p_filesz and p_memsz of PT_LOAD segments to multiples
+	 of 16.  This should always be possible when using the standard
+	 linker scripts, but don't create overlapping segments if
+	 someone is playing games with linker scripts.  */
+      last = NULL;
+      for (i = count; i-- != 0; )
+	if (phdr[i].p_type == PT_LOAD)
+	  {
+	    unsigned adjust;
 
-	adjust = -phdr[i].p_filesz & 15;
-	if (adjust != 0
-	    && last != NULL
-	    && phdr[i].p_offset + phdr[i].p_filesz > last->p_offset - adjust)
-	  break;
+	    adjust = -phdr[i].p_filesz & 15;
+	    if (adjust != 0
+		&& last != NULL
+		&& (phdr[i].p_offset + phdr[i].p_filesz
+		    > last->p_offset - adjust))
+	      break;
 
-	adjust = -phdr[i].p_memsz & 15;
-	if (adjust != 0
-	    && last != NULL
-	    && phdr[i].p_filesz != 0
-	    && phdr[i].p_vaddr + phdr[i].p_memsz > last->p_vaddr - adjust
-	    && phdr[i].p_vaddr + phdr[i].p_memsz <= last->p_vaddr)
-	  break;
+	    adjust = -phdr[i].p_memsz & 15;
+	    if (adjust != 0
+		&& last != NULL
+		&& phdr[i].p_filesz != 0
+		&& phdr[i].p_vaddr + phdr[i].p_memsz > last->p_vaddr - adjust
+		&& phdr[i].p_vaddr + phdr[i].p_memsz <= last->p_vaddr)
+	      break;
 
-	if (phdr[i].p_filesz != 0)
-	  last = &phdr[i];
-      }
+	    if (phdr[i].p_filesz != 0)
+	      last = &phdr[i];
+	  }
 
-  if (i == (unsigned int) -1)
-    for (i = count; i-- != 0; )
-      if (phdr[i].p_type == PT_LOAD)
-	{
-	unsigned adjust;
+      if (i == (unsigned int) -1)
+	for (i = count; i-- != 0; )
+	  if (phdr[i].p_type == PT_LOAD)
+	    {
+	      unsigned adjust;
 
-	adjust = -phdr[i].p_filesz & 15;
-	phdr[i].p_filesz += adjust;
+	      adjust = -phdr[i].p_filesz & 15;
+	      phdr[i].p_filesz += adjust;
 
-	adjust = -phdr[i].p_memsz & 15;
-	phdr[i].p_memsz += adjust;
-      }
+	      adjust = -phdr[i].p_memsz & 15;
+	      phdr[i].p_memsz += adjust;
+	    }
+    }
 
-  return TRUE;
+  return _bfd_elf_modify_headers (abfd, info);
 }
 
 bfd_boolean
@@ -5527,7 +5530,7 @@  spu_elf_size_sections (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info)
 
 #define elf_backend_additional_program_headers	spu_elf_additional_program_headers
 #define elf_backend_modify_segment_map		spu_elf_modify_segment_map
-#define elf_backend_modify_program_headers	spu_elf_modify_program_headers
+#define elf_backend_modify_headers		spu_elf_modify_headers
 #define elf_backend_post_process_headers	spu_elf_post_process_headers
 #define elf_backend_fake_sections		spu_elf_fake_sections
 #define elf_backend_special_sections		spu_elf_special_sections
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 16e66f95d2..f214fa1420 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -5429,8 +5429,8 @@  static const struct elf_x86_backend_data elf_x86_64_nacl_arch_bed =
 #define elf_backend_object_p			elf64_x86_64_nacl_elf_object_p
 #undef	elf_backend_modify_segment_map
 #define	elf_backend_modify_segment_map		nacl_modify_segment_map
-#undef	elf_backend_modify_program_headers
-#define	elf_backend_modify_program_headers	nacl_modify_program_headers
+#undef	elf_backend_modify_headers
+#define	elf_backend_modify_headers		nacl_modify_headers
 #undef	elf_backend_final_write_processing
 #define elf_backend_final_write_processing	nacl_final_write_processing
 
@@ -5483,7 +5483,7 @@  elf32_x86_64_nacl_elf_object_p (bfd *abfd)
 #undef	elf_backend_bfd_from_remote_memory
 #undef	elf_backend_size_info
 #undef	elf_backend_modify_segment_map
-#undef	elf_backend_modify_program_headers
+#undef	elf_backend_modify_headers
 #undef	elf_backend_final_write_processing
 
 /* Intel L1OM support.  */
diff --git a/bfd/elfnn-ia64.c b/bfd/elfnn-ia64.c
index da10178d4f..63917702de 100644
--- a/bfd/elfnn-ia64.c
+++ b/bfd/elfnn-ia64.c
@@ -1191,8 +1191,7 @@  elfNN_ia64_modify_segment_map (bfd *abfd,
    for SHF_IA_64_NORECOV on each.  */
 
 static bfd_boolean
-elfNN_ia64_modify_program_headers (bfd *abfd,
-				   struct bfd_link_info *info ATTRIBUTE_UNUSED)
+elfNN_ia64_modify_headers (bfd *abfd, struct bfd_link_info *info)
 {
   struct elf_obj_tdata *tdata = elf_tdata (abfd);
   struct elf_segment_map *m;
@@ -1224,7 +1223,7 @@  elfNN_ia64_modify_program_headers (bfd *abfd,
       found:;
       }
 
-  return TRUE;
+  return _bfd_elf_modify_headers (abfd, info);
 }
 
 /* According to the Tahoe assembler spec, all labels starting with a
@@ -5037,8 +5036,8 @@  elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
 	elfNN_ia64_additional_program_headers
 #define elf_backend_modify_segment_map \
 	elfNN_ia64_modify_segment_map
-#define elf_backend_modify_program_headers \
-	elfNN_ia64_modify_program_headers
+#define elf_backend_modify_headers \
+	elfNN_ia64_modify_headers
 #define elf_info_to_howto \
 	elfNN_ia64_info_to_howto
 
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index 29ad2e8481..a10601bd53 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -509,8 +509,8 @@ 
 #ifndef elf_backend_modify_segment_map
 #define elf_backend_modify_segment_map	0
 #endif
-#ifndef elf_backend_modify_program_headers
-#define elf_backend_modify_program_headers	0
+#ifndef elf_backend_modify_headers
+#define elf_backend_modify_headers		_bfd_elf_modify_headers
 #endif
 #ifndef elf_backend_allow_non_load_phdr
 #define elf_backend_allow_non_load_phdr	0
@@ -823,7 +823,7 @@  static struct elf_backend_data elfNN_bed =
   elf_backend_final_write_processing,
   elf_backend_additional_program_headers,
   elf_backend_modify_segment_map,
-  elf_backend_modify_program_headers,
+  elf_backend_modify_headers,
   elf_backend_allow_non_load_phdr,
   elf_backend_gc_keep,
   elf_backend_gc_mark_dynamic_ref,