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)
}
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))
/* 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;
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. */
: 0),
output_section->alignment_power)
!= output_section->lma)
- abort ();
+ goto sorry;
}
else
{
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;
}
/* 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;
}
_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;
}
}