i386.opt (mmitigate-rop): Mark as deprecated.
authorUros Bizjak <ubizjak@gmail.com>
Wed, 15 Aug 2018 21:07:08 +0000 (23:07 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Wed, 15 Aug 2018 21:07:08 +0000 (23:07 +0200)
* config/i386/i386.opt (mmitigate-rop): Mark as deprecated.
* doc/invoke.texi (mmitigate-rop): Remove.
* config/i386/i386.c: Do not include "regrename.h".
(ix86_rop_should_change_byte_p, reg_encoded_number)
(ix86_get_modrm_for_rop, set_rop_modrm_reg_bits, ix86_mitigate_rop):
Remove.
(ix86_reorg): Remove call to ix86_mitigate_rop.
* config/i386/i386.md (attr "modrm_class"): Remove.
(cmp<mode>_ccno_1, mov<mode>_xor, movstrict<mode>_xor)
(x86_mov<mode>cc_0_m1. x86_mov<mode>cc_0_m1_se)
(x86_mov<mode>cc_0_m1_neg): Remove modrm_class attribute override.

testsuite/Changelog:

* gcc.target/i386/rop1.c: Remove.
* gcc.target/i386/pr83554 (dg-options): Remove -mmitigate-rop.

From-SVN: r263572

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.md
gcc/config/i386/i386.opt
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr83554.c
gcc/testsuite/gcc.target/i386/rop1.c [deleted file]

index d39a1cf5b50862e6375c601c3118506e07188e4b..609d28b51532ea86c128718f8427df7b6e2b49e2 100644 (file)
@@ -1,3 +1,17 @@
+2018-08-15  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/i386.opt (mmitigate-rop): Mark as deprecated.
+       * doc/invoke.texi (mmitigate-rop): Remove.
+       * config/i386/i386.c: Do not include "regrename.h".
+       (ix86_rop_should_change_byte_p, reg_encoded_number)
+       (ix86_get_modrm_for_rop, set_rop_modrm_reg_bits, ix86_mitigate_rop):
+       Remove.
+       (ix86_reorg): Remove call to ix86_mitigate_rop.
+       * config/i386/i386.md (attr "modrm_class"): Remove.
+       (cmp<mode>_ccno_1, mov<mode>_xor, movstrict<mode>_xor)
+       (x86_mov<mode>cc_0_m1. x86_mov<mode>cc_0_m1_se)
+       (x86_mov<mode>cc_0_m1_neg): Remove modrm_class attribute override.
+
 2018-08-15  Will Schmidt  <will_schmidt@vnet.ibm.com>
 
        * config/rs6000/rs600.c (rs6000_gimple_fold_builtin): Add entries to
index dad91c1dcf78689c393d61a17c5534bd4d0bf869..3548de2169c2b947f132b01f6966ec38a0985218 100644 (file)
@@ -75,7 +75,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-iterator.h"
 #include "dbgcnt.h"
 #include "case-cfn-macros.h"
-#include "regrename.h"
 #include "dojump.h"
 #include "fold-const-call.h"
 #include "tree-vrp.h"
@@ -3135,15 +3134,6 @@ ix86_debug_options (void)
   return;
 }
 
-/* Return true if T is one of the bytes we should avoid with
-   -mmitigate-rop.  */
-
-static bool
-ix86_rop_should_change_byte_p (int t)
-{
-  return t == 0xc2 || t == 0xc3 || t == 0xca || t == 0xcb;
-}
-
 static const char *stringop_alg_names[] = {
 #define DEF_ENUM
 #define DEF_ALG(alg, name) #name,
@@ -29110,98 +29100,6 @@ ix86_instantiate_decls (void)
       instantiate_decl_rtl (s->rtl);
 }
 \f
