elf_backend_modify_headers
[deliverable/binutils-gdb.git] / bfd / elf.c
index be060d579ccec113b6222787faba5fccc907bbd5..d1815e152646a679ca9589e71c70d5db5fe21beb 100644 (file)
--- 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.  */
 
@@ -7324,7 +7330,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
                                          : 0),
                                       output_section->alignment_power)
                          != output_section->lma)
-                       abort ();
+                       goto sorry;
                    }
                  else
                    {
@@ -7363,7 +7369,8 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
             negative size - or segments that do not contain any sections.  */
          if (map->count == 0)
            {
-             bfd_set_error (bfd_error_bad_value);
+           sorry:
+             bfd_set_error (bfd_error_sorry);
              free (sections);
              return FALSE;
            }
@@ -9277,7 +9284,7 @@ _bfd_elf_validate_reloc (bfd *abfd, arelent *areloc)
   /* xgettext:c-format */
   _bfd_error_handler (_("%pB: %s unsupported"),
                      abfd, areloc->howto->name);
-  bfd_set_error (bfd_error_bad_value);
+  bfd_set_error (bfd_error_sorry);
   return FALSE;
 }
 
@@ -12249,7 +12256,7 @@ _bfd_elf_final_write_processing (bfd *abfd)
            _bfd_error_handler (_("symbol type STT_GNU_IFUNC is unsupported"));
          if (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_unique)
            _bfd_error_handler (_("symbol binding STB_GNU_UNIQUE is unsupported"));
-         bfd_set_error (bfd_error_bad_value);
+         bfd_set_error (bfd_error_sorry);
          return FALSE;
        }
     }
This page took 0.02443 seconds and 4 git commands to generate.