aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog6
-rw-r--r--bfd/elfxx-mips.c11
-rw-r--r--ld/ChangeLog7
-rw-r--r--ld/testsuite/ld-mips-elf/mips-elf.exp2
-rw-r--r--ld/testsuite/ld-mips-elf/unaligned-branch.d23
-rw-r--r--ld/testsuite/ld-mips-elf/unaligned-branch.s21
-rw-r--r--ld/testsuite/ld-mips-elf/unaligned-text.s15
7 files changed, 85 insertions, 0 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index fa83823..726e4c3 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,11 @@
2016-05-28 Maciej W. Rozycki <macro@imgtec.com>
+ * elfxx-mips.c (b_reloc_p): New function.
+ (_bfd_mips_elf_relocate_section) <bfd_reloc_outofrange>: Handle
+ branch relocations.
+
+2016-05-28 Maciej W. Rozycki <macro@imgtec.com>
+
* elfxx-mips.c (mips_elf_calculate_relocation): <R_MIPS16_26>
<R_MIPS_26, R_MICROMIPS_26_S1>: Drop the region bits of the
reloc location from calculation, treat the addend as signed with
diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index d519090..e2f4749 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -2216,6 +2216,15 @@ jal_reloc_p (int r_type)
}
static inline bfd_boolean
+b_reloc_p (int r_type)
+{
+ return (r_type == R_MIPS_PC26_S2
+ || r_type == R_MIPS_PC21_S2
+ || r_type == R_MIPS_PC16
+ || r_type == R_MIPS_GNU_REL16_S2);
+}
+
+static inline bfd_boolean
aligned_pcrel_reloc_p (int r_type)
{
return (r_type == R_MIPS_PC18_S3
@@ -10261,6 +10270,8 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
msg = NULL;
if (jal_reloc_p (howto->type))
msg = _("JALX to a non-word-aligned address");
+ else if (b_reloc_p (howto->type))
+ msg = _("Branch to a non-instruction-aligned address");
else if (aligned_pcrel_reloc_p (howto->type))
msg = _("PC-relative load from unaligned address");
if (msg)
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 238b25f..1b99a43 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,5 +1,12 @@
2016-05-28 Maciej W. Rozycki <macro@imgtec.com>
+ * testsuite/ld-mips-elf/unaligned-branch.d: New test.
+ * testsuite/ld-mips-elf/unaligned-branch.s: New test source.
+ * testsuite/ld-mips-elf/unaligned-text.s: New test source.
+ * testsuite/ld-mips-elf/mips-elf.exp: Run the new test.
+
+2016-05-28 Maciej W. Rozycki <macro@imgtec.com>
+
* testsuite/ld-mips-elf/unaligned-syms.s: Rename to...
* testsuite/ld-mips-elf/unaligned-data.s: ... this.
* testsuite/ld-mips-elf/unaligned-ldpc-0.d: Adjust accordingly.
diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp
index f8c8b09..61a119e 100644
--- a/ld/testsuite/ld-mips-elf/mips-elf.exp
+++ b/ld/testsuite/ld-mips-elf/mips-elf.exp
@@ -199,6 +199,8 @@ if $has_newabi {
[list [list ld $abi_ldflags(n32)]]
}
+run_dump_test "unaligned-branch" [list [list ld $abi_ldflags(o32)]]
+
run_dump_test "unaligned-lwpc-0" [list [list ld $abi_ldflags(o32)]]
run_dump_test "unaligned-lwpc-1" [list [list ld $abi_ldflags(o32)]]
run_dump_test "unaligned-ldpc-0" [list [list ld $abi_ldflags(o32)]]
diff --git a/ld/testsuite/ld-mips-elf/unaligned-branch.d b/ld/testsuite/ld-mips-elf/unaligned-branch.d
new file mode 100644
index 0000000..54894b6
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/unaligned-branch.d
@@ -0,0 +1,23 @@
+#name: MIPS branch to unaligned symbol
+#source: unaligned-branch.s
+#source: unaligned-text.s
+#as: -EB -32 -mips32r6
+#ld: -EB -Ttext 0x10000000 -e 0x10000000
+#error: \A[^\n]*: In function `foo':\n
+#error: \(\.text\+0x14\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x24\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x28\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x30\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x38\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x3c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x44\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x4c\): Branch to a non-instruction-aligned address\Z
diff --git a/ld/testsuite/ld-mips-elf/unaligned-branch.s b/ld/testsuite/ld-mips-elf/unaligned-branch.s
new file mode 100644
index 0000000..8fef3bb
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/unaligned-branch.s
@@ -0,0 +1,21 @@
+ .text
+ .align 4
+ .globl foo
+ .ent foo
+foo:
+ b bar0
+ beqzc $2, bar0
+ bc bar0
+ b bar1
+ beqzc $2, bar1
+ bc bar1
+ b bar2
+ beqzc $2, bar2
+ bc bar2
+ b bar3
+ beqzc $2, bar3
+ bc bar3
+ b bar4
+ beqzc $2, bar4
+ bc bar4
+ .end foo
diff --git a/ld/testsuite/ld-mips-elf/unaligned-text.s b/ld/testsuite/ld-mips-elf/unaligned-text.s
new file mode 100644
index 0000000..4b3aa38
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/unaligned-text.s
@@ -0,0 +1,15 @@
+ .macro sym n:req
+ .if \n
+ .globl bar\@
+ .type bar\@, @object
+bar\@ :
+ .byte 0
+ .size bar\@, . - bar\@
+ sym \n - 1
+ .endif
+ .endm
+
+ .text
+ .align 4
+ .space 32
+ sym 16