From a76e6f2fc1f2242809ec35fa2fe42fd67f2610eb Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 30 Aug 2010 06:01:22 +0000 Subject: [PATCH] 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. --- bfd/ChangeLog | 10 +++++++++- bfd/elf.c | 49 +++++++++++++++++++++++++++++++++---------------- 2 files changed, 42 insertions(+), 17 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 32cc1750377..603af38778a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2010-08-30 Alan Modra + + 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. + 2010-08-28 Alan Modra * elflink.c (_bfd_elf_dynamic_symbol_p): Rename param. Make @@ -191,7 +199,7 @@ elf_tdata's core_lwpid instead of to core_pid. * elfn32-mips.c (elf32_mips_grok_prstatus): Write the LWPID to elf_tdata's core_lwpid instead of to core_pid. - + * plugin.c (bfd_plugin_core_file_pid): New function. * aout-target.h (MY_core_file_pid): Define. * aout-tic30.c (MY_core_file_pid, MY_core_file_p): New defines. diff --git a/bfd/elf.c b/bfd/elf.c index f4e505876a4..c9e9fab85e5 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -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; -- 2.30.2