diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2013-12-12 10:35:47 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2014-01-08 05:57:21 -0800 |
commit | 43a8475ca01b676fb764aaed0c4ed1cc16fc3c87 (patch) | |
tree | fa782701a2a7bfcba6852cb7d9b51bb8d7650fd0 /bfd | |
parent | 221fd5d598e7dcf7b953150986a501b462b99891 (diff) | |
download | gdb-43a8475ca01b676fb764aaed0c4ed1cc16fc3c87.zip gdb-43a8475ca01b676fb764aaed0c4ed1cc16fc3c87.tar.gz gdb-43a8475ca01b676fb764aaed0c4ed1cc16fc3c87.tar.bz2 |
Adjust LOAD segment to generate GNU_RELRO segment
This patch fixes 2 GNU_RELRO segment bugs:
1. lang_size_sections didn't properly align base to the maximum
alignment power of sections between DATA_SEGMENT_ALIGN and
DATA_SEGMENT_RELRO_END.
2. ld failed to adjust LOAD segment to generate GNU_RELRO segment
when LOAD segment doesn't fit GNU_RELRO segment. This is
https://sourceware.org/bugzilla/show_bug.cgi?id=14207
We "fixed" ld by not generating GNU_RELRO segment. This patch
adjusts LOAD segment to generate GNU_RELRO segment. It fixes
PR ld/16322 and at the same time it also fixes PR binutils/16323
since now we can adjust LOAD segment if it is too small.
bfd/
PR ld/14207
PR ld/16322
PR binutils/16323
* elf.c (_bfd_elf_map_sections_to_segments): Don't check section
size for PT_GNU_RELRO segment.
(assign_file_positions_for_load_sections): If PT_LOAD segment
doesn't fit PT_GNU_RELRO segment, adjust its p_filesz and p_memsz.
ld/
PR ld/14207
PR ld/16322
PR binutils/16323
* ldlang.c (lang_size_sections): Properly align RELRO base.
ld/testsuite/
PR ld/14207
PR ld/16322
PR binutils/16323
* ld-elf/pr16322.d: New file.
* ld-elf/pr16322.s: Likewise.
* ld-x86-64/pr14207.d: Expect PT_GNU_RELRO segment.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 10 | ||||
-rw-r--r-- | bfd/elf.c | 41 |
2 files changed, 46 insertions, 5 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7ea72c0..c2053be 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2014-01-08 H.J. Lu <hongjiu.lu@intel.com> + + PR ld/14207 + PR ld/16322 + PR binutils/16323 + * elf.c (_bfd_elf_map_sections_to_segments): Don't check section + size for PT_GNU_RELRO segment. + (assign_file_positions_for_load_sections): If PT_LOAD segment + doesn't fit PT_GNU_RELRO segment, adjust its p_filesz and p_memsz. + 2014-01-07 Tom Tromey <tromey@redhat.com> * elf32-xtensa.c (vsprint_msg): Don't use old VA_* compatibility @@ -4184,11 +4184,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info) == (SEC_LOAD | SEC_HAS_CONTENTS)) break; - if (i == (unsigned) -1) - continue; - - if (m->sections[i]->vma + m->sections[i]->size - >= info->relro_end) + if (i != (unsigned) -1) break; } } @@ -4380,6 +4376,7 @@ assign_file_positions_for_load_sections (bfd *abfd, unsigned int alloc; unsigned int i, j; bfd_vma header_pad = 0; + bfd_vma relro_start = 0, relro_end = 0; if (link_info == NULL && !_bfd_elf_map_sections_to_segments (abfd, link_info)) @@ -4450,6 +4447,23 @@ assign_file_positions_for_load_sections (bfd *abfd, header_pad -= off; off += header_pad; + /* Get start and end of PT_GNU_RELRO segment. */ + if (link_info != NULL) + { + relro_start = link_info->relro_start; + relro_end = link_info->relro_end; + } + else + { + for (m = elf_seg_map (abfd); m != NULL; m = m->next) + if (m->p_type == PT_GNU_RELRO) + { + relro_start = m->p_paddr; + relro_end = relro_start + m->p_size; + break; + } + } + for (m = elf_seg_map (abfd), p = phdrs, j = 0; m != NULL; m = m->next, p++, j++) @@ -4792,6 +4806,23 @@ assign_file_positions_for_load_sections (bfd *abfd, p->p_flags |= PF_W; } } + + if (relro_start != 0 + && p->p_type == PT_LOAD + && p->p_vaddr >= relro_start) + { + /* If PT_LOAD segment doesn't fit PT_GNU_RELRO segment, + adjust its p_filesz and p_memsz. */ + if (p->p_vaddr + p->p_filesz < relro_end) + { + bfd_vma adjust = relro_end - (p->p_vaddr + p->p_filesz); + p->p_filesz += adjust; + off += adjust; + } + if (p->p_vaddr + p->p_memsz < relro_end) + p->p_memsz += relro_end - (p->p_vaddr + p->p_memsz); + } + off -= off_adjust; /* Check that all sections are in a PT_LOAD segment. |