PR4499, assign file positions assumes segment offsets increasing

This rewrites much of assign_file_positions_for_non_load_sections to
allow objcopy and strip to handle cases like that in PR4499 where
program headers were not in their usual position immediately after the
ELF file header, and PT_LOAD headers were not sorted by paddr.

	PR 4499
include/
	* elf/internal.h (struct elf_segment_map): Delete header_size.
	Add no_sort_lma and idx.
bfd/
	* elf-nacl.c (nacl_modify_segment_map): Set no_sort_lma for all
	PT_LOAD segments.
	* elf32-spu.c (spu_elf_modify_segment_map): Likewise on overlay
	PT_LOAD segments.
	* elf.c (elf_sort_segments): New function.
	(assign_file_positions_except_relocs): Use shortcuts to elfheader
	and elf_tdata.  Seek to e_phoff not sizeof_ehdr to write program
	headers.  Move PT_PHDR check..
	(assign_file_positions_for_non_load_sections): ..and code setting
	PT_PHDR p_vaddr and p_paddr, and code setting __ehdr_start value..
	(assign_file_positions_for_load_sections): ..to here.  Sort
	PT_LOAD headers.  Delete header_pad code.  Use actual number of
	headers rather than allocated in calculating size for program
	headers.  Don't assume program headers follow ELF file header.
	Simplify pt_load_count code.  Only set "off" for PT_LOAD or
	PT_NOTE in cores.
	(rewrite_elf_program_header): Set p_vaddr_offset for segments
	that include file and program headers.
	(copy_elf_program_header): Likewise, replacing header_size code.
This commit is contained in:
Alan Modra
2019-10-23 17:40:51 +10:30
parent c0c121b01c
commit 30fe183248
6 changed files with 299 additions and 239 deletions

View File

@ -273,8 +273,6 @@ struct elf_segment_map
bfd_vma p_align;
/* Segment size in file and memory */
bfd_vma p_size;
/* Required size of filehdr + phdrs, if non-zero */
bfd_vma header_size;
/* Whether the p_flags field is valid; if not, the flags are based
on the section flags. */
unsigned int p_flags_valid : 1;
@ -291,6 +289,13 @@ struct elf_segment_map
unsigned int includes_filehdr : 1;
/* Whether this segment includes the program headers. */
unsigned int includes_phdrs : 1;
/* Assume this PT_LOAD header has an lma of zero when sorting
headers before assigning file offsets. PT_LOAD headers with this
flag set are placed after one with includes_filehdr set, and
before PT_LOAD headers without this flag set. */
unsigned int no_sort_lma : 1;
/* Index holding original order before sorting segments. */
unsigned int idx;
/* Number of sections (may be 0). */
unsigned int count;
/* Sections. Actual number of elements is in count field. */