aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2019-11-18 17:09:01 +1030
committerAlan Modra <amodra@gmail.com>2019-11-18 22:06:09 +1030
commit6d6c25c8eaaf42755a759beeb2996502322b960c (patch)
tree3ec735f2069634d339bde6d46dab7a7c758eb164 /bfd/elf.c
parentPR25196, abort in rewrite_elf_program_header (diff)
downloadbinutils-gdb-6d6c25c8eaaf42755a759beeb2996502322b960c.tar.gz
binutils-gdb-6d6c25c8eaaf42755a759beeb2996502322b960c.tar.bz2
binutils-gdb-6d6c25c8eaaf42755a759beeb2996502322b960c.zip
elf_backend_modify_headers
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.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r--bfd/elf.c76
1 files changed, 41 insertions, 35 deletions
diff --git a/bfd/elf.c b/bfd/elf.c
index e10099842b8..d1815e15264 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. */