This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

cope with leading segment padding


As I wrote at http://sourceware.org/ml/binutils/2006-12/msg00137.html objcopy & objstrip were failing on a foreign executable due to leading padding in a segment.

This patch fixes objcopy and strip to cope with that. I've tested on arm-wrs-vxworks and i686-linux-gnu with no regressions. I can't readily produce a testcase for this problem, because binutils won't produce such an elf file.

ok?

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2006-12-14  Nathan Sidwell  <nathan@codesourcery.com>

	bfd/
	* elf.c (assign_file_positions_for_load_sections): Adjust p_vaddr
	by p_vaddr_offset.  Copy alignment & use if it is valid.
	(rewrite_elf_program_headers): Cope with leading padding in a
	segment that does not contain file or program headers.
	(copy_elf_program_header): Likewise.

	include/elf/
	* internal.h (struct elf_segment_map): Add p_vaddr_offset field.

Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.368
diff -c -3 -p -r1.368 elf.c
*** bfd/elf.c	1 Dec 2006 15:55:29 -0000	1.368
--- bfd/elf.c	14 Dec 2006 09:57:28 -0000
*************** assign_file_positions_for_load_sections 
*** 4326,4332 ****
        if (m->count == 0)
  	p->p_vaddr = 0;
        else
! 	p->p_vaddr = m->sections[0]->vma;
  
        if (m->p_paddr_valid)
  	p->p_paddr = m->p_paddr;
--- 4326,4332 ----
        if (m->count == 0)
  	p->p_vaddr = 0;
        else
! 	p->p_vaddr = m->sections[0]->vma - m->p_vaddr_offset;
  
        if (m->p_paddr_valid)
  	p->p_paddr = m->p_paddr;
*************** assign_file_positions_for_load_sections 
*** 4353,4358 ****
--- 4353,4360 ----
  	}
        else if (m->count == 0)
  	p->p_align = 1 << bed->s->log_file_align;
+       else if (m->p_align_valid)
+ 	p->p_align = m->p_align;
        else
  	p->p_align = 0;
  
*************** assign_file_positions_for_load_sections 
*** 4363,4380 ****
  	  bfd_vma adjust;
  	  unsigned int align_power = 0;
  
! 	  for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
  	    {
! 	      unsigned int secalign;
! 
! 	      secalign = bfd_get_section_alignment (abfd, *secpp);
! 	      if (secalign > align_power)
! 		align_power = secalign;
  	    }
- 	  align = (bfd_size_type) 1 << align_power;
- 
- 	  if (align < maxpagesize)
- 	    align = maxpagesize;
  
  	  adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align);
  	  off += adjust;
--- 4365,4386 ----
  	  bfd_vma adjust;
  	  unsigned int align_power = 0;
  
! 	  if (m->p_align_valid)
! 	    align = p->p_align;
! 	  else
  	    {
! 	      for (i = 0, secpp = m->sections; i < m->count; i++, secpp++)
! 		{
! 		  unsigned int secalign;
! 		  
! 		  secalign = bfd_get_section_alignment (abfd, *secpp);
! 		  if (secalign > align_power)
! 		    align_power = secalign;
! 		}
! 	      align = (bfd_size_type) 1 << align_power;
! 	      if (align < maxpagesize)
! 		align = maxpagesize;
  	    }
  
  	  adjust = vma_page_aligned_bias (m->sections[0]->vma, off, align);
  	  off += adjust;
*************** assign_file_positions_for_load_sections 
*** 4605,4610 ****
--- 4611,4617 ----
  	      if (p->p_type == PT_GNU_RELRO)
  		p->p_align = 1;
  	      else if (align > p->p_align
+ 		       && !m->p_align_valid
  		       && (p->p_type != PT_LOAD
  			   || (abfd->flags & D_PAGED) == 0))
  		p->p_align = align;
*************** rewrite_elf_program_header (bfd *ibfd, b
*** 5581,5587 ****
  	  map->count = section_count;
  	  *pointer_to_map = map;
  	  pointer_to_map = &map->next;
! 
  	  free (sections);
  	  continue;
  	}
--- 5588,5601 ----
  	  map->count = section_count;
  	  *pointer_to_map = map;
  	  pointer_to_map = &map->next;
! 	  
! 	  if (matching_lma != map->p_paddr
! 	      && !map->includes_filehdr && !map->includes_phdrs)
! 	    /* 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 - map->p_paddr;
! 	  
  	  free (sections);
  	  continue;
  	}
*************** copy_elf_program_header (bfd *ibfd, bfd 
*** 5800,5805 ****
--- 5814,5820 ----
        unsigned int section_count;
        bfd_size_type amt;
        Elf_Internal_Shdr *this_hdr;
+       bfd_vma first_lma = 0;
  
        /* FIXME: Do we need to copy PT_NULL segment?  */
        if (segment->p_type == PT_NULL)
*************** copy_elf_program_header (bfd *ibfd, bfd 
*** 5812,5818 ****
  	{
  	  this_hdr = &(elf_section_data(section)->this_hdr);
  	  if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment))
! 	    section_count++;
  	}
  
        /* Allocate a segment map big enough to contain
--- 5827,5837 ----
  	{
  	  this_hdr = &(elf_section_data(section)->this_hdr);
  	  if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment))
! 	    {
! 	      if (!section_count || section->lma < first_lma)
! 		first_lma = section->lma;
! 	      section_count++;
! 	    }
  	}
  
        /* Allocate a segment map big enough to contain
*************** copy_elf_program_header (bfd *ibfd, bfd 
*** 5834,5839 ****
--- 5853,5859 ----
        map->p_paddr_valid = 1;
        map->p_align = segment->p_align;
        map->p_align_valid = 1;
+       map->p_vaddr_offset = 0;
  
        /* Determine if this segment contains the ELF file header
  	 and if it contains the program headers themselves.  */
*************** copy_elf_program_header (bfd *ibfd, bfd 
*** 5853,5858 ****
--- 5873,5882 ----
  	    phdr_included = TRUE;
  	}
  
+       if (!map->includes_phdrs && !map->includes_filehdr)
+ 	/* There is some other padding before the first section.  */
+ 	map->p_vaddr_offset = first_lma - segment->p_paddr;
+       
        if (section_count != 0)
  	{
  	  unsigned int isec = 0;
Index: include/elf/internal.h
===================================================================
RCS file: /cvs/src/src/include/elf/internal.h,v
retrieving revision 1.15
diff -c -3 -p -r1.15 internal.h
*** include/elf/internal.h	1 Jun 2006 05:40:24 -0000	1.15
--- include/elf/internal.h	14 Dec 2006 09:57:35 -0000
*************** struct elf_segment_map
*** 235,240 ****
--- 235,242 ----
    unsigned long p_flags;
    /* Program segment physical address.  */
    bfd_vma p_paddr;
+   /* Program segment virtual address offset from section vma.  */
+   bfd_vma p_vaddr_offset;
    /* Program segment alignment.  */
    bfd_vma p_align;
    /* Whether the p_flags field is valid; if not, the flags are based

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]