diff options
author | Alan Modra <amodra@gmail.com> | 2010-08-30 06:01:22 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2010-08-30 06:01:22 +0000 |
commit | a76e6f2fc1f2242809ec35fa2fe42fd67f2610eb (patch) | |
tree | bc92ef27ecda222d14accb2e9552a35f73cb12be /bfd/elf.c | |
parent | 48cb5944c5776da8fbcec9d24668b700e60607e6 (diff) | |
download | binutils-a76e6f2fc1f2242809ec35fa2fe42fd67f2610eb.zip binutils-a76e6f2fc1f2242809ec35fa2fe42fd67f2610eb.tar.gz binutils-a76e6f2fc1f2242809ec35fa2fe42fd67f2610eb.tar.bz2 |
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.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r-- | bfd/elf.c | 49 |
1 files changed, 33 insertions, 16 deletions
@@ -5870,7 +5870,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd) 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 *obfd) 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 *obfd) 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 *obfd) 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; |