This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: VMA section overlap warnings for overlays
- From: Alan Modra <amodra at gmail dot com>
- To: "H.J. Lu" <hjl dot tools at gmail dot com>, binutils at sourceware dot org
- Date: Sat, 28 Aug 2010 22:58:36 +0930
- Subject: Re: VMA section overlap warnings for overlays
- References: <4D60B0700D1DB54A8C0C6E9BE69163700E67DFD1@EXCHANGEVS.IceraSemi.local> <20100421082441.GG3510@bubble.grove.modra.org> <4D60B0700D1DB54A8C0C6E9BE69163700E7815C7@EXCHANGEVS.IceraSemi.local> <20100422011106.GI3510@bubble.grove.modra.org> <20100422015303.GK3510@bubble.grove.modra.org> <AANLkTimSJqoCMEiVcU_VJx3RNLxzNeo16MJ5pj-9YZ47@mail.gmail.com> <20100828105631.GW15723@bubble.grove.modra.org>
The real bug was that copy_elf_program_header calculated header_size
from the first section found to be in the segment rather than the
section with the lowest lma. So a one line fix. The rest of this
patch is to cope with (and fix) invalid program header p_paddr values.
I won't commit this immediately as I'd like to run some more tests.
PR binutils/11953
* elf.c (copy_elf_program_header): Calculate map->header_size
from lowest_section, not first_section. Validate program
header p_paddr against section lma. Find lowest_section in
second loop over headers.
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.517
diff -u -p -r1.517 elf.c
--- bfd/elf.c 25 Aug 2010 14:53:40 -0000 1.517
+++ bfd/elf.c 28 Aug 2010 12:57:00 -0000
@@ -5870,7 +5870,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;
+ asection *lowest_section;
/* Compute how many sections are in this segment. */
for (section = ibfd->sections, section_count = 0;
@@ -5880,10 +5880,8 @@ copy_elf_program_header (bfd *ibfd, bfd
this_hdr = &(elf_section_data(section)->this_hdr);
if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
{
- if (!first_section)
- first_section = lowest_section = section;
- if (section->lma < lowest_section->lma)
- lowest_section = section;
+ if (first_section == NULL)
+ first_section = section;
section_count++;
}
}
@@ -5937,17 +5935,7 @@ copy_elf_program_header (bfd *ibfd, bfd
phdr_included = TRUE;
}
- if (map->includes_filehdr && first_section)
- /* We need to keep the space used by the headers fixed. */
- map->header_size = first_section->vma - segment->p_vaddr;
-
- if (!map->includes_phdrs
- && !map->includes_filehdr
- && map->p_paddr_valid)
- /* There is some other padding before the first section. */
- map->p_vaddr_offset = ((lowest_section ? lowest_section->lma : 0)
- - segment->p_paddr);
-
+ lowest_section = first_section;
if (section_count != 0)
{
unsigned int isec = 0;
@@ -5960,12 +5948,41 @@ copy_elf_program_header (bfd *ibfd, bfd
if (ELF_SECTION_IN_SEGMENT (this_hdr, segment))
{
map->sections[isec++] = section->output_section;
+ if (section->lma < lowest_section->lma)
+ lowest_section = section;
+ if ((section->flags & SEC_ALLOC) != 0)
+ {
+ bfd_vma seg_off;
+
+ /* Section lmas are set up from PT_LOAD header
+ p_paddr in _bfd_elf_make_section_from_shdr.
+ If this header has a p_paddr that disagrees
+ with the section lma, flag the p_paddr as
+ invalid. */
+ if ((section->flags & SEC_LOAD) != 0)
+ seg_off = this_hdr->sh_offset - segment->p_offset;
+ else
+ seg_off = this_hdr->sh_addr - segment->p_vaddr;
+ if (section->lma - segment->p_paddr != seg_off)
+ map->p_paddr_valid = FALSE;
+ }
if (isec == section_count)
break;
}
}
}
+ if (map->includes_filehdr && lowest_section != NULL)
+ /* We need to keep the space used by the headers fixed. */
+ map->header_size = lowest_section->vma - segment->p_vaddr;
+
+ if (!map->includes_phdrs
+ && !map->includes_filehdr
+ && map->p_paddr_valid)
+ /* There is some other padding before the first section. */
+ map->p_vaddr_offset = ((lowest_section ? lowest_section->lma : 0)
+ - segment->p_paddr);
+
map->count = section_count;
*pointer_to_map = map;
pointer_to_map = &map->next;
--
Alan Modra
Australia Development Lab, IBM