diff options
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 d39283a..f20f79d 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 15d6da0..5de9ab6 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1460,6 +1460,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 |