aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog10
-rw-r--r--bfd/elf-bfd.h4
-rw-r--r--bfd/elf.c11
-rw-r--r--bfd/elf32-hppa.c1
-rw-r--r--bfd/elfxx-target.h4
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
diff --git a/bfd/elf.c b/bfd/elf.c
index 33fb4d2..94726ba 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -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