PR binutils/11953
authorAlan Modra <amodra@gmail.com>
Mon, 30 Aug 2010 06:01:22 +0000 (06:01 +0000)
committerAlan Modra <amodra@gmail.com>
Mon, 30 Aug 2010 06:01:22 +0000 (06:01 +0000)
* 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
bfd/elf.c

index 32cc17503773479a800b87cc5b1e96d955d433d5..603af38778acb0ee690fe1dc4a93ddb22f3f5efd 100644 (file)
@@ -1,3 +1,11 @@
+2010-08-30  Alan Modra  <amodra@gmail.com>
+
+       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  <amodra@gmail.com>
 
        * elflink.c (_bfd_elf_dynamic_symbol_p): Rename param.  Make
        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.
index f4e505876a48ded9de93a34da434689cad0245a6..c9e9fab85e553ad6d15e99f6e86b0647e2c96d30 100644 (file)
--- 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;