-/* Return the number used for encoding REG, in the range 0..7.  */
-
-static int
-reg_encoded_number (rtx reg)
-{
-  unsigned regno = REGNO (reg);
-  switch (regno)
-    {
-    case AX_REG:
-      return 0;
-    case CX_REG:
-      return 1;
-    case DX_REG:
-      return 2;
-    case BX_REG:
-      return 3;
-    case SP_REG:
-      return 4;
-    case BP_REG:
-      return 5;
-    case SI_REG:
-      return 6;
-    case DI_REG:
-      return 7;
-    default:
-      break;
-    }
-  if (IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG))
-    return regno - FIRST_STACK_REG;
-  if (IN_RANGE (regno, FIRST_SSE_REG, LAST_SSE_REG))
-    return regno - FIRST_SSE_REG;
-  if (IN_RANGE (regno, FIRST_MMX_REG, LAST_MMX_REG))
-    return regno - FIRST_MMX_REG;
-  if (IN_RANGE (regno, FIRST_REX_SSE_REG, LAST_REX_SSE_REG))
-    return regno - FIRST_REX_SSE_REG;
-  if (IN_RANGE (regno, FIRST_REX_INT_REG, LAST_REX_INT_REG))
-    return regno - FIRST_REX_INT_REG;
-  if (IN_RANGE (regno, FIRST_MASK_REG, LAST_MASK_REG))
-    return regno - FIRST_MASK_REG;
-  return -1;
-}
-
-/* Given an insn INSN with NOPERANDS OPERANDS, return the modr/m byte used
-   in its encoding if it could be relevant for ROP mitigation, otherwise
-   return -1.  If POPNO0 and POPNO1 are nonnull, store the operand numbers
-   used for calculating it into them.  */
-
-static int
-ix86_get_modrm_for_rop (rtx_insn *insn, rtx *operands, int noperands,
-                       int *popno0 = 0, int *popno1 = 0)
-{
-  if (asm_noperands (PATTERN (insn)) >= 0)
-    return -1;
-  int has_modrm = get_attr_modrm (insn);
-  if (!has_modrm)
-    return -1;
-  enum attr_modrm_class cls = get_attr_modrm_class (insn);
-  rtx op0, op1;
-  switch (cls)
-    {
-    case MODRM_CLASS_OP02:
-      gcc_assert (noperands >= 3);
-      if (popno0)
-       {
-         *popno0 = 0;
-         *popno1 = 2;
-       }
-      op0 = operands[0];
-      op1 = operands[2];
-      break;
-    case MODRM_CLASS_OP01:
-      gcc_assert (noperands >= 2);
-      if (popno0)
-       {
-         *popno0 = 0;
-         *popno1 = 1;
-       }
-      op0 = operands[0];
-      op1 = operands[1];
-      break;
-    default:
-      return -1;
-    }
-  if (REG_P (op0) && REG_P (op1))
-    {
-      int enc0 = reg_encoded_number (op0);
-      int enc1 = reg_encoded_number (op1);
-      return 0xc0 + (enc1 << 3) + enc0;
-    }
-  return -1;
-}
-
 /* Check whether x86 address PARTS is a pc-relative address.  */
 
 bool
@@ -42215,215 +42113,6 @@ ix86_seh_fixup_eh_fallthru (void)
     }
 }
 
