Patch to the way BFD reads overlaid ELF sections
Richard Sandiford
rsandifo@redhat.com
Wed May 1 11:27:00 GMT 2002
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;
}
}
}
More information about the Binutils
mailing list