Fix strip when sections are not sorted

Daniel Jacobowitz drow@false.org
Wed Jul 25 15:46:00 GMT 2007


I don't see anything in the gABI that requires sections to be sorted
by increasing address in the section table, and I can get GNU ld to
produce files where this is not the case; e.g. linking a shared
library with -Tbss will put .bss first in the section table, even if
you specify a high address.  Stripping such files fails, because we
assume the first section we encounter sets the base for the containing
segment.  Later on we discover that .data's file offset does not fit
in the segment, because .data has a lower address than the adjusted
.bss.

I think we should use the lowest section address, rather than the
first section encountered.  Is this patch OK?

-- 
Daniel Jacobowitz
CodeSourcery

2007-07-25  Daniel Jacobowitz  <dan@codesourcery.com>

	* elf.c (rewrite_elf_program_header): Handle sections not sorted
	by address.
	(copy_elf_program_header): Likewise.

---
 bfd/elf.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

Index: binutils-2.17.50/bfd/elf.c
===================================================================
--- binutils-2.17.50.orig/bfd/elf.c	2007-07-25 08:12:44.000000000 -0700
+++ binutils-2.17.50/bfd/elf.c	2007-07-25 08:14:31.000000000 -0700
@@ -5605,7 +5605,7 @@ rewrite_elf_program_header (bfd *ibfd, b
 		      IS_CONTAINED_BY_VMA (output_section, segment))
                 )
 		{
-		  if (matching_lma == 0)
+		  if (matching_lma == 0 || output_section->lma < matching_lma)
 		    matching_lma = output_section->lma;
 
 		  /* We assume that if the section fits within the segment
@@ -5858,6 +5858,7 @@ copy_elf_program_header (bfd *ibfd, bfd 
       bfd_size_type amt;
       Elf_Internal_Shdr *this_hdr;
       asection *first_section = NULL;
+      asection *lowest_section = NULL;
 
       /* FIXME: Do we need to copy PT_NULL segment?  */
       if (segment->p_type == PT_NULL)
@@ -5872,7 +5873,9 @@ copy_elf_program_header (bfd *ibfd, bfd 
 	  if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment))
 	    {
 	      if (!first_section)
-		first_section = section;
+		first_section = lowest_section = section;
+	      if (section->vma < lowest_section->vma)
+		lowest_section = section;
 	      section_count++;
 	    }
 	}
@@ -5918,7 +5921,7 @@ copy_elf_program_header (bfd *ibfd, bfd 
 
       if (!map->includes_phdrs && !map->includes_filehdr)
 	/* There is some other padding before the first section.  */
-	map->p_vaddr_offset = ((first_section ? first_section->lma : 0)
+	map->p_vaddr_offset = ((lowest_section ? lowest_section->lma : 0)
 			       - segment->p_paddr);
       
       if (section_count != 0)



More information about the Binutils mailing list