2007-10-10 H.J. Lu <hongjiu.lu@intel.com>
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 11 Oct 2007 05:03:07 +0000 (05:03 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 11 Oct 2007 05:03:07 +0000 (05:03 +0000)
* 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/ChangeLog
bfd/elf.c

index 9117508b977516da0c0b400c2c6082f6ba5e619d..9e8ffad0deb904e18cb8aed44f83ef302729e097 100644 (file)
@@ -1,3 +1,10 @@
+2007-10-10  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.
+
 2007-10-05  Bob Wilson  <bob.wilson@acm.org>
        
        * elf32-xtensa.c (relax_section): Call pin_internal_relocs when
index 3c2a49a1acb3897ea50555f3314b1fc2197777d3..d215144386a33f9870d53e5ffc835b63aadcc0ec 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -3358,13 +3358,12 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info)
     {
       /* 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)
@@ -3889,21 +3888,38 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
          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;
+         for (m = mfirst; m != NULL; m = m->next)
+           {
+             if (m->p_type == PT_LOAD)
+               {
+                 asection *last = m->sections[m->count - 1];
+                 bfd_vma vaddr = m->sections[0]->vma;
+                 bfd_vma filesz = last->vma - vaddr + last->size;
 
-         *pm = m;
-         pm = &m->next;
+                 if (vaddr < info->relro_end
+                     && vaddr >= info->relro_start
+                     && (vaddr + filesz) >= info->relro_end)
+                   break;
+               }
+             }
+
+         /* Make a PT_GNU_RELRO segment only when it isn't empty.  */
+         if (m != NULL)
+           {
+             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);