-/* Given a register number BASE, the lowest of a group of registers, update
-   regsets IN and OUT with the registers that should be avoided in input
-   and output operands respectively when trying to avoid generating a modr/m
-   byte for -mmitigate-rop.  */
-
-static void
-set_rop_modrm_reg_bits (int base, HARD_REG_SET &in, HARD_REG_SET &out)
-{
-  SET_HARD_REG_BIT (out, base);
-  SET_HARD_REG_BIT (out, base + 1);
-  SET_HARD_REG_BIT (in, base + 2);
-  SET_HARD_REG_BIT (in, base + 3);
-}
-
-/* Called if -mmitigate-rop is in effect.  Try to rewrite instructions so
-   that certain encodings of modr/m bytes do not occur.  */
-static void
-ix86_mitigate_rop (void)
-{
-  HARD_REG_SET input_risky;
-  HARD_REG_SET output_risky;
-  HARD_REG_SET inout_risky;
-
-  CLEAR_HARD_REG_SET (output_risky);
-  CLEAR_HARD_REG_SET (input_risky);
-  SET_HARD_REG_BIT (output_risky, AX_REG);
-  SET_HARD_REG_BIT (output_risky, CX_REG);
-  SET_HARD_REG_BIT (input_risky, BX_REG);
-  SET_HARD_REG_BIT (input_risky, DX_REG);
-  set_rop_modrm_reg_bits (FIRST_SSE_REG, input_risky, output_risky);
-  set_rop_modrm_reg_bits (FIRST_REX_INT_REG, input_risky, output_risky);
-  set_rop_modrm_reg_bits (FIRST_REX_SSE_REG, input_risky, output_risky);
-  set_rop_modrm_reg_bits (FIRST_EXT_REX_SSE_REG, input_risky, output_risky);
-  set_rop_modrm_reg_bits (FIRST_MASK_REG, input_risky, output_risky);
-  COPY_HARD_REG_SET (inout_risky, input_risky);
-  IOR_HARD_REG_SET (inout_risky, output_risky);
-
-  df_note_add_problem ();
-  /* Fix up what stack-regs did.  */
-  df_insn_rescan_all ();
-  df_analyze ();
-
-  regrename_init (true);
-  regrename_analyze (NULL);
-
-  auto_vec<du_head_p> cands;
-  
-  for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
-    {
-      if (!NONDEBUG_INSN_P (insn))
-       continue;
-
-      if (GET_CODE (PATTERN (insn)) == USE
-         || GET_CODE (PATTERN (insn)) == CLOBBER)
-       continue;
-
-      extract_insn (insn);
-
-      int opno0, opno1;
-      int modrm = ix86_get_modrm_for_rop (insn, recog_data.operand,
-                                         recog_data.n_operands, &opno0,
-                                         &opno1);
-
-      if (!ix86_rop_should_change_byte_p (modrm))
-       continue;
-
-      insn_rr_info *info = &insn_rr[INSN_UID (insn)];
-
-      /* This happens when regrename has to fail a block.  */
-      if (!info->op_info)
-       continue;
-
-      if (info->op_info[opno0].n_chains != 0)
-       {
-         gcc_assert (info->op_info[opno0].n_chains == 1);
-         du_head_p op0c;
-         op0c = regrename_chain_from_id (info->op_info[opno0].heads[0]->id);
-         if (op0c->target_data_1 + op0c->target_data_2 == 0
-             && !op0c->cannot_rename)
-           cands.safe_push (op0c);
-
-         op0c->target_data_1++;
-       }
-      if (info->op_info[opno1].n_chains != 0)
-       {
-         gcc_assert (info->op_info[opno1].n_chains == 1);
-         du_head_p op1c;
-         op1c = regrename_chain_from_id (info->op_info[opno1].heads[0]->id);
-         if (op1c->target_data_1 + op1c->target_data_2 == 0
-             && !op1c->cannot_rename)
-           cands.safe_push (op1c);
-
-         op1c->target_data_2++;
-       }
-    }
-
-  int i;
-  du_head_p head;
-  FOR_EACH_VEC_ELT (cands, i, head)
-    {
-      int old_reg, best_reg;
-      HARD_REG_SET unavailable;
-
-      CLEAR_HARD_REG_SET (unavailable);
-      if (head->target_data_1)
-       IOR_HARD_REG_SET (unavailable, output_risky);
-      if (head->target_data_2)
-       IOR_HARD_REG_SET (unavailable, input_risky);
-
-      int n_uses;
-      reg_class superclass = regrename_find_superclass (head, &n_uses,
-                                                       &unavailable);
-      old_reg = head->regno;
-      best_reg = find_rename_reg (head, superclass, &unavailable,
-                                 old_reg, false);
-      bool ok = regrename_do_replace (head, best_reg);
-      gcc_assert (ok);
-      if (dump_file)
-       fprintf (dump_file, "Chain %d renamed as %s in %s\n", head->id,
-                reg_names[best_reg], reg_class_names[superclass]);
-
-    }
-  
-  regrename_finish ();
-
-  df_analyze ();
-
-  basic_block bb;
-  regset_head live;
-
-  INIT_REG_SET (&live);
-
-  FOR_EACH_BB_FN (bb, cfun)
-    {
-      rtx_insn *insn;
-
-      COPY_REG_SET (&live, DF_LR_OUT (bb));
-      df_simulate_initialize_backwards (bb, &live);
-
-      FOR_BB_INSNS_REVERSE (bb, insn)
-       {
-         if (!NONDEBUG_INSN_P (insn))
-           continue;
-
-         df_simulate_one_insn_backwards (bb, insn, &live);
-
-         if (GET_CODE (PATTERN (insn)) == USE
-             || GET_CODE (PATTERN (insn)) == CLOBBER)
-           continue;
-
-         extract_insn (insn);
-         constrain_operands_cached (insn, reload_completed);
-         int opno0, opno1;
-         int modrm = ix86_get_modrm_for_rop (insn, recog_data.operand,
-                                             recog_data.n_operands, &opno0,
-                                             &opno1);
-         if (modrm < 0
-             || !ix86_rop_should_change_byte_p (modrm)
-             || opno0 == opno1)
-           continue;
-
-         rtx oldreg = recog_data.operand[opno1];
-         preprocess_constraints (insn);
-         const operand_alternative *alt = which_op_alt ();
-
-         int i;
-         for (i = 0; i < recog_data.n_operands; i++)
-           if (i != opno1
-               && alt[i].earlyclobber
-               && reg_overlap_mentioned_p (recog_data.operand[i],
-                                           oldreg))
-             break;
-
-         if (i < recog_data.n_operands)
-           continue;
-
-         if (dump_file)
-           fprintf (dump_file,
-                    "attempting to fix modrm byte in insn %d:"
-                    " reg %d class %s", INSN_UID (insn), REGNO (oldreg),
-                    reg_class_names[alt[opno1].cl]);
-
-         HARD_REG_SET unavailable;
-         REG_SET_TO_HARD_REG_SET (unavailable, &live);
-         SET_HARD_REG_BIT (unavailable, REGNO (oldreg));
-         IOR_COMPL_HARD_REG_SET (unavailable, call_used_reg_set);
-         IOR_HARD_REG_SET (unavailable, fixed_reg_set);
-         IOR_HARD_REG_SET (unavailable, output_risky);
-         IOR_COMPL_HARD_REG_SET (unavailable,
-                                 reg_class_contents[alt[opno1].cl]);
-
-         for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-             if (!TEST_HARD_REG_BIT (unavailable, i))
-               break;
-         if (i == FIRST_PSEUDO_REGISTER)
-           {
-             if (dump_file)
-               fprintf (dump_file, ", none available\n");
-             continue;
-           }
-         if (dump_file)
-           fprintf (dump_file, " -> %d\n", i);
-         rtx newreg = gen_rtx_REG (recog_data.operand_mode[opno1], i);
-         validate_change (insn, recog_data.operand_loc[opno1], newreg, false);
-         insn = emit_insn_before (gen_move_insn (newreg, oldreg), insn);
-       }
-    }
-}
-
 /* Implement machine specific optimizations.  We implement padding of returns
    for K8 CPUs and pass to avoid 4 jumps in the single 16 byte window.  */
 static void
