MIPS: Add options to control branch ISA checks
authorMaciej W. Rozycki <macro@imgtec.com>
Mon, 30 Jan 2017 17:11:22 +0000 (17:11 +0000)
committerMaciej W. Rozycki <macro@imgtec.com>
Mon, 30 Jan 2017 17:16:01 +0000 (17:16 +0000)
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.

25 files changed:
bfd/ChangeLog
bfd/elfxx-mips.c
bfd/elfxx-mips.h
gas/ChangeLog
gas/config/tc-mips.c
gas/doc/as.texinfo
gas/doc/c-mips.texi
gas/testsuite/gas/mips/branch-local-ignore-2.d [new file with mode: 0644]
gas/testsuite/gas/mips/branch-local-ignore-3.d [new file with mode: 0644]
gas/testsuite/gas/mips/branch-local-ignore-n32-2.d [new file with mode: 0644]
gas/testsuite/gas/mips/branch-local-ignore-n32-3.d [new file with mode: 0644]
gas/testsuite/gas/mips/branch-local-ignore-n64-2.d [new file with mode: 0644]
gas/testsuite/gas/mips/branch-local-ignore-n64-3.d [new file with mode: 0644]
gas/testsuite/gas/mips/mips.exp
ld/ChangeLog
ld/emultempl/mipself.em
ld/ld.texinfo
ld/testsuite/ld-mips-elf/bal-jalx-pic-ignore-n32.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/bal-jalx-pic-ignore-n64.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/bal-jalx-pic-ignore.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips-elf.exp
ld/testsuite/ld-mips-elf/unaligned-branch-ignore-2.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/unaligned-branch-ignore-micromips.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/unaligned-branch-ignore-mips16.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/unaligned-branch-ignore-r6-1.d [new file with mode: 0644]

index 4fc1bc0e33d2ec65b925b92fbed0866573ba3590..e7a46644a671dbb4d21554aaaad9571a6718cc24 100644 (file)
@@ -1,3 +1,17 @@
+2017-01-30  Maciej W. Rozycki  <macro@imgtec.com>
+
+       * 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.
+
 2017-01-27  Hans-Peter Nilsson  <hp@axis.com>
 
        * elf32-cris.c (elf_cris_finish_dynamic_symbol): Remove now unused
index ce58c436e9960c273e0377baffe483cdf2f56de8..bda02b128ec0eee9ec35be47a327958ef528c8c5 100644 (file)
@@ -443,6 +443,9 @@ struct mips_elf_link_hash_table
   /* True if we can only use 32-bit microMIPS instructions.  */
   bfd_boolean insn32;
 
+  /* True if we suppress checks for invalid branches between ISA modes.  */
+  bfd_boolean ignore_branch_isa;
+
   /* True if we're generating code for VxWorks.  */
   bfd_boolean is_vxworks;
 
@@ -6416,31 +6419,33 @@ mips_elf_perform_relocation (struct bfd_link_info *info,
          value <<= 2;
        }
 
-      if (bfd_link_pic (info) || !ok)
+      if (ok && !bfd_link_pic (info))
        {
-         info->callbacks->einfo
-           (_("%X%H: Unsupported branch between ISA modes\n"),
-            input_bfd, input_section, relocation->r_offset);
-         return TRUE;
-       }
+         addr = (input_section->output_section->vma
+                 + input_section->output_offset
+                 + relocation->r_offset
+                 + 4);
+         dest = addr + (((value & 0x3ffff) ^ 0x20000) - 0x20000);
 
-      addr = (input_section->output_section->vma
-             + input_section->output_offset
-             + relocation->r_offset
-             + 4);
-      dest = addr + (((value & 0x3ffff) ^ 0x20000) - 0x20000);
+         if ((addr >> 28) << 28 != (dest >> 28) << 28)
+           {
+             info->callbacks->einfo
+               (_("%X%H: Cannot convert branch between ISA modes "
+                  "to JALX: relocation out of range\n"),
+                input_bfd, input_section, relocation->r_offset);
+             return TRUE;
+           }
 
