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: Fix relro strip test for MIPS


On Thu, Sep 20, 2007 at 11:58:20AM -0700, H.J. Lu wrote:
> On Thu, Sep 20, 2007 at 02:07:51PM -0400, Daniel Jacobowitz wrote:
> > On Thu, Sep 20, 2007 at 10:57:25AM -0700, H.J. Lu wrote:
> > > What happens is linker will allocate a segment for PT_GNU_RELRO
> > > if there is a .dynamic section. But it doesn't work for MIPS.
> > > Is there a way for linker to remove a segment reserved for
> > > PT_GNU_RELRO?
> > 
> > Not and reclaim its space.  That's why we convert it to PT_NULL.
> > 
> 
> That was done before Alan wrote a patch to remove the empty PT_LOAD
> segment. Maybe we can use the similar approach to remove empty
> PT_GNU_RELRO segment.
> 
> 

This patch may not be perfect. We may need to a better way to check if
a PT_GNU_RELRO segment is needed in _bfd_elf_map_sections_to_segments.


H.J.
----
2007-09-21  H.J. Lu  <hongjiu.lu@intel.com>

	* elf.c (get_program_header_size): Always add a PT_GNU_RELRO
	segment for -z relro.
	(_bfd_elf_map_sections_to_segments): Make a PT_GNU_RELRO
	segment only when needed.

--- bfd/elf.c.relro	2007-09-21 09:37:29.000000000 -0700
+++ bfd/elf.c	2007-09-21 09:52:42.000000000 -0700
@@ -3362,13 +3362,12 @@ get_program_header_size (bfd *abfd, stru
     {
       /* We need a PT_DYNAMIC segment.  */
       ++segs;
+    }
 
-      if (info->relro)
-	{
-	  /* We need a PT_GNU_RELRO segment only when there is a
-	     PT_DYNAMIC segment.  */
-	  ++segs;
-	}
+  if (info->relro)
+    {
+      /* We need a PT_GNU_RELRO segment.  */
+      ++segs;
     }
 
   if (elf_tdata (abfd)->eh_frame_hdr)
@@ -3991,21 +3990,43 @@ _bfd_elf_map_sections_to_segments (bfd *
 	  pm = &m->next;
 	}
 
-      if (dynsec != NULL && info->relro)
+      if (info->relro)
 	{
-	  /* We make a PT_GNU_RELRO segment only when there is a
-	     PT_DYNAMIC segment.  */
-	  amt = sizeof (struct elf_segment_map);
-	  m = bfd_zalloc (abfd, amt);
-	  if (m == NULL)
-	    goto error_return;
-	  m->next = NULL;
-	  m->p_type = PT_GNU_RELRO;
-	  m->p_flags = PF_R;
-	  m->p_flags_valid = 1;
+	  bfd_vma vaddr;
 
-	  *pm = m;
-	  pm = &m->next;
+	  for (m = mfirst; m != NULL; m = m->next)
+	    {
+	      vaddr = 0;
+	      if (m->p_type == PT_LOAD)
+		{
+		  bfd_vma filesz = 0;
+
+		  vaddr = m->sections[0]->vma;
+		  for (i = 0; i < m->count; i++)
+		    filesz = (m->sections[i]->vma - vaddr
+			      + m->sections[i]->size);
+
+		  if (vaddr <= info->relro_end
+		      && vaddr >= info->relro_start
+		      && (vaddr + filesz >= info->relro_end))
+		    break;
+		}
+	      }
+
+	  if (m != NULL && info->relro_end > vaddr)
+	    {
+	      amt = sizeof (struct elf_segment_map);
+	      m = bfd_zalloc (abfd, amt);
+	      if (m == NULL)
+		goto error_return;
+	      m->next = NULL;
+	      m->p_type = PT_GNU_RELRO;
+	      m->p_flags = PF_R;
+	      m->p_flags_valid = 1;
+
+	      *pm = m;
+	      pm = &m->next;
+	    }
 	}
 
       free (sections);


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