]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
* Import this patch from the mainline:
authorNick Clifton <nickc@redhat.com>
Tue, 23 Dec 2008 10:06:46 +0000 (10:06 +0000)
committerNick Clifton <nickc@redhat.com>
Tue, 23 Dec 2008 10:06:46 +0000 (10:06 +0000)
        2008-11-10  Andreas Schwab  <schwab@suse.de>

        PR 7011
        * elf.c (assign_file_positions_for_non_load_sections): Handle
        PT_GNU_RELRO specially.

bfd/ChangeLog
bfd/elf.c

index f621b3dca4458209f3b4d908554ebd4b196b70ae..51362e3efa0eb180e8ec069e1de9d444d6c3fc06 100644 (file)
@@ -1,3 +1,12 @@
+2008-12-23  Nick Clifton  <nickc@redhat.com>
+
+       * Import this patch from the mainline:
+       2008-11-10  Andreas Schwab  <schwab@suse.de>
+
+       PR 7011
+       * elf.c (assign_file_positions_for_non_load_sections): Handle
+       PT_GNU_RELRO specially.
+
 2008-11-20  Alan Modra  <amodra@bigpond.net.au>
 
        * elf32-ppc.c (allocate_dynrelocs): Always use tlsld_got for
index 6406b740519842b387bca10f0736d21d7aa94d4e..8639a5d565260ffca2318dd6c6a5eabf6451ffa9 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -4606,7 +4606,61 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
        m != NULL;
        m = m->next, p++)
     {
-      if (m->count != 0)
+      if (p->p_type == PT_GNU_RELRO)
+       {
+         const Elf_Internal_Phdr *lp;
+
+         BFD_ASSERT (!m->includes_filehdr && !m->includes_phdrs);
+
+         if (link_info != NULL)
+           {
+             /* During linking the range of the RELRO segment is passed
+                in link_info.  */
+             for (lp = phdrs; lp < phdrs + count; ++lp)
+               {
+                 if (lp->p_type == PT_LOAD
+                     && lp->p_vaddr >= link_info->relro_start
+                     && lp->p_vaddr < link_info->relro_end
+                     && lp->p_vaddr + lp->p_filesz >= link_info->relro_end)
+                   break;
+               }
+           }
+         else
+           {
+             /* Otherwise we are copying an executable or shared
+                library, but we need to use the same linker logic.  */
+             for (lp = phdrs; lp < phdrs + count; ++lp)
+               {
+                 if (lp->p_type == PT_LOAD
+                     && lp->p_paddr == p->p_paddr)
+                   break;
+               }
+           }
+
+         if (lp < phdrs + count)
+           {
+             p->p_vaddr = lp->p_vaddr;
+             p->p_paddr = lp->p_paddr;
+             p->p_offset = lp->p_offset;
+             if (link_info != NULL)
+               p->p_filesz = link_info->relro_end - lp->p_vaddr;
+             else if (m->p_size_valid)
+               p->p_filesz = m->p_size;
+             else
+               abort ();
+             p->p_memsz = p->p_filesz;
+             p->p_align = 1;
+             p->p_flags = (lp->p_flags & ~PF_W);
+           }
+         else if (link_info != NULL)
+           {
+             memset (p, 0, sizeof *p);
+             p->p_type = PT_NULL;
+           }
+         else
+           abort ();
+       }
+      else if (m->count != 0)
        {
          if (p->p_type != PT_LOAD
              && (p->p_type != PT_NOTE
@@ -4622,87 +4676,20 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
              p->p_filesz = sect->filepos - m->sections[0]->filepos;
              if (hdr->sh_type != SHT_NOBITS)
                p->p_filesz += hdr->sh_size;
-
-             if (p->p_type == PT_GNU_RELRO)
-               {
-                 /* When we get here, we are copying executable
-                    or shared library. But we need to use the same
-                    linker logic.  */
-                 Elf_Internal_Phdr *lp;
-
-                 for (lp = phdrs; lp < phdrs + count; ++lp)
-                   {
-                     if (lp->p_type == PT_LOAD
-                         && lp->p_paddr == p->p_paddr)
-                       break;
-                   }
-         
-                 if (lp < phdrs + count)
-                   {
-                     /* We should use p_size if it is valid since it
-                        may contain the first few bytes of the next
-                        SEC_ALLOC section.  */
-                     if (m->p_size_valid)
-                       p->p_filesz = m->p_size;
-                     else
-                       abort ();
-                     p->p_vaddr = lp->p_vaddr;
-                     p->p_offset = lp->p_offset;
-                     p->p_memsz = p->p_filesz;
-                     p->p_align = 1;
-                   }
-                 else
-                   abort ();
-               }
-             else
-               p->p_offset = m->sections[0]->filepos;
+             p->p_offset = m->sections[0]->filepos;
            }
        }
-      else
+      else if (m->includes_filehdr)
        {
-         if (m->includes_filehdr)
-           {
-             p->p_vaddr = filehdr_vaddr;
-             if (! m->p_paddr_valid)
-               p->p_paddr = filehdr_paddr;
-           }
-         else if (m->includes_phdrs)
-           {
-             p->p_vaddr = phdrs_vaddr;
-             if (! m->p_paddr_valid)
-               p->p_paddr = phdrs_paddr;
-           }
-         else if (p->p_type == PT_GNU_RELRO)
-           {
-             Elf_Internal_Phdr *lp;
-
-             for (lp = phdrs; lp < phdrs + count; ++lp)
-               {
-                 if (lp->p_type == PT_LOAD
-                     && lp->p_vaddr <= link_info->relro_end
-                     && lp->p_vaddr >= link_info->relro_start
-                     && (lp->p_vaddr + lp->p_filesz
-                         >= link_info->relro_end))
-                   break;
-               }
-
-             if (lp < phdrs + count
-                 && link_info->relro_end > lp->p_vaddr)
-               {
-                 p->p_vaddr = lp->p_vaddr;
-                 p->p_paddr = lp->p_paddr;
-                 p->p_offset = lp->p_offset;
-                 p->p_filesz = link_info->relro_end - lp->p_vaddr;
-                 p->p_memsz = p->p_filesz;
-                 p->p_align = 1;
-                 p->p_flags = (lp->p_flags & ~PF_W);
-               }
-             else
-               {
-                 memset (p, 0, sizeof *p);
-                 p->p_type = PT_NULL;
-               }
-           }
+         p->p_vaddr = filehdr_vaddr;
+         if (! m->p_paddr_valid)
+           p->p_paddr = filehdr_paddr;
+       }
+      else if (m->includes_phdrs)
+       {
+         p->p_vaddr = phdrs_vaddr;
+         if (! m->p_paddr_valid)
+           p->p_paddr = phdrs_paddr;
        }
     }