From 8b10b0b3e100c25322a083248c7a18bf5a1f3527 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Mon, 30 Jan 2017 17:11:22 +0000 Subject: 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'"), . 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. --- gas/config/tc-mips.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'gas/config/tc-mips.c') diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c index 02a4e22..d151b01 100644 --- a/gas/config/tc-mips.c +++ b/gas/config/tc-mips.c @@ -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; /* 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; -- cgit v1.1