Fix several mix up between octets and bytes in ELF program headers

When converting between addresses in ELF headers [octets] and bfd
LMA/VMA [bytes], the number of octets per byte needs to be
incorporated.

In ld, the SIZEOF_HEADERS linker script statement must be resolved to
bytes instead of octets.

include/
	* elf/internal.h (struct elf_internal_phdr): Add unit (octets)
	to several member field comments.
	(Elf_Internal_Shdr): likewise.
bfd/
	* elf.c (_bfd_elf_make_section_from_shdr): Introduce new temp
	opb.  Divide Elf_Internal_Shdr::sh_addr by opb when setting
	section LMA/VMA.
	(_bfd_elf_make_section_from_phdr): Similarly.
	(elf_fake_sections): Fix calculation of
	Elf_Internal_shdr::sh_addr from section VMA.
	(_bfd_elf_map_sections_to_segments): Fix mixup between octets
	and bytes.
	(assign_file_positions_for_load_sections): Fix calculations of
	Elf_Internal_shdr::p_vaddr and p_paddr from section LMA/VMA.  Fix
	comparison between program header address and section LMA.
	(assign_file_positions_for_non_load_sections): Likewise.
	(rewrite_elf_program_header): Likewise.  Introduce new temp opb.
	(IS_CONTAINED_BY_VMA): Add parameter opb.
	(IS_CONTAINED_BY_LMA,IS_SECTION_IN_INPUT_SEGMENT,
	INCLUDE_SECTION_IN_SEGMENT): Likewise.
	(copy_elf_program_header): Update call to ELF_SECTION_IN_SEGMENT.
	Fix calculations of p_addr_valid and p_vaddr_offset.
	* elflink.c (elf_link_add_object_symbols): Multiply section VMA
	with octets per byte when comparing against p_vaddr.
ld/
	* ldexp.c (fold_name): Return SIZEOF_HEADERS in bytes.
This commit is contained in:
Christian Eggers
2020-03-02 20:11:00 +00:00
committed by Alan Modra
parent fd486f32d1
commit 502794d432
7 changed files with 131 additions and 73 deletions

View File

@@ -84,14 +84,14 @@ typedef struct elf_internal_ehdr {
/* Program header */
struct elf_internal_phdr {
unsigned long p_type; /* Identifies program segment type */
unsigned long p_flags; /* Segment flags */
bfd_vma p_offset; /* Segment file offset */
bfd_vma p_vaddr; /* Segment virtual address */
bfd_vma p_paddr; /* Segment physical address */
bfd_vma p_filesz; /* Segment size in file */
bfd_vma p_memsz; /* Segment size in memory */
bfd_vma p_align; /* Segment alignment, file & memory */
unsigned long p_type; /* Identifies program segment type. */
unsigned long p_flags; /* Segment flags. */
bfd_vma p_offset; /* Segment file offset in octets. */
bfd_vma p_vaddr; /* Segment virtual address in octets. */
bfd_vma p_paddr; /* Segment physical address in octets. */
bfd_vma p_filesz; /* Segment size in file in octets. */
bfd_vma p_memsz; /* Segment size in memory in octets. */
bfd_vma p_align; /* Segment alignment, file & memory. */
};
typedef struct elf_internal_phdr Elf_Internal_Phdr;
@@ -102,9 +102,10 @@ typedef struct elf_internal_shdr {
unsigned int sh_name; /* Section name, index in string tbl */
unsigned int sh_type; /* Type of section */
bfd_vma sh_flags; /* Miscellaneous section attributes */
bfd_vma sh_addr; /* Section virtual addr at execution */
file_ptr sh_offset; /* Section file offset */
bfd_size_type sh_size; /* Size of section in bytes */
bfd_vma sh_addr; /* Section virtual addr at execution in
octets. */
file_ptr sh_offset; /* Section file offset in octets. */
bfd_size_type sh_size; /* Size of section in octets. */
unsigned int sh_link; /* Index of another section */
unsigned int sh_info; /* Additional section information */
bfd_vma sh_addralign; /* Section alignment */
@@ -267,7 +268,7 @@ struct elf_segment_map
unsigned long p_flags;
/* Program segment physical address. */
bfd_vma p_paddr;
/* Program segment virtual address offset from section vma. */
/* Program segment virtual address offset from section vma in bytes. */
bfd_vma p_vaddr_offset;
/* Program segment alignment. */
bfd_vma p_align;