@@ -42433,9 +42122,6 @@ ix86_reorg (void)
      with old MDEP_REORGS that are not CFG based.  Recompute it now.  */
   compute_bb_for_insn ();
 
-  if (flag_mitigate_rop)
-    ix86_mitigate_rop ();
-  
   if (TARGET_SEH && current_function_has_exception_handlers ())
     ix86_seh_fixup_eh_fallthru ();
 
index 10783d305d24ea12cd9def9a4e579da628d35c62..918241d953a656b063b827469671f0ba9e07a3bc 100644 (file)
         ]
         (const_int 1)))
 
-(define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
-  (cond [(eq_attr "modrm" "0")
-          (const_string "none")
-        (eq_attr "type" "alu,imul,ishift")
-          (const_string "op02")
-        (eq_attr "type" "imov,imovx,lea,alu1,icmp")
-          (const_string "op01")
-        (eq_attr "type" "incdec")
-          (const_string "incdec")
-        (eq_attr "type" "push,pop")
-          (const_string "pushpop")]
-        (const_string "unknown")))
-
 ;; The (bounding maximum) length of an instruction in bytes.
 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
 ;; Later we may want to split them and compute proper length as for
    ktest<mskmodesuffix>\t%0, %0"
   [(set_attr "type" "test,icmp,msklog")
    (set_attr "length_immediate" "0,1,*")
-   (set_attr "modrm_class" "op0,unknown,*")
    (set_attr "prefix" "*,*,vex")
    (set_attr "mode" "<MODE>")])
 
    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
   [(set_attr "type" "test,icmp")
    (set_attr "length_immediate" "0,1")
-   (set_attr "modrm_class" "op0,unknown")
    (set_attr "mode" "<MODE>")])
 
 (define_insn "*cmp<mode>_1"
   "reload_completed"
   "xor{l}\t%k0, %k0"
   [(set_attr "type" "alu1")
-   (set_attr "modrm_class" "op0")
    (set_attr "mode" "SI")
    (set_attr "length_immediate" "0")])
 
   "reload_completed"
   "xor{<imodesuffix>}\t%0, %0"
   [(set_attr "type" "alu1")
-   (set_attr "modrm_class" "op0")
    (set_attr "mode" "<MODE>")
    (set_attr "length_immediate" "0")])
 
   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
   [(set_attr "type" "lea")
    (set_attr "length_address" "4")
-   (set_attr "modrm_class" "unknown")
    (set_attr "mode" "DI")])
 
 (define_insn "set_rip_rex64"
   ""
   "sbb{<imodesuffix>}\t%0, %0"
   [(set_attr "type" "alu1")
-   (set_attr "modrm_class" "op0")
    (set_attr "use_carry" "1")
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "<MODE>")
   ""
   "sbb{<imodesuffix>}\t%0, %0"
   [(set_attr "type" "alu1")
-   (set_attr "modrm_class" "op0")
    (set_attr "use_carry" "1")
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "<MODE>")
   ""
   "sbb{<imodesuffix>}\t%0, %0"
   [(set_attr "type" "alu1")
-   (set_attr "modrm_class" "op0")
    (set_attr "use_carry" "1")
    (set_attr "pent_pair" "pu")
    (set_attr "mode" "<MODE>")
index a34d4acf1a26e9d4bb1974f2d7d061979a660eeb..3724994760db16d819900a2aa31b71a36cace648 100644 (file)
@@ -842,7 +842,7 @@ Target Report Mask(ISA_CLWB) Var(ix86_isa_flags) Save
 Support CLWB instruction.
 
 mpcommit
-Target Undocumented Warn(%<-mpcommit%> was deprecated)
+Target Ignore Warn(%qs was deprecated)
 ;; Deprecated
 
 mfxsr
@@ -999,8 +999,8 @@ Target RejectNegative Joined Integer Var(ix86_stack_protector_guard_symbol_str)
 Use the given symbol for addressing the stack-protector guard.
 
 mmitigate-rop
-Target Var(flag_mitigate_rop)
-Attempt to avoid generating instruction sequences containing ret bytes.
+Target Ignore Warn(%qs was deprecated)
+;; Deprecated
 
 mgeneral-regs-only
 Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flags) Save
index 586af1787c7f7c4760125784bed665b86b1181a6..d91e6c5e36d4fe3fbaf6817c05e5413a62f1a6dd 100644 (file)
@@ -1292,7 +1292,7 @@ See RS/6000 and PowerPC Options.
 -malign-data=@var{type}  -mstack-protector-guard=@var{guard} @gol
 -mstack-protector-guard-reg=@var{reg} @gol
 -mstack-protector-guard-offset=@var{offset} @gol
--mstack-protector-guard-symbol=@var{symbol} -mmitigate-rop @gol
+-mstack-protector-guard-symbol=@var{symbol} @gol
 -mgeneral-regs-only -mcall-ms2sysv-xlogues @gol
 -mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol
 -mindirect-branch-register}
