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 | |
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')
-rw-r--r-- | bfd/ChangeLog | 10 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 4 | ||||
-rw-r--r-- | bfd/elf.c | 11 | ||||
-rw-r--r-- | bfd/elf32-hppa.c | 1 | ||||
-rw-r--r-- | bfd/elfxx-target.h | 4 |
5 files changed, 30 insertions, 0 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4be12b8..0c45c44 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,15 @@ 2017-02-16 Alan Modra <amodra@gmail.com> + PR 21000 + * 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. + +2017-02-16 Alan Modra <amodra@gmail.com> + PR 21132 * elf32-hppa.c (allocate_plt_static): Allocate space for relocs if pic. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 9ea763a..f5a8d75 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1461,6 +1461,10 @@ struct elf_backend_data This field indicates whether this behavior is required. */ unsigned want_p_paddr_set_to_zero : 1; + /* Target has broken hardware and/or kernel that requires pages not + to be mapped twice with different permissions. */ + unsigned no_page_alias : 1; + /* True if an object file lacking a .note.GNU-stack section should be assumed to be requesting exec stack. At least one other file in the link needs to have a .note.GNU-stack section @@ -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) { diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index e64ea9a..d5b911c 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -4646,6 +4646,7 @@ elf32_hppa_elf_get_symbol_type (Elf_Internal_Sym *elf_sym, int type) #define elf_backend_want_dynrelro 1 #define elf_backend_rela_normal 1 #define elf_backend_dtrel_excludes_plt 1 +#define elf_backend_no_page_alias 1 #define TARGET_BIG_SYM hppa_elf32_vec #define TARGET_BIG_NAME "elf32-hppa" diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index 00252ce..d063fb7 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -114,6 +114,9 @@ #ifndef elf_backend_want_p_paddr_set_to_zero #define elf_backend_want_p_paddr_set_to_zero 0 #endif +#ifndef elf_backend_no_page_alias +#define elf_backend_no_page_alias 0 +#endif #ifndef elf_backend_default_execstack #define elf_backend_default_execstack 1 #endif @@ -860,6 +863,7 @@ static struct elf_backend_data elfNN_bed = elf_backend_want_dynbss, elf_backend_want_dynrelro, elf_backend_want_p_paddr_set_to_zero, + elf_backend_no_page_alias, elf_backend_default_execstack, elf_backend_caches_rawsize, elf_backend_extern_protected_data |