aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@imgtec.com>2017-01-30 17:11:22 +0000
committerMaciej W. Rozycki <macro@imgtec.com>2017-01-30 17:16:01 +0000
commit8b10b0b3e100c25322a083248c7a18bf5a1f3527 (patch)
tree4993513d1cb11f9a039d4c01b7373a9afcb13616 /ld
parent7795a8f8bdde2fa5c0e0639b92280314b32ec78d (diff)
downloadgdb-8b10b0b3e100c25322a083248c7a18bf5a1f3527.zip
gdb-8b10b0b3e100c25322a083248c7a18bf5a1f3527.tar.gz
gdb-8b10b0b3e100c25322a083248c7a18bf5a1f3527.tar.bz2
MIPS: Add options to control branch ISA checks
Complement commit 9d862524f6ae ("MIPS: Verify the ISA mode and alignment of branch and jump targets") and add GAS and LD options to control the checks for invalid branches between ISA modes introduced there, to help with some handwritten code lacking `.insn' annotation for labels used as branch targets and code produced by older versions of GCC which suffers from the issue with branches to code that has been optimized away, addressed with GCC commit 242424 ("MIPS/GCC: Mark trailing labels with `.insn'"), <https://gcc.gnu.org/ml/gcc-patches/2016-11/msg01061.html>. bfd/ * elfxx-mips.h (_bfd_mips_elf_insn32): Rename prototype to... (_bfd_mips_elf_linker_flags): ... this. Add another parameter. * elfxx-mips.c (mips_elf_link_hash_table): Add `ignore_branch_isa' member. (mips_elf_perform_relocation): Do not treat an ISA mode mismatch in branch relocation calculation as an error if `ignore_branch_isa' has been set. (_bfd_mips_elf_insn32): Rename to... (_bfd_mips_elf_linker_flags): ... this. Rename the `on' parameter to `insn32' and add an `ignore_branch_isa' parameter. Handle the new parameter. gas/ * config/tc-mips.c (mips_ignore_branch_isa): New variable. (options): Add OPTION_IGNORE_BRANCH_ISA and OPTION_NO_IGNORE_BRANCH_ISA enum values. (md_longopts): Add "mignore-branch-isa" and "mno-ignore-branch-isa" options. (md_parse_option): Handle OPTION_IGNORE_BRANCH_ISA and OPTION_NO_IGNORE_BRANCH_ISA. (fix_bad_cross_mode_branch_p): Return FALSE if `mips_ignore_branch_isa' has been set. (md_show_usage): Add `-mignore-branch-isa' and `-mno-ignore-branch-isa'. * doc/as.texinfo (Target MIPS options): Add `-mignore-branch-isa' and `-mno-ignore-branch-isa' options. (-mignore-branch-isa, -mno-ignore-branch-isa): New options. * doc/c-mips.texi (MIPS Options): Add `-mignore-branch-isa' and `-mno-ignore-branch-isa' options. * testsuite/gas/mips/branch-local-ignore-2.d: New test. * testsuite/gas/mips/branch-local-ignore-3.d: New test. * testsuite/gas/mips/branch-local-ignore-n32-2.d: New test. * testsuite/gas/mips/branch-local-ignore-n32-3.d: New test. * testsuite/gas/mips/branch-local-ignore-n64-2.d: New test. * testsuite/gas/mips/branch-local-ignore-n64-3.d: New test. * testsuite/gas/mips/mips.exp: Run the new tests. ld/ * emultempl/mipself.em (ignore_branch_isa): New variable. (mips_create_output_section_statements): Rename `_bfd_mips_elf_insn32' called to `_bfd_mips_elf_linker_flags', add `ignore_branch_isa' argument. (PARSE_AND_LIST_PROLOGUE): Add OPTION_IGNORE_BRANCH_ISA and OPTION_NO_IGNORE_BRANCH_ISA enum values. (PARSE_AND_LIST_LONGOPTS): Add "ignore-branch-isa" and "no-ignore-branch-isa" options. (PARSE_AND_LIST_OPTIONS): Add `--ignore-branch-isa' and `--no-ignore-branch-isa'. (PARSE_AND_LIST_ARGS_CASES): Handle OPTION_IGNORE_BRANCH_ISA and OPTION_NO_IGNORE_BRANCH_ISA. * ld.texinfo (Options specific to MIPS targets): Add `--ignore-branch-isa' and `--no-ignore-branch-isa' options. (ld and the MIPS family): Likewise. * testsuite/ld-mips-elf/bal-jalx-pic-ignore.d: New test. * testsuite/ld-mips-elf/bal-jalx-pic-ignore-n32.d: New test. * testsuite/ld-mips-elf/bal-jalx-pic-ignore-n64.d: New test. * testsuite/ld-mips-elf/unaligned-branch-ignore-2.d: New test. * testsuite/ld-mips-elf/unaligned-branch-ignore-r6-1: New test. * testsuite/ld-mips-elf/unaligned-branch-ignore-mips16: New test. * testsuite/ld-mips-elf/unaligned-branch-ignore-micromips: New test. * testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog30
-rw-r--r--ld/emultempl/mipself.em25
-rw-r--r--ld/ld.texinfo30
-rw-r--r--ld/testsuite/ld-mips-elf/bal-jalx-pic-ignore-n32.d6
-rw-r--r--ld/testsuite/ld-mips-elf/bal-jalx-pic-ignore-n64.d6
-rw-r--r--ld/testsuite/ld-mips-elf/bal-jalx-pic-ignore.d22
-rw-r--r--ld/testsuite/ld-mips-elf/mips-elf.exp11
-rw-r--r--ld/testsuite/ld-mips-elf/unaligned-branch-ignore-2.d64
-rw-r--r--ld/testsuite/ld-mips-elf/unaligned-branch-ignore-micromips.d84
-rw-r--r--ld/testsuite/ld-mips-elf/unaligned-branch-ignore-mips16.d36
-rw-r--r--ld/testsuite/ld-mips-elf/unaligned-branch-ignore-r6-1.d72
11 files changed, 383 insertions, 3 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index fec48e2..5c5504c 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,33 @@
+2017-01-30 Maciej W. Rozycki <macro@imgtec.com>
+
+ * emultempl/mipself.em (ignore_branch_isa): New variable.
+ (mips_create_output_section_statements): Rename
+ `_bfd_mips_elf_insn32' called to `_bfd_mips_elf_linker_flags',
+ add `ignore_branch_isa' argument.
+ (PARSE_AND_LIST_PROLOGUE): Add OPTION_IGNORE_BRANCH_ISA and
+ OPTION_NO_IGNORE_BRANCH_ISA enum values.
+ (PARSE_AND_LIST_LONGOPTS): Add "ignore-branch-isa" and
+ "no-ignore-branch-isa" options.
+ (PARSE_AND_LIST_OPTIONS): Add `--ignore-branch-isa' and
+ `--no-ignore-branch-isa'.
+ (PARSE_AND_LIST_ARGS_CASES): Handle OPTION_IGNORE_BRANCH_ISA and
+ OPTION_NO_IGNORE_BRANCH_ISA.
+
+ * ld.texinfo (Options specific to MIPS targets): Add
+ `--ignore-branch-isa' and `--no-ignore-branch-isa' options.
+ (ld and the MIPS family): Likewise.
+
+ * testsuite/ld-mips-elf/bal-jalx-pic-ignore.d: New test.
+ * testsuite/ld-mips-elf/bal-jalx-pic-ignore-n32.d: New test.
+ * testsuite/ld-mips-elf/bal-jalx-pic-ignore-n64.d: New test.
+ * testsuite/ld-mips-elf/unaligned-branch-ignore-2.d: New test.
+ * testsuite/ld-mips-elf/unaligned-branch-ignore-r6-1: New test.
+ * testsuite/ld-mips-elf/unaligned-branch-ignore-mips16: New
+ test.
+ * testsuite/ld-mips-elf/unaligned-branch-ignore-micromips: New
+ test.
+ * testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.
+
2017-01-29 Hans-Peter Nilsson <hp@axis.com>
PR binutils/19935
diff --git a/ld/emultempl/mipself.em b/ld/emultempl/mipself.em
index 74ede87..cd68707 100644
--- a/ld/emultempl/mipself.em
+++ b/ld/emultempl/mipself.em
@@ -34,6 +34,7 @@ static lang_input_statement_type *stub_file;
static bfd *stub_bfd;
static bfd_boolean insn32;
+static bfd_boolean ignore_branch_isa;
static void
mips_after_parse (void)
@@ -202,7 +203,7 @@ mips_create_output_section_statements (void)
htab = elf_hash_table (&link_info);
if (is_elf_hash_table (htab) && is_mips_elf (link_info.output_bfd))
- _bfd_mips_elf_insn32 (&link_info, insn32);
+ _bfd_mips_elf_linker_flags (&link_info, insn32, ignore_branch_isa);
if (is_mips_elf (link_info.output_bfd))
_bfd_mips_elf_init_stubs (&link_info, mips_add_stub_section);
@@ -253,13 +254,17 @@ PARSE_AND_LIST_PROLOGUE='
enum
{
OPTION_INSN32 = 301,
- OPTION_NO_INSN32
+ OPTION_NO_INSN32,
+ OPTION_IGNORE_BRANCH_ISA,
+ OPTION_NO_IGNORE_BRANCH_ISA
};
'
PARSE_AND_LIST_LONGOPTS='
{ "insn32", no_argument, NULL, OPTION_INSN32 },
{ "no-insn32", no_argument, NULL, OPTION_NO_INSN32 },
+ { "ignore-branch-isa", no_argument, NULL, OPTION_IGNORE_BRANCH_ISA },
+ { "no-ignore-branch-isa", no_argument, NULL, OPTION_NO_IGNORE_BRANCH_ISA },
'
PARSE_AND_LIST_OPTIONS='
@@ -269,6 +274,14 @@ PARSE_AND_LIST_OPTIONS='
fprintf (file, _("\
--no-insn32 Generate all microMIPS instructions\n"
));
+ fprintf (file, _("\
+ --ignore-branch-isa Accept invalid branch relocations requiring\n\
+ an ISA mode switch\n"
+ ));
+ fprintf (file, _("\
+ --no-ignore-branch-isa Reject invalid branch relocations requiring\n\
+ an ISA mode switch\n"
+ ));
'
PARSE_AND_LIST_ARGS_CASES='
@@ -279,6 +292,14 @@ PARSE_AND_LIST_ARGS_CASES='
case OPTION_NO_INSN32:
insn32 = FALSE;
break;
+
+ case OPTION_IGNORE_BRANCH_ISA:
+ ignore_branch_isa = TRUE;
+ break;
+
+ case OPTION_NO_IGNORE_BRANCH_ISA:
+ ignore_branch_isa = FALSE;
+ break;
'
LDEMUL_AFTER_PARSE=mips_after_parse
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 2ce7560..8f2dfdb 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -3001,7 +3001,8 @@ Info entry for @file{ld}.
@c man begin OPTIONS
The following options are supported to control microMIPS instruction
-generation when linking for MIPS targets.
+generation and branch relocation checks for ISA mode transitions when
+linking for MIPS targets.
@table @gcctabopt
@@ -3016,6 +3017,20 @@ or in relaxation. If @samp{--insn32} is used, then the linker only uses
used, all instruction encodings are used, including 16-bit ones where
possible.
+@kindex --ignore-branch-isa
+@item --ignore-branch-isa
+@kindex --no-ignore-branch-isa
+@itemx --no-ignore-branch-isa
+These options control branch relocation checks for invalid ISA mode
+transitions. If @samp{--ignore-branch-isa} is used, then the linker
+accepts any branch relocations and any ISA mode transition required
+is lost in relocation calculation, except for some cases of @code{BAL}
+instructions which meet relaxation conditions and are converted to
+equivalent @code{JALX} instructions as the associated relocation is
+calculated. By default or if @samp{--no-ignore-branch-isa} is used
+a check is made causing the loss of an ISA mode transition to produce
+an error.
+
@end table
@c man end
@@ -7062,6 +7077,19 @@ used, then the linker only uses 32-bit instruction encodings. By default
or if @samp{--no-insn32} is used, all instruction encodings are used,
including 16-bit ones where possible.
+@cindex MIPS branch relocation check control
+@kindex --ignore-branch-isa
+@kindex --no-ignore-branch-isa
+The @samp{--ignore-branch-isa} and @samp{--no-ignore-branch-isa} options
+control branch relocation checks for invalid ISA mode transitions. If
+@samp{--ignore-branch-isa} is used, then the linker accepts any branch
+relocations and any ISA mode transition required is lost in relocation
+calculation, except for some cases of @code{BAL} instructions which meet
+relaxation conditions and are converted to equivalent @code{JALX}
+instructions as the associated relocation is calculated. By default
+or if @samp{--no-ignore-branch-isa} is used a check is made causing
+the loss of an ISA mode transition to produce an error.
+
@ifclear GENERIC
@lowersections
@end ifclear
diff --git a/ld/testsuite/ld-mips-elf/bal-jalx-pic-ignore-n32.d b/ld/testsuite/ld-mips-elf/bal-jalx-pic-ignore-n32.d
new file mode 100644
index 0000000..c402ba8
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/bal-jalx-pic-ignore-n32.d
@@ -0,0 +1,6 @@
+#name: MIPS BAL/JALX in PIC mode (ignore branch ISA, n32)
+#source: ../../../gas/testsuite/gas/mips/branch-addend.s
+#as: -EB -n32 -march=from-abi
+#ld: -EB -Ttext 0x1c000000 -e 0x1c000000 -shared --ignore-branch-isa
+#objdump: -dr --prefix-addresses --show-raw-insn
+#dump: bal-jalx-pic-ignore.d
diff --git a/ld/testsuite/ld-mips-elf/bal-jalx-pic-ignore-n64.d b/ld/testsuite/ld-mips-elf/bal-jalx-pic-ignore-n64.d
new file mode 100644
index 0000000..e1bbb92
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/bal-jalx-pic-ignore-n64.d
@@ -0,0 +1,6 @@
+#name: MIPS BAL/JALX in PIC mode (ignore branch ISA, n64)
+#source: ../../../gas/testsuite/gas/mips/branch-addend.s
+#as: -EB -64 -march=from-abi
+#ld: -EB -Ttext 0x1c000000 -e 0x1c000000 -shared --ignore-branch-isa
+#objdump: -dr --prefix-addresses --show-raw-insn
+#dump: bal-jalx-pic-ignore.d
diff --git a/ld/testsuite/ld-mips-elf/bal-jalx-pic-ignore.d b/ld/testsuite/ld-mips-elf/bal-jalx-pic-ignore.d
new file mode 100644
index 0000000..279b87a
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/bal-jalx-pic-ignore.d
@@ -0,0 +1,22 @@
+#name: MIPS BAL/JALX in PIC mode (ignore branch ISA)
+#source: ../../../gas/testsuite/gas/mips/branch-addend.s
+#as: -EB -32
+#ld: -EB -Ttext 0x1c000000 -e 0x1c000000 -shared --ignore-branch-isa
+#objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*mips.*
+
+Disassembly of section \.text:
+ \.\.\.
+[0-9a-f]+ <[^>]*> 0000 02d0 not zero,zero
+[0-9a-f]+ <[^>]*> 001f 0f3c jr ra
+[0-9a-f]+ <[^>]*> 0000 02d0 not zero,zero
+[0-9a-f]+ <[^>]*> 0000 0000 nop
+[0-9a-f]+ <[^>]*> 00000027 nor zero,zero,zero
+[0-9a-f]+ <[^>]*> 04117ffa bal 0*1c021000 <.*>
+[0-9a-f]+ <[^>]*> 00000027 nor zero,zero,zero
+[0-9a-f]+ <[^>]*> 04117ffc bal 0*1c021010 <.*>
+[0-9a-f]+ <[^>]*> 00000027 nor zero,zero,zero
+[0-9a-f]+ <[^>]*> 03e00009 jalr zero,ra
+[0-9a-f]+ <[^>]*> 00000027 nor zero,zero,zero
+ \.\.\.
diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp
index 5639c84..7fa11c5 100644
--- a/ld/testsuite/ld-mips-elf/mips-elf.exp
+++ b/ld/testsuite/ld-mips-elf/mips-elf.exp
@@ -216,17 +216,20 @@ run_dump_test "jalx-local" [list [list ld $abi_ldflags(o32)]]
run_dump_test "bal-jalx-addend" [list [list ld $abi_ldflags(o32)]]
run_dump_test "bal-jalx-local" [list [list ld $abi_ldflags(o32)]]
run_dump_test "bal-jalx-pic" [list [list ld $abi_ldflags(o32)]]
+run_dump_test "bal-jalx-pic-ignore" [list [list ld $abi_ldflags(o32)]]
if $has_newabi {
run_dump_test "jalx-addend-n32" [list [list ld $abi_ldflags(n32)]]
run_dump_test "jalx-local-n32" [list [list ld $abi_ldflags(n32)]]
run_dump_test "bal-jalx-addend-n32" [list [list ld $abi_ldflags(n32)]]
run_dump_test "bal-jalx-local-n32" [list [list ld $abi_ldflags(n32)]]
run_dump_test "bal-jalx-pic-n32" [list [list ld $abi_ldflags(n32)]]
+ run_dump_test "bal-jalx-pic-ignore-n32" [list [list ld $abi_ldflags(n32)]]
run_dump_test "jalx-addend-n64" [list [list ld $abi_ldflags(n64)]]
run_dump_test "jalx-local-n64" [list [list ld $abi_ldflags(n64)]]
run_dump_test "bal-jalx-addend-n64" [list [list ld $abi_ldflags(n64)]]
run_dump_test "bal-jalx-local-n64" [list [list ld $abi_ldflags(n64)]]
run_dump_test "bal-jalx-pic-n64" [list [list ld $abi_ldflags(n64)]]
+ run_dump_test "bal-jalx-pic-ignore-n64" [list [list ld $abi_ldflags(n64)]]
}
run_dump_test "unaligned-jalx-0" [list [list ld $abi_ldflags(o32)]]
@@ -262,14 +265,22 @@ run_dump_test "unaligned-branch" [list [list ld $abi_ldflags(o32)]]
if $has_newabi {
run_dump_test "unaligned-branch-2" \
[list [list ld $abi_ldflags(n32)]]
+ run_dump_test "unaligned-branch-ignore-2" \
+ [list [list ld $abi_ldflags(n32)]]
run_dump_test "unaligned-branch-r6-1" \
[list [list ld $abi_ldflags(n32)]]
+ run_dump_test "unaligned-branch-ignore-r6-1" \
+ [list [list ld $abi_ldflags(n32)]]
run_dump_test "unaligned-branch-r6-2" \
[list [list ld $abi_ldflags(n32)]]
run_dump_test "unaligned-branch-mips16" \
[list [list ld $abi_ldflags(n32)]]
+ run_dump_test "unaligned-branch-ignore-mips16" \
+ [list [list ld $abi_ldflags(n32)]]
run_dump_test "unaligned-branch-micromips" \
[list [list ld $abi_ldflags(n32)]]
+ run_dump_test "unaligned-branch-ignore-micromips" \
+ [list [list ld $abi_ldflags(n32)]]
run_dump_test "unaligned-jump" \
[list [list ld $abi_ldflags(n32)]]
run_dump_test "unaligned-jump-mips16" \
diff --git a/ld/testsuite/ld-mips-elf/unaligned-branch-ignore-2.d b/ld/testsuite/ld-mips-elf/unaligned-branch-ignore-2.d
new file mode 100644
index 0000000..323c43a
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/unaligned-branch-ignore-2.d
@@ -0,0 +1,64 @@
+#name: MIPS link branch to unaligned symbol 2 (ignore branch ISA)
+#as: -EB -n32 -march=from-abi
+#ld: -EB -Ttext 0x1c000000 -e 0x1c000000 --ignore-branch-isa
+#source: ../../../gas/testsuite/gas/mips/unaligned-branch-2.s
+#error: \A[^\n]*: In function `foo':\n
+#error: \(\.text\+0x101c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1024\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x102c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1034\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x103c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1044\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x104c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1054\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x105c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x107c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1084\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x108c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1094\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x109c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10a4\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10ac\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10b4\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10bc\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10f4\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10fc\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1104\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1124\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x112c\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1134\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x113c\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1144\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x114c\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1154\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x115c\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1164\): Cannot convert a branch to JALX for a non-word-aligned address\Z
diff --git a/ld/testsuite/ld-mips-elf/unaligned-branch-ignore-micromips.d b/ld/testsuite/ld-mips-elf/unaligned-branch-ignore-micromips.d
new file mode 100644
index 0000000..6a62fe5
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/unaligned-branch-ignore-micromips.d
@@ -0,0 +1,84 @@
+#name: microMIPS link branch to unaligned symbol (ignore branch ISA)
+#as: -EB -n32 -march=from-abi
+#ld: -EB -Ttext 0x1c000000 -e 0x1c000000 --ignore-branch-isa
+#source: ../../../gas/testsuite/gas/mips/unaligned-branch-micromips-2.s
+#error: \A[^\n]*: In function `foo':\n
+#error: \(\.text\+0x100a\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1012\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x101a\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x102a\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1032\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x103a\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1062\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1072\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1088\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x108e\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1094\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10a0\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10a6\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10ac\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10ca\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10d6\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10e8\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10ee\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10f4\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1100\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1106\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x110c\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x112a\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1136\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1146\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x114a\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x114e\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1156\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x115a\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x115e\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1172\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x117a\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1186\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x118a\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x118e\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1196\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x119a\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x119e\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x11b2\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x11ba\): Branch to a non-instruction-aligned address\Z
diff --git a/ld/testsuite/ld-mips-elf/unaligned-branch-ignore-mips16.d b/ld/testsuite/ld-mips-elf/unaligned-branch-ignore-mips16.d
new file mode 100644
index 0000000..f6ace4a
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/unaligned-branch-ignore-mips16.d
@@ -0,0 +1,36 @@
+#name: MIPS16 link branch to unaligned symbol (ignore branch ISA)
+#as: -EB -n32 -march=from-abi
+#ld: -EB -Ttext 0x1c000000 -e 0x1c000000 --ignore-branch-isa
+#source: ../../../gas/testsuite/gas/mips/unaligned-branch-mips16-2.s
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1008\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x100e\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1014\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1020\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1026\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x102c\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x104a\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1056\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1068\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x106e\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1074\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1080\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1086\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x108c\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10aa\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10b6\): Branch to a non-instruction-aligned address\Z
diff --git a/ld/testsuite/ld-mips-elf/unaligned-branch-ignore-r6-1.d b/ld/testsuite/ld-mips-elf/unaligned-branch-ignore-r6-1.d
new file mode 100644
index 0000000..b7a11bd
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/unaligned-branch-ignore-r6-1.d
@@ -0,0 +1,72 @@
+#name: MIPSr6 link branch to unaligned symbol 1 (ignore branch ISA)
+#as: -EB -n32 -march=from-abi
+#ld: -EB -Ttext 0x1c000000 -e 0x1c000000 --ignore-branch-isa
+#source: ../../../gas/testsuite/gas/mips/unaligned-branch-r6-3.s
+#error: \A[^\n]*: In function `foo':\n
+#error: \(\.text\+0x101c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1024\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x102c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1034\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x103c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1044\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x104c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1054\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x105c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x107c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1084\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x108c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1094\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x109c\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10a4\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10ac\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10b4\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10bc\): Branch to a non-instruction-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10dc\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10e4\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10f4\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x10fc\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1104\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x110c\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1114\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1124\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x112c\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1134\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x113c\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1144\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x114c\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1164\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x116c\): Cannot convert a branch to JALX for a non-word-aligned address\n
+#error: [^\n]*: In function `foo':\n
+#error: \(\.text\+0x1174\): Cannot convert a branch to JALX for a non-word-aligned address\Z