File assign-file-positions.diff of Package cross-i386-binutils

2008-11-11  Alan Modra  <amodra@bigpond.net.au>

	* elf.c (assign_file_positions_for_non_load_sections): Consolidate
	PT_GNU_RELRO handling.

2008-11-07  Andreas Schwab  <schwab@suse.de>

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

Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.466
retrieving revision 1.468
diff -u -a -p -u -p -a -r1.466 -r1.468
--- bfd/elf.c	8 Oct 2008 08:30:27 -0000	1.466
+++ bfd/elf.c	11 Nov 2008 04:26:13 -0000	1.468
@@ -4631,7 +4631,61 @@ assign_file_positions_for_non_load_secti
        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
@@ -4647,87 +4701,20 @@ assign_file_positions_for_non_load_secti
 	      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;
 	}
     }