@@ -28003,13 +28003,6 @@ which segment register (@code{%fs} or @code{%gs}) to use as base register
 for reading the canary, and from what offset from that base register.
 The default for those is as specified in the relevant ABI.
 
-@item -mmitigate-rop
-@opindex mmitigate-rop
-Try to avoid generating code sequences that contain unintended return
-opcodes, to mitigate against certain forms of attack. At the moment,
-this option is limited in what it can do and should not be relied
-on to provide serious protection.
-
 @item -mgeneral-regs-only
 @opindex mgeneral-regs-only
 Generate code that uses only the general-purpose registers.  This
index f8be6137cadf9ea0bdb52180ae165d8ccc2a1fe0..39ce2776578f6b341f69712f2daea4101d5c6a16 100644 (file)
@@ -1,3 +1,8 @@
+2018-08-15  Uros Bizjak  <ubizjak@gmail.com>
+
+       * gcc.target/i386/rop1.c: Remove.
+       * gcc.target/i386/pr83554 (dg-options): Remove -mmitigate-rop.
+
 2018-08-15  Will Schmidt  <will_schmidt@vnet.ibm.com>
 
        * gcc.target/powerpc/fold-vec-splat-char.c: New.
index 63ab366ae90a82719045748c42598ea014bb7587..615971527f5992c4b9e78dc8ea6b7699bf6c8d84 100644 (file)
@@ -1,6 +1,6 @@
 /* PR target/83554 */
 /* { dg-do compile { target int128 } } */
-/* { dg-options "-Os -mmitigate-rop" } */
+/* { dg-options "-Os" } */
 
 unsigned a;
 unsigned __int128
diff --git a/gcc/testsuite/gcc.target/i386/rop1.c b/gcc/testsuite/gcc.target/i386/rop1.c
deleted file mode 100644 (file)
index 0b37267..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/* { dg-do compile } */
-/* { dg-require-effective-target lp64 } */
-/* { dg-options "-mcmodel=medium -mmitigate-rop" } */
-void
-foo (void)
-{
-}