-      if ((addr >> 28) << 28 != (dest >> 28) << 28)
+         /* Make this the JALX opcode.  */
+         x = ((dest >> 2) & 0x3ffffff) | jalx_opcode << 26;
+       }
+      else if (!mips_elf_hash_table (info)->ignore_branch_isa)
        {
          info->callbacks->einfo
-           (_("%X%H: Cannot convert branch between ISA modes "
-              "to JALX: relocation out of range\n"),
+           (_("%X%H: Unsupported branch between ISA modes\n"),
             input_bfd, input_section, relocation->r_offset);
          return TRUE;
        }
-
-      /* Make this the JALX opcode.  */
-      x = ((dest >> 2) & 0x3ffffff) | jalx_opcode << 26;
     }
 
   /* Try converting JAL to BAL and J(AL)R to B(AL), if the target is in
@@ -14095,12 +14100,15 @@ _bfd_mips_elf_use_plts_and_copy_relocs (struct bfd_link_info *info)
 }
 
 /* A function that the linker calls to select between all or only
-   32-bit microMIPS instructions.  */
+   32-bit microMIPS instructions, and between making or ignoring
+   branch relocation checks for invalid transitions between ISA modes.  */
 
 void
-_bfd_mips_elf_insn32 (struct bfd_link_info *info, bfd_boolean on)
+_bfd_mips_elf_linker_flags (struct bfd_link_info *info, bfd_boolean insn32,
+                           bfd_boolean ignore_branch_isa)
 {
-  mips_elf_hash_table (info)->insn32 = on;
+  mips_elf_hash_table (info)->insn32 = insn32;
+  mips_elf_hash_table (info)->ignore_branch_isa = ignore_branch_isa;
 }
 \f
 /* Structure for saying that BFD machine EXTENSION extends BASE.  */
index 8f16cc9c53466a571a182b20ef6b9825fc7b66ff..fa5b5d2de93a27a77d1031e0b818b3b80a49c5f7 100644 (file)
@@ -150,8 +150,8 @@ extern bfd_boolean _bfd_mips_elf_ignore_undef_symbol
   (struct elf_link_hash_entry *);
 extern void _bfd_mips_elf_use_plts_and_copy_relocs
   (struct bfd_link_info *);
-extern void _bfd_mips_elf_insn32
-  (struct bfd_link_info *, bfd_boolean);
+extern void _bfd_mips_elf_linker_flags
+  (struct bfd_link_info *, bfd_boolean, bfd_boolean);
 extern bfd_boolean _bfd_mips_elf_init_stubs
   (struct bfd_link_info *,
    asection *(*) (const char *, asection *, asection *));
index 0f3c73b32ef3ed78e5f1fb2531d4754a2343f24d..69d7c1378f770e5ecdebe69e133cbee2f04510fc 100644 (file)
@@ -1,3 +1,31 @@
+2017-01-30  Maciej W. Rozycki  <macro@imgtec.com>
+
+       * 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.
+
 2017-01-30  Maciej W. Rozycki  <macro@imgtec.com>
 
        * testsuite/gas/mips/branch-local-2.d: New test.
index 02a4e2240a72347c485a5ac564e5309af44f22a9..d151b0124d964f0c04a94fb931e9544d6f83bc66 100644 (file)
@@ -943,6 +943,11 @@ static bfd_boolean mips_fix_cn63xxp1;
    efficient expansion.  */
 
 static int mips_relax_branch;
