bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RFC: Do not ignore segments with LMA of 0 when loading ELF binaries


From: Nick Clifton
Subject: RFC: Do not ignore segments with LMA of 0 when loading ELF binaries
Date: 05 Feb 2002 15:00:08 +0000

Hi Guys,

  One of the developers at Red Hat came across a problem with ARM ELF
  binaries where the bfd library was incorrectly assigning the LMA of
  one section to be its VMA.  The problem was that the section was
  assigned to a segment whose LMA was 0, and so bfd, assuming that
  this was an uninitialised segment, refused to reset the LMA from the
  VMA.

  The effect of this was that when they ran objcopy to convert the
  executable into the binary format they saw this error message:

    BFD: Warning: Writing section `.rom_vectors' to huge (ie negative)
     file offset 0x9fffe000.

  Objdump also shows the same problem:

    Idx Name          Size      VMA       LMA       File off  Algn
      7 .rom_vectors  00000040  a0000000  a0000000  00008000  2**0

  ie it incorrectly has the LMA set to the same address as the VMA.
  But readelf gets it right:

  Section Headers:
    [Nr] Name              Type            Addr     Off    Size  
    [ 8] .rom_vectors      PROGBITS        a0000000 008000 000040

  Program Headers:
    Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  
    LOAD           0x008000 0xa0000000 0x00000000 0x00040 0x00040

   Section to Segment mapping:
    Segment Sections...
     00     .rom_vectors

  The problem is this piece of code in
  _bfd_elf_make_section_from_shdr():

      /* This section is part of this segment if its file
         offset plus size lies within the segment's memory
         span and, if the section is loaded, the extent of the
         loaded data lies within the extent of the segment.  
         If the p_paddr field is not set, we don't alter the 
         LMA.  */
      if (phdr->p_type == PT_LOAD
          && phdr->p_paddr
          && (bfd_vma) hdr->sh_offset >= phdr->p_offset

  The test for a non-zero p_paddr is wrong.  An earlier comment in the
  code said this:

      /* Look through the phdrs to see if we need to adjust the lma.
         If all the p_paddr fields are zero, we ignore them, since
         some ELF linkers produce such output.  */

  But the code checks to see if *all* the p_paddr's are zero, in which
  case it is reasonable to assume that they have not been
  initialised.  But in this case only one segment has a zero physical
  address, all the others are non-zero, and the zero-addressed segment
  has been correctly initialised.

  I would like to remove the test for a non-zero p_paddr (see the
  proposed patch below) but before I do so I would like to check to
  see if anyone knows if this would break anything.

  I ran the ld and binutils testsuites for the x86 native toolchain
  and this patch did not introduce any new failures.

Cheers
        Nick

2002-02-05  Nick Clifton  <address@hidden>

        * elf.c (_bfd_elf_make_section_from_shdr): Do not insist on
        non-zero physical addresses when adjusting the LMAs of new
        sections.

Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.127
diff -c -3 -p -w -r1.127 elf.c
*** elf.c       2002/01/30 10:31:28     1.127
--- elf.c       2002/02/05 12:32:08
*************** _bfd_elf_make_section_from_shdr (abfd, h
*** 652,661 ****
                 offset plus size lies within the segment's memory
                 span and, if the section is loaded, the extent of the
                 loaded data lies within the extent of the segment.  
!                If the p_paddr field is not set, we don't alter the 
!                LMA.  */
              if (phdr->p_type == PT_LOAD
-                 && phdr->p_paddr
                  && (bfd_vma) hdr->sh_offset >= phdr->p_offset
                  && (hdr->sh_offset + hdr->sh_size
                      <= phdr->p_offset + phdr->p_memsz)
--- 652,666 ----
                 offset plus size lies within the segment's memory
                 span and, if the section is loaded, the extent of the
                 loaded data lies within the extent of the segment.  
! 
!                Note - we used to check the p_paddr field as well, and
!                refuse to set the LMA if it was 0.  This is wrong
!                though as a perfectly valid, initialised segment can
!                have a p_paddr of zero.  Some architectures, eg ARM,
!                place special significance one the address 0 and
!                executables need to be able to have a segment which
!                covers this address.  */
              if (phdr->p_type == PT_LOAD
                  && (bfd_vma) hdr->sh_offset >= phdr->p_offset
                  && (hdr->sh_offset + hdr->sh_size
                      <= phdr->p_offset + phdr->p_memsz)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]