diff options
author | Alan Modra <amodra@gmail.com> | 2018-10-06 12:24:28 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2018-10-08 20:26:08 +1030 |
commit | 5d695627883b32cf33adb529c8fc7271b46dcf55 (patch) | |
tree | 4baf2317406f3ca458656472fcd8812edde379be /bfd/elf.c | |
parent | 1b9e270b09c140464a7892c95c28eafa812c6b08 (diff) | |
download | gdb-5d695627883b32cf33adb529c8fc7271b46dcf55.zip gdb-5d695627883b32cf33adb529c8fc7271b46dcf55.tar.gz gdb-5d695627883b32cf33adb529c8fc7271b46dcf55.tar.bz2 |
Use p_vaddr_offset to set p_vaddr on segments without sections
p_vaddr is currently set from the first section vma if a segment has
sections, and to zero if a segment has no sections. This means we
lose p_vaddr when objcopy'ing executables if a segment without
sections has a non-zero p_vaddr.
This patch saves p_vaddr to p_vaddr_offset, and to make the use of
p_vaddr_offset consistent, inverts the sign. (It's now added to
section vma to get segment vaddr, and added to zero when there are no
sections.)
* elf.c (assign_file_positions_for_load_sections): Set p_vaddr
from m->p_vaddr_offset for segments without sections. Invert
sign of p_vaddr_offset.
(rewrite_elf_program_header, copy_elf_program_header): Save
old segment p_vaddr to p_vaddr_offset. Invert sign of
p_vaddr_offset.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r-- | bfd/elf.c | 23 |
1 files changed, 13 insertions, 10 deletions
@@ -5358,16 +5358,16 @@ assign_file_positions_for_load_sections (bfd *abfd, p->p_flags = m->p_flags; if (m->count == 0) - p->p_vaddr = 0; + p->p_vaddr = m->p_vaddr_offset; else - p->p_vaddr = m->sections[0]->vma - m->p_vaddr_offset; + p->p_vaddr = m->sections[0]->vma + m->p_vaddr_offset; if (m->p_paddr_valid) p->p_paddr = m->p_paddr; else if (m->count == 0) p->p_paddr = 0; else - p->p_paddr = m->sections[0]->lma - m->p_vaddr_offset; + p->p_paddr = m->sections[0]->lma + m->p_vaddr_offset; if (p->p_type == PT_LOAD && (abfd->flags & D_PAGED) != 0) @@ -6881,6 +6881,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) " at vaddr=%#" PRIx64 ", is this intentional?"), ibfd, (uint64_t) segment->p_vaddr); + map->p_vaddr_offset = segment->p_vaddr; map->count = 0; *pointer_to_map = map; pointer_to_map = &map->next; @@ -7005,7 +7006,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd) /* There is some padding before the first section in the segment. So, we must account for that in the output segment's vma. */ - map->p_vaddr_offset = matching_lma->lma - map->p_paddr; + map->p_vaddr_offset = map->p_paddr - matching_lma->lma; free (sections); continue; @@ -7367,12 +7368,14 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) map->header_size = lowest_section->filepos; } - if (!map->includes_phdrs - && !map->includes_filehdr - && map->p_paddr_valid) - /* There is some other padding before the first section. */ - map->p_vaddr_offset = ((lowest_section ? lowest_section->lma : 0) - - segment->p_paddr); + if (section_count == 0) + map->p_vaddr_offset = segment->p_vaddr; + else if (!map->includes_phdrs + && !map->includes_filehdr + && map->p_paddr_valid) + /* Account for padding before the first section. */ + map->p_vaddr_offset = (segment->p_paddr + - (lowest_section ? lowest_section->lma : 0)); map->count = section_count; *pointer_to_map = map; |