This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: PR ld/5149: Set PF_X for PT_GNU_RELRO segment only when needed


We currently set PF_X for PT_GNU_RELRO segment when the corresponding
PT_LOAD segment has PF_X. It isn't necessary. This patch checks
sections in PT_GNU_RELRO segment before setting PF_X.


H.J.
---
2007-10-22  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/5149
	* elf.c (assign_file_positions_for_non_load_sections): Set
	PF_X for PT_GNU_RELRO segment only if a section has
	SHF_EXECINSTR.

--- bfd/elf.c.relro	2007-10-22 12:22:32.000000000 -0700
+++ bfd/elf.c	2007-10-22 15:25:55.000000000 -0700
@@ -4728,27 +4728,57 @@ assign_file_positions_for_non_load_secti
 	  else if (p->p_type == PT_GNU_RELRO)
 	    {
 	      Elf_Internal_Phdr *lp;
+	      struct elf_segment_map *lm;
 
-	      for (lp = phdrs; lp < phdrs + count; ++lp)
+	      for (lm = elf_tdata (abfd)->segment_map, lp = phdrs;
+		   lm != NULL; lm = lm->next, lp++)
 		{
 		  if (lp->p_type == PT_LOAD
-		      && lp->p_vaddr <= link_info->relro_end
+		      && lp->p_vaddr < link_info->relro_end
 		      && lp->p_vaddr >= link_info->relro_start
-		      && (lp->p_vaddr + lp->p_filesz
+		      && ((lp->p_vaddr + lp->p_filesz)
 			  >= link_info->relro_end))
 		    break;
 		}
 
-	      if (lp < phdrs + count
-		  && link_info->relro_end > lp->p_vaddr)
+	      if (lm != NULL)
 		{
+		  unsigned long p_flags = lp->p_flags & ~PF_W;
+
 		  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);
+
+		  if ((p_flags & PF_X) != 0)
+		    {
+		      Elf_Internal_Shdr *hdr;
+
+		      /* Clear PF_X.  */
+		      p_flags &= ~PF_X;
+
+		      for (i = 0; i < lm->count; i++) 
+			{
+			  hdr = &elf_section_data (lm->sections[i])->this_hdr;
+
+			  if (hdr->sh_addr >= link_info->relro_start)
+			    {
+			      if (hdr->sh_addr >= link_info->relro_end)
+				break;
+
+			      /* Set PF_X only if a section has
+				 SHF_EXECINSTR.  */
+			      if ((hdr->sh_flags & SHF_EXECINSTR))
+				{
+				  p_flags |= PF_X;
+				  break;
+				}
+			    }
+			}
+		    }
+		  p->p_flags = p_flags;
 		}
 	      else
 		{


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]