diff options
author | Alan Modra <amodra@gmail.com> | 2017-02-14 10:45:51 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2017-02-16 23:09:38 +1030 |
commit | a8c75b765e57aaebb99d4e32e0f228835cff2737 (patch) | |
tree | 2cea5382768b3cae9de0e04d151a7313d1024e77 /bfd/elf.c | |
parent | 247d6c4c14769b7576d810a381a68e35388ee874 (diff) | |
download | gdb-a8c75b765e57aaebb99d4e32e0f228835cff2737.zip gdb-a8c75b765e57aaebb99d4e32e0f228835cff2737.tar.gz gdb-a8c75b765e57aaebb99d4e32e0f228835cff2737.tar.bz2 |
hppa -z relro again
I misunderstood the hppa alias problem. File offsets of segments need
to be such that no page is mapped twice with different permissions.
(Which still seems to me like something the kernel could fix, but
anyhow, this is not so difficult to achieve in ld.)
PR 21000
bfd/
* elf-bfd.h (struct elf_backend_data): Add no_page_alias.
* elfxx-target.h (elf_backend_no_page_alias): Define.
(elfNN_bed): Init new field.
* elf.c (assign_file_positions_for_load_sections): If no_page_alias
ensure PT_LOAD segment starts on a new page.
* elf32-hppa.c (elf_backend_no_page_alias): Define.
ld/
* testsuite/ld-elf/loadaddr1.d: Adjust for hppa file offsets.
* testsuite/ld-elf/loadaddr2.d: Likewise.
* testsuite/ld-elf/loadaddr3a.d: Likewise.
* testsuite/ld-scripts/rgn-at5.d: Likewise.
Diffstat (limited to 'bfd/elf.c')
-rw-r--r-- | bfd/elf.c | 11 |
1 files changed, 11 insertions, 0 deletions
@@ -5125,6 +5125,7 @@ assign_file_positions_for_load_sections (bfd *abfd, Elf_Internal_Phdr *p; file_ptr off; bfd_size_type maxpagesize; + unsigned int pt_load_count = 0; unsigned int alloc; unsigned int i, j; bfd_vma header_pad = 0; @@ -5252,6 +5253,7 @@ assign_file_positions_for_load_sections (bfd *abfd, maxpagesize = m->p_align; p->p_align = maxpagesize; + pt_load_count += 1; } else if (m->p_align_valid) p->p_align = m->p_align; @@ -5303,6 +5305,15 @@ assign_file_positions_for_load_sections (bfd *abfd, } off_adjust = vma_page_aligned_bias (p->p_vaddr, off, align); + + /* Broken hardware and/or kernel require that files do not + map the same page with different permissions on some hppa + processors. */ + if (pt_load_count > 1 + && bed->no_page_alias + && (off & (maxpagesize - 1)) != 0 + && (off & -maxpagesize) == ((off + off_adjust) & -maxpagesize)) + off_adjust += maxpagesize; off += off_adjust; if (no_contents) { |