diff options
author | Alan Modra <amodra@gmail.com> | 2019-11-18 17:09:01 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2019-11-18 22:06:09 +1030 |
commit | 6d6c25c8eaaf42755a759beeb2996502322b960c (patch) | |
tree | 3ec735f2069634d339bde6d46dab7a7c758eb164 /bfd/elf.c | |
parent | PR25196, abort in rewrite_elf_program_header (diff) | |
download | binutils-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.c | 76 |
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. */ |