MIPS/BFD: Correctly handle `bfd_reloc_outofrange' with branches
authorMaciej W. Rozycki <macro@imgtec.com>
Sat, 28 May 2016 09:57:58 +0000 (10:57 +0100)
committerMaciej W. Rozycki <macro@imgtec.com>
Sat, 28 May 2016 09:59:45 +0000 (10:59 +0100)
Fix internal errors like:

ld: BFD (GNU Binutils) 2.26.51.20160526 internal error, aborting at .../bfd/elfxx-mips.c:10278 in _bfd_mips_elf_relocate_section

ld: Please report this bug.

triggered by the `bfd_reloc_outofrange' condition on branch relocations.

bfd/
* elfxx-mips.c (b_reloc_p): New function.
(_bfd_mips_elf_relocate_section) <bfd_reloc_outofrange>: Handle
branch relocations.

ld/
* 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.

bfd/ChangeLog
bfd/elfxx-mips.c
ld/ChangeLog
ld/testsuite/ld-mips-elf/mips-elf.exp
ld/testsuite/ld-mips-elf/unaligned-branch.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/unaligned-branch.s [new file with mode: 0644]
ld/testsuite/ld-mips-elf/unaligned-text.s [new file with mode: 0644]

index fa83823d889a2f267b5e259cac7cf3dffeddc291..726e4c3ff8f4faa7e5c9c8f58dbc6c1eecd6dc97 100644 (file)
@@ -1,3 +1,9 @@
+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>
index d519090dc156b78ec0ee99a0a646e05a991a09cf..e2f47499e9349ecbcb727c0c2ce27efd352888c1 100644 (file)
@@ -2215,6 +2215,15 @@ jal_reloc_p (int r_type)
          || r_type == R_MICROMIPS_26_S1);
 }
 
+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)
 {
@@ -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)
index 238b25f866f933dc72ce2e7f61d6c3a833e79700..1b99a438ac895a0d80f1edd9f3154225ffa8d909 100644 (file)
@@ -1,3 +1,10 @@
+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...
index f8c8b09bda0d834eeac84f93d4c779a8260db098..61a119e39a9ea834729b7fb4c66c0fcda6b1ab7a 100644 (file)
@@ -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 (file)
index 0000000..54894b6
--- /dev/null
@@ -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 (file)
index 0000000..8fef3bb
--- /dev/null
@@ -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 (file)
index 0000000..4b3aa38
--- /dev/null
@@ -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
This page took 0.035643 seconds and 4 git commands to generate.