This is the mail archive of the binutils@sources.redhat.com 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]

Patch to the way BFD reads overlaid ELF sections


The overlay-size test I sent in my previous mail produces an executable
with the following segments:

  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  [...]
  LOAD           0x002000 0x00020000 0x00020000 0x00000 0x00010 RW  0x1000
  LOAD           0x002000 0x00020000 0x00020010 0x00000 0x00030 RW  0x1000
  LOAD           0x002000 0x00020000 0x00020040 0x00000 0x00020 RW  0x1000
  [...]

These segments are associated with the sections .bss1, .bss2 and .bss3
respectively.  They all have the same VMA, and the second is larger
than the third.

When mapping sections to segments, the ELF reader stops on the first
segment that matches.  So in this case it maps .bss3 to the second
segment rather than the third, and hence gives it the wrong LMA:

Idx Name          Size      VMA       LMA       File off  Algn
  0 .bss1         00000010  00020000  00020000  00002000  2**0
                  ALLOC
  1 .bss2         00000030  00020000  00020010  00002000  2**0
                  ALLOC
  2 .bss3         00000020  00020000  00020010  00002000  2**0
                  ALLOC
  [...]

One fix would be to check all the matching segments and base
the LMA on the smallest one.  Is that likely to cause any
problems?

Patch tested on the same targets as the OVERLAY patch, and fixes the
objdump part of that test case.

Richard

	* elf.c (_bfd_elf_make_section_from_shdr): Base the LMA on the
	smallest matching segment.

Index: elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.137
diff -c -p -d -r1.137 elf.c
*** elf.c	12 Apr 2002 03:30:56 -0000	1.137
--- elf.c	1 May 2002 16:07:32 -0000
*************** _bfd_elf_make_section_from_shdr (abfd, h
*** 645,651 ****
--- 645,654 ----
  	}
        if (i < elf_elfheader (abfd)->e_phnum)
  	{
+ 	  Elf_Internal_Phdr *chosen_phdr;
+ 
  	  phdr = elf_tdata (abfd)->phdr;
+ 	  chosen_phdr = 0;
  	  for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++)
  	    {
  	      /* This section is part of this segment if its file
*************** _bfd_elf_make_section_from_shdr (abfd, h
*** 666,672 ****
  		      <= phdr->p_offset + phdr->p_memsz)
  		  && ((flags & SEC_LOAD) == 0
  		      || (hdr->sh_offset + hdr->sh_size
! 			  <= phdr->p_offset + phdr->p_filesz)))
  		{
  		  if ((flags & SEC_LOAD) == 0)
  		    newsect->lma = (phdr->p_paddr
--- 669,677 ----
  		      <= phdr->p_offset + phdr->p_memsz)
  		  && ((flags & SEC_LOAD) == 0
  		      || (hdr->sh_offset + hdr->sh_size
! 			  <= phdr->p_offset + phdr->p_filesz))
! 		  && (chosen_phdr == 0
! 		      || chosen_phdr->p_memsz > phdr->p_memsz))
  		{
  		  if ((flags & SEC_LOAD) == 0)
  		    newsect->lma = (phdr->p_paddr
*************** _bfd_elf_make_section_from_shdr (abfd, h
*** 689,695 ****
  		  if (hdr->sh_addr >= phdr->p_vaddr
  		      && (hdr->sh_addr + hdr->sh_size
  			  <= phdr->p_vaddr + phdr->p_memsz))
! 		    break;
  		}
  	    }
  	}
--- 694,700 ----
  		  if (hdr->sh_addr >= phdr->p_vaddr
  		      && (hdr->sh_addr + hdr->sh_size
  			  <= phdr->p_vaddr + phdr->p_memsz))
! 		    chosen_phdr = phdr;
  		}
  	    }
  	}


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