+
+/* TRUE if checks are suppressed for invalid branches between ISA modes.
+   Needed for broken assembly produced by some GCC versions and some
+   sloppy code out there, where branches to data labels are present.  */
+static bfd_boolean mips_ignore_branch_isa;
 \f
 /* The expansion of many macros depends on the type of symbol that
    they refer to.  For example, when generating position-dependent code,
@@ -1465,6 +1470,8 @@ enum options
     OPTION_GP64,
     OPTION_RELAX_BRANCH,
     OPTION_NO_RELAX_BRANCH,
+    OPTION_IGNORE_BRANCH_ISA,
+    OPTION_NO_IGNORE_BRANCH_ISA,
     OPTION_INSN32,
     OPTION_NO_INSN32,
     OPTION_MSHARED,
@@ -1591,6 +1598,8 @@ struct option md_longopts[] =
   {"mgp64", no_argument, NULL, OPTION_GP64},
   {"relax-branch", no_argument, NULL, OPTION_RELAX_BRANCH},
   {"no-relax-branch", no_argument, NULL, OPTION_NO_RELAX_BRANCH},
+  {"mignore-branch-isa", no_argument, NULL, OPTION_IGNORE_BRANCH_ISA},
+  {"mno-ignore-branch-isa", no_argument, NULL, OPTION_NO_IGNORE_BRANCH_ISA},
   {"minsn32", no_argument, NULL, OPTION_INSN32},
   {"mno-insn32", no_argument, NULL, OPTION_NO_INSN32},
   {"mshared", no_argument, NULL, OPTION_MSHARED},
@@ -14499,6 +14508,14 @@ md_parse_option (int c, const char *arg)
       mips_relax_branch = 0;
       break;
 
+    case OPTION_IGNORE_BRANCH_ISA:
+      mips_ignore_branch_isa = TRUE;
+      break;
+
+    case OPTION_NO_IGNORE_BRANCH_ISA:
+      mips_ignore_branch_isa = FALSE;
+      break;
+
     case OPTION_INSN32:
       file_mips_opts.insn32 = TRUE;
       break;
@@ -15133,6 +15150,9 @@ fix_bad_cross_mode_branch_p (fixS *fixP)
   int other;
   char *buf;
 
+  if (mips_ignore_branch_isa)
+    return FALSE;
+
   if (!fixP->fx_addsy || S_FORCE_RELOC (fixP->fx_addsy, TRUE))
     return FALSE;
 
@@ -19662,6 +19682,8 @@ MIPS options:\n\
 -mdouble-float         allow 32-bit and 64-bit floating-point operations\n\
 --[no-]construct-floats        [dis]allow floating point values to be constructed\n\
 --[no-]relax-branch    [dis]allow out-of-range branches to be relaxed\n\
+-mignore-branch-isa    accept invalid branches requiring an ISA mode switch\n\
+-mno-ignore-branch-isa reject invalid branches requiring an ISA mode switch\n\
 -mnan=ENCODING         select an IEEE 754 NaN encoding convention, either of:\n"));
 
   first = 1;
index 5e30fc4d8ac583ef89e55702036c53c0978dfc30..007332ee46c438cda13111e7fc54df1ec14b1795 100644 (file)
@@ -416,6 +416,7 @@ gcc(1), ld(1), and the Info entries for @file{binutils} and @file{ld}.
    [@b{-mips32r3}] [@b{-mips32r5}] [@b{-mips32r6}] [@b{-mips64}] [@b{-mips64r2}]
    [@b{-mips64r3}] [@b{-mips64r5}] [@b{-mips64r6}]
    [@b{-construct-floats}] [@b{-no-construct-floats}]
+   [@b{-mignore-branch-isa}] [@b{-mno-ignore-branch-isa}]
    [@b{-mnan=@var{encoding}}]
    [@b{-trap}] [@b{-no-break}] [@b{-break}] [@b{-no-trap}]
    [@b{-mips16}] [@b{-no-mips16}]
@@ -1546,6 +1547,17 @@ The @samp{--relax-branch} option enables the relaxation of out-of-range
 branches.  By default @samp{--no-relax-branch} is selected, causing any
 out-of-range branches to produce an error.
 
+@item -mignore-branch-isa
+@itemx -mno-ignore-branch-isa
+Ignore branch checks for invalid transitions between ISA modes.  The
+semantics of branches does not provide for an ISA mode switch, so in
+most cases the ISA mode a branch has been encoded for has to be the
+same as the ISA mode of the branch's target label.  Therefore GAS has
+checks implemented that verify in branch assembly that the two ISA
+modes match.  @samp{-mignore-branch-isa} disables these checks.  By
+default @samp{-mno-ignore-branch-isa} is selected, causing any invalid
+branch requiring a transition between ISA modes to produce an error.
+
 @item -mnan=@var{encoding}
 Select between the IEEE 754-2008 (@option{-mnan=2008}) or the legacy
 (@option{-mnan=legacy}) NaN encoding format.  The latter is the default.
index 04666f42a6f2cf9860b4506fcd6dc2c34ef293c7..d9a09f1940ca6c58fb513bab682935a1af956e03 100644 (file)
@@ -472,6 +472,37 @@ Also no MIPS16 branches are ever relaxed.
 By default @samp{--no-relax-branch} is selected, causing any out-of-range
 branches to produce an error.
 
+@item -mignore-branch-isa
+@itemx -mno-ignore-branch-isa
+Ignore branch checks for invalid transitions between ISA modes.
+
+The semantics of branches does not provide for an ISA mode switch, so in
+most cases the ISA mode a branch has been encoded for has to be the same
+as the ISA mode of the branch's target label.  If the ISA modes do not
+match, then such a branch, if taken, will cause the ISA mode to remain
+unchanged and instructions that follow will be executed in the wrong ISA
+mode causing the program to misbehave or crash.
+
+In the case of the @code{BAL} instruction it may be possible to relax
+it to an equivalent @code{JALX} instruction so that the ISA mode is
+switched at the run time as required.  For other branches no relaxation
+is possible and therefore GAS has checks implemented that verify in
+branch assembly that the two ISA modes match, and report an error
+otherwise so that the problem with code can be diagnosed at the assembly
+time rather than at the run time.
+
+However some assembly code, including generated code produced by some
+versions of GCC, may incorrectly include branches to data labels, which
+appear to require a mode switch but are either dead or immediately
+followed by valid instructions encoded for the same ISA the branch has
+been encoded for.  While not strictly correct at the source level such
+code will execute as intended, so to help with these cases
+@samp{-mignore-branch-isa} is supported which disables ISA mode checks
+for branches.
+
+By default @samp{-mno-ignore-branch-isa} is selected, causing any invalid
+branch requiring a transition between ISA modes to produce an error.
+
 @cindex @option{-mnan=} command line option, MIPS
 @item -mnan=@var{encoding}
 This option indicates whether the source code uses the IEEE 2008
diff --git a/gas/testsuite/gas/mips/branch-local-ignore-2.d b/gas/testsuite/gas/mips/branch-local-ignore-2.d
new file mode 100644 (file)
index 0000000..ddac741
--- /dev/null
@@ -0,0 +1,29 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS branch local symbol relocation 2 (ignore branch ISA)
+#as: -32 -mignore-branch-isa
+#source: branch-local-2.s
+
+.*: +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]+ <[^>]*> 1000ffff     b       00001014 <bar\+0x4>
+[      ]*[0-9a-f]+: R_MIPS_PC16        foo
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+[0-9a-f]+ <[^>]*> 1443ffff     bne     v0,v1,0000101c <bar\+0xc>
+[      ]*[0-9a-f]+: R_MIPS_PC16        foo
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+[0-9a-f]+ <[^>]*> 0451ffff     bgezal  v0,00001024 <bar\+0x14>
+[      ]*[0-9a-f]+: R_MIPS_PC16        foo
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+[0-9a-f]+ <[^>]*> 0450ffff     bltzal  v0,0000102c <bar\+0x1c>
+[      ]*[0-9a-f]+: R_MIPS_PC16        foo
+[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/gas/testsuite/gas/mips/branch-local-ignore-3.d b/gas/testsuite/gas/mips/branch-local-ignore-3.d
new file mode 100644 (file)
index 0000000..918a2ce
--- /dev/null
@@ -0,0 +1,23 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -mmips:isa32r6
+#name: MIPS branch local symbol relocation 3 (ignore branch ISA)
+#as: -32 -mignore-branch-isa
+#source: branch-local-3.s
+
+.*: +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]+ <[^>]*> cbffffff     bc      00001014 <bar\+0x4>
+[      ]*[0-9a-f]+: R_MIPS_PC26_S2     foo
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+[0-9a-f]+ <[^>]*> d85fffff     beqzc   v0,0000101c <bar\+0xc>
+[      ]*[0-9a-f]+: R_MIPS_PC21_S2     foo
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+[0-9a-f]+ <[^>]*> 03e00009     jr      ra
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+       \.\.\.
diff --git a/gas/testsuite/gas/mips/branch-local-ignore-n32-2.d b/gas/testsuite/gas/mips/branch-local-ignore-n32-2.d
new file mode 100644 (file)
index 0000000..080402c
--- /dev/null
@@ -0,0 +1,29 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS branch local symbol relocation 2 (ignore branch ISA, n32)
+#as: -n32 -march=from-abi -mignore-branch-isa
+#source: branch-local-2.s
+
+.*: +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]+ <[^>]*> 10000000     b       00001018 <bar\+0x8>
+[      ]*[0-9a-f]+: R_MIPS_PC16        foo-0x4
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000     bne     v0,v1,00001020 <bar\+0x10>
+[      ]*[0-9a-f]+: R_MIPS_PC16        foo-0x4
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+[0-9a-f]+ <[^>]*> 04510000     bgezal  v0,00001028 <bar\+0x18>
+[      ]*[0-9a-f]+: R_MIPS_PC16        foo-0x4
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+[0-9a-f]+ <[^>]*> 04500000     bltzal  v0,00001030 <bar\+0x20>
+[      ]*[0-9a-f]+: R_MIPS_PC16        foo-0x4
+[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/gas/testsuite/gas/mips/branch-local-ignore-n32-3.d b/gas/testsuite/gas/mips/branch-local-ignore-n32-3.d
new file mode 100644 (file)
index 0000000..a4dbc7f
--- /dev/null
@@ -0,0 +1,23 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -mmips:isa32r6
+#name: MIPS branch local symbol relocation 3 (ignore branch ISA, n32)
+#as: -n32 -march=from-abi -mignore-branch-isa
+#source: branch-local-3.s
+
+.*: +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]+ <[^>]*> c8000000     bc      00001018 <bar\+0x8>
+[      ]*[0-9a-f]+: R_MIPS_PC26_S2     foo-0x4
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+[0-9a-f]+ <[^>]*> d8400000     beqzc   v0,00001020 <bar\+0x10>
+[      ]*[0-9a-f]+: R_MIPS_PC21_S2     foo-0x4
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+[0-9a-f]+ <[^>]*> 03e00009     jr      ra
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+       \.\.\.
diff --git a/gas/testsuite/gas/mips/branch-local-ignore-n64-2.d b/gas/testsuite/gas/mips/branch-local-ignore-n64-2.d
new file mode 100644 (file)
index 0000000..12cd510
--- /dev/null
@@ -0,0 +1,37 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#name: MIPS branch local symbol relocation 2 (ignore branch ISA, n64)
+#as: -64 -march=from-abi -mignore-branch-isa
+#source: branch-local-2.s
+
+.*: +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]+ <[^>]*> 10000000     b       0000000000001018 <bar\+0x8>
+[      ]*[0-9a-f]+: R_MIPS_PC16        foo-0x4
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*-0x4
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*-0x4
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+[0-9a-f]+ <[^>]*> 14430000     bne     v0,v1,0000000000001020 <bar\+0x10>
+[      ]*[0-9a-f]+: R_MIPS_PC16        foo-0x4
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*-0x4
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*-0x4
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+[0-9a-f]+ <[^>]*> 04510000     bgezal  v0,0000000000001028 <bar\+0x18>
+[      ]*[0-9a-f]+: R_MIPS_PC16        foo-0x4
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*-0x4
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*-0x4
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+[0-9a-f]+ <[^>]*> 04500000     bltzal  v0,0000000000001030 <bar\+0x20>
+[      ]*[0-9a-f]+: R_MIPS_PC16        foo-0x4
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*-0x4
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*-0x4
+[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/gas/testsuite/gas/mips/branch-local-ignore-n64-3.d b/gas/testsuite/gas/mips/branch-local-ignore-n64-3.d
new file mode 100644 (file)
index 0000000..9d6dca9
--- /dev/null
@@ -0,0 +1,27 @@
+#objdump: -dr --prefix-addresses --show-raw-insn -mmips:isa32r6
+#name: MIPS branch local symbol relocation 3 (ignore branch ISA, n64)
+#as: -64 -march=from-abi -mignore-branch-isa
+#source: branch-local-3.s
+
+.*: +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]+ <[^>]*> c8000000     bc      0000000000001018 <bar\+0x8>
+[      ]*[0-9a-f]+: R_MIPS_PC26_S2     foo-0x4
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*-0x4
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*-0x4
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+[0-9a-f]+ <[^>]*> d8400000     beqzc   v0,0000000000001020 <bar\+0x10>
+[      ]*[0-9a-f]+: R_MIPS_PC21_S2     foo-0x4
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*-0x4
+[      ]*[0-9a-f]+: R_MIPS_NONE        \*ABS\*-0x4
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+[0-9a-f]+ <[^>]*> 03e00009     jr      ra
+[0-9a-f]+ <[^>]*> 00000027     nor     zero,zero,zero
+       \.\.\.
index 4580fbf8346bf99af81cee30006a2f66f5e31891..5a695427bc287d7cd42cf3f45611764f4f1593c9 100644 (file)
@@ -626,16 +626,22 @@ if { [istarget mips*-*-vxworks*] } {
     run_dump_test "branch-weak-7"
     run_dump_test "branch-local-1"
     run_dump_test "branch-local-2"
+    run_dump_test "branch-local-ignore-2"
     run_dump_test "branch-local-3"
+    run_dump_test "branch-local-ignore-3"
     run_dump_test "branch-local-4"
     if $has_newabi {
        run_dump_test "branch-local-n32-1"
        run_dump_test "branch-local-n32-2"
+       run_dump_test "branch-local-ignore-n32-2"
        run_dump_test "branch-local-n32-3"
+       run_dump_test "branch-local-ignore-n32-3"
        run_dump_test "branch-local-n32-4"
        run_dump_test "branch-local-n64-1"
        run_dump_test "branch-local-n64-2"
+       run_dump_test "branch-local-ignore-n64-2"
        run_dump_test "branch-local-n64-3"
+       run_dump_test "branch-local-ignore-n64-3"
        run_dump_test "branch-local-n64-4"
     }
     run_dump_test "branch-addend"
index fec48e2eb9babfb2e5710c59ce231c87cec35945..5c5504c69f10e015591ab87a141fe434fba9541a 100644 (file)
@@ -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
index 74ede8742105868ef452b359b4448762b42e3d1d..cd68707ec388046c83fdaa1b240ce3ace378a835 100644 (file)
@@ -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
index 2ce7560f2296bfc5a77b717b6e27bc75a83d9a53..8f2dfdb1a296bd4551c348b3e150fe33a1afaaac 100644 (file)
@@ -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 (file)
index 0000000..c402ba8
--- /dev/null
@@ -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 (file)
index 0000000..e1bbb92
--- /dev/null
@@ -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 (file)
index 0000000..279b87a
--- /dev/null
@@ -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
+       \.\.\.
index 5639c8417fbc6aba1780c20b8a0eb4d91b0827fb..7fa11c5989d1ad2d9bda5c4b392a842ef0835234 100644 (file)
@@ -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 (file)
index 0000000..323c43a
--- /dev/null
@@ -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 (file)
index 0000000..6a62fe5
--- /dev/null
@@ -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 (file)
index 0000000..f6ace4a
--- /dev/null
@@ -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 (file)
index 0000000..b7a11bd
--- /dev/null
@@ -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