summaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorH.J. Lu <hjl@lucon.org>2007-10-11 05:03:07 +0000
committerH.J. Lu <hjl@lucon.org>2007-10-11 05:03:07 +0000
commit7db32cb5e22439731fbc3e07ac43d0a635e5309e (patch)
treea28ddb4b93ef71f5f608d1f1c26067954c4742b7 /bfd
parentd45e2cf6adf3518dde9b417a2ec82180213b31b1 (diff)
downloadbinutils-redhat-7db32cb5e22439731fbc3e07ac43d0a635e5309e.tar.gz
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.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog7
-rw-r--r--bfd/elf.c54
2 files changed, 42 insertions, 19 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 9117508b97..9e8ffad0de 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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
diff --git a/bfd/elf.c b/bfd/elf.c
index 3c2a49a1ac..d215144386 100644
--- 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);