+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
{
/* 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)
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);