[binutils-gdb] Use p_vaddr_offset to set p_vaddr on segments without sections

Alan Modra amodra@sourceware.org
Mon Oct 8 10:03:00 GMT 2018


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=5d695627883b32cf33adb529c8fc7271b46dcf55

commit 5d695627883b32cf33adb529c8fc7271b46dcf55
Author: Alan Modra <amodra@gmail.com>
Date:   Sat Oct 6 12:24:28 2018 +0930

    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.

Diff:
---
 bfd/ChangeLog |  9 +++++++++
 bfd/elf.c     | 23 +++++++++++++----------
 2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 3d6796b..5276305 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,14 @@
 2018-10-08  Alan Modra  <amodra@gmail.com>
 
+	* 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.
+
+2018-10-08  Alan Modra  <amodra@gmail.com>
+
 	* elf.c (get_program_header_size): Don't count PT_INTERP if
 	.interp is empty.
 	(_bfd_elf_map_sections_to_segments): Don't create PT_INTERP if
diff --git a/bfd/elf.c b/bfd/elf.c
index fe43c9f..742a52e 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -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;



More information about the Binutils-cvs mailing list