aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2007-10-11 05:03:07 +0000
committerH.J. Lu <hjl.tools@gmail.com>2007-10-11 05:03:07 +0000
commitf210dcff90d54b8ae46967a3a4b07757cacd959f (patch)
tree5b13f3c4584eeca53cf09f5ec885177ccdcb2d5f /bfd/elf.c
parent21dec5f51af65996b82580eebd9a8914286347a1 (diff)
downloadgdb-f210dcff90d54b8ae46967a3a4b07757cacd959f.zip
gdb-f210dcff90d54b8ae46967a3a4b07757cacd959f.tar.gz
gdb-f210dcff90d54b8ae46967a3a4b07757cacd959f.tar.bz2
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/elf.c')
-rw-r--r--bfd/elf.c54
1 files changed, 35 insertions, 19 deletions
diff --git a/bfd/elf.c b/bfd/elf.c
index 3c2a49a..d215144 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);