/* Harden conditionals.
   Copyright (C) 2021-2022 Free Software Foundation, Inc.
   Contributed by Alexandre Oliva <oliva@adacore.com>.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "fold-const.h"
#include "gimple.h"
#include "gimplify.h"
#include "tree-pass.h"
#include "ssa.h"
#include "gimple-iterator.h"
#include "tree-cfg.h"
#include "basic-block.h"
#include "cfghooks.h"
#include "cfgloop.h"
#include "tree-eh.h"
#include "sbitmap.h"
#include "diagnostic.h"
#include "intl.h"

namespace {

/* These passes introduces redundant, but reversed conditionals at
   compares, such as those used in conditional branches, and those
   that compute boolean results.  This doesn't make much sense for
   abstract CPUs, but this kind of hardening may avoid undesirable
   execution paths on actual CPUs under such attacks as of power
   deprivation.  */

/* Define a pass to harden conditionals other than branches.  */

const pass_data pass_data_harden_compares = {
  GIMPLE_PASS,
  "hardcmp",
  OPTGROUP_NONE,
  TV_NONE,
  PROP_cfg | PROP_ssa, // properties_required
  0,	    // properties_provided
  0,	    // properties_destroyed
  0,	    // properties_start
  TODO_update_ssa
  | TODO_cleanup_cfg
  | TODO_verify_il, // properties_finish
};

class pass_harden_compares : public gimple_opt_pass
{
public:
  pass_harden_compares (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_harden_compares, ctxt)
  {}
  opt_pass *clone ()  final override
  {
    return new pass_harden_compares (m_ctxt);
  }
  bool gate (function *) final override
  {
    return flag_harden_compares;
  }
  unsigned int execute (function *) final override;
};

/* Define a pass to harden conditionals in branches.  This pass must
   run after the above, otherwise it will re-harden the checks
   introduced by the above.  */

const pass_data pass_data_harden_conditional_branches = {
  GIMPLE_PASS,
  "hardcbr",
  OPTGROUP_NONE,
  TV_NONE,
  PROP_cfg | PROP_ssa, // properties_required
  0,	    // properties_provided
  0,	    // properties_destroyed
  0,	    // properties_start
  TODO_update_ssa
  | TODO_cleanup_cfg
  | TODO_verify_il, // properties_finish
};

class pass_harden_conditional_branches : public gimple_opt_pass
{
public:
  pass_harden_conditional_branches (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_harden_conditional_branches, ctxt)
  {}
  opt_pass *clone () final override
  {
    return new pass_harden_conditional_branches (m_ctxt);
  }
  bool gate (function *) final override
  {
    return flag_harden_conditional_branches;
  }
  unsigned int execute (function *) final override;
};

}

/* If VAL is an SSA name, return an SSA name holding the same value,
   but without the compiler's knowing that it holds the same value, so
   that uses thereof can't be optimized the way VAL might.  Insert
   stmts that initialize it before *GSIP, with LOC.

   Otherwise, VAL must be an invariant, returned unchanged.  */

static inline tree
detach_value (location_t loc, gimple_stmt_iterator *gsip, tree val)
{
  if (TREE_CONSTANT (val) || TREE_CODE (val) != SSA_NAME)
    {
      gcc_checking_assert (is_gimple_min_invariant (val));
      return val;
    }

  /* Create a SSA "copy" of VAL.  It would be nice to have it named
     after the corresponding variable, but sharing the same decl is
     problematic when VAL is a DECL_BY_REFERENCE RESULT_DECL, and
     copying just the identifier hits -fcompare-debug failures.  */
  tree ret = make_ssa_name (TREE_TYPE (val));

  /* Some modes won't fit in general regs, so we fall back to memory
     for them.  ??? It would be ideal to try to identify an alternate,
     wider or more suitable register class, and use the corresponding
     constraint, but there's no logic to go from register class to
     constraint, even if there is a corresponding constraint, and even
     if we could enumerate constraints, we can't get to their string
     either.  So this will do for now.  */
  bool need_memory = true;
  enum machine_mode mode = TYPE_MODE (TREE_TYPE (val));
  if (mode != BLKmode)
    for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
      if (TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i)
	  && targetm.hard_regno_mode_ok (i, mode))
	{
	  need_memory = false;
	  break;
	}

  tree asminput = val;
  tree asmoutput = ret;
  const char *constraint_out = need_memory ? "=m" : "=g";
  const char *constraint_in = need_memory ? "m" : "0";

  if (need_memory)
    {
      tree temp = create_tmp_var (TREE_TYPE (val), "dtch");
      mark_addressable (temp);

      gassign *copyin = gimple_build_assign (temp, asminput);
      gimple_set_location (copyin, loc);
      gsi_insert_before (gsip, copyin, GSI_SAME_STMT);

      asminput = asmoutput = temp;
    }

  /* Output an asm statement with matching input and output.  It does
     nothing, but after it the compiler no longer knows the output
     still holds the same value as the input.  */
  vec<tree, va_gc> *inputs = NULL;
  vec<tree, va_gc> *outputs = NULL;
  vec_safe_push (outputs,
		 build_tree_list
		 (build_tree_list
		  (NULL_TREE, build_string (strlen (constraint_out),
					    constraint_out)),
		  asmoutput));
  vec_safe_push (inputs,
		 build_tree_list
		 (build_tree_list
		  (NULL_TREE, build_string (strlen (constraint_in),
					    constraint_in)),
		  asminput));
  gasm *detach = gimple_build_asm_vec ("", inputs, outputs,
				       NULL, NULL);
  gimple_set_location (detach, loc);
  gsi_insert_before (gsip, detach, GSI_SAME_STMT);

  if (need_memory)
    {
      gassign *copyout = gimple_build_assign (ret, asmoutput);
      gimple_set_location (copyout, loc);
      gsi_insert_before (gsip, copyout, GSI_SAME_STMT);
      SSA_NAME_DEF_STMT (ret) = copyout;

      gassign *clobber = gimple_build_assign (asmoutput,
					      build_clobber
					      (TREE_TYPE (asmoutput)));
      gimple_set_location (clobber, loc);
      gsi_insert_before (gsip, clobber, GSI_SAME_STMT);
    }
  else
    SSA_NAME_DEF_STMT (ret) = detach;

  return ret;
}

/* Build a cond stmt out of COP, LHS, RHS, insert it before *GSIP with
   location LOC.  *GSIP must be at the end of a basic block.  The succ
   edge out of the block becomes the true or false edge opposite to
   that in FLAGS.  Create a new block with a single trap stmt, in the
   cold partition if the function is partitioned,, and a new edge to
   it as the other edge for the cond.  */

static inline void
insert_check_and_trap (location_t loc, gimple_stmt_iterator *gsip,
		       int flags, enum tree_code cop, tree lhs, tree rhs)
{
  basic_block chk = gsi_bb (*gsip);

  gcond *cond = gimple_build_cond (cop, lhs, rhs, NULL, NULL);
  gimple_set_location (cond, loc);
  gsi_insert_before (gsip, cond, GSI_SAME_STMT);

  basic_block trp = create_empty_bb (chk);

  gimple_stmt_iterator gsit = gsi_after_labels (trp);
  gcall *trap = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
  gimple_set_location (trap, loc);
  gsi_insert_before (&gsit, trap, GSI_SAME_STMT);

  if (dump_file)
    fprintf (dump_file,
	     "Adding reversed compare to block %i, and trap to block %i\n",
	     chk->index, trp->index);

  if (BB_PARTITION (chk))
    BB_SET_PARTITION (trp, BB_COLD_PARTITION);

  int true_false_flag = flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
  gcc_assert (true_false_flag);
  int neg_true_false_flag = (~flags) & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);

  /* Remove the fallthru bit, and set the truth value for the
     preexisting edge and for the newly-created one.  In hardcbr,
     FLAGS is taken from the edge of the original cond expr that we're
     dealing with, so the reversed compare is expected to yield the
     negated result, and the same result calls for a trap.  In
     hardcmp, we're comparing the boolean results of the original and
     of the reversed compare, so we're passed FLAGS to trap on
     equality.  */
  single_succ_edge (chk)->flags &= ~EDGE_FALLTHRU;
  single_succ_edge (chk)->flags |= neg_true_false_flag;
  single_succ_edge (chk)->probability = profile_probability::always ();
  edge e = make_edge (chk, trp, true_false_flag);
  e->goto_locus = loc;
  e->probability = profile_probability::never ();

  if (dom_info_available_p (CDI_DOMINATORS))
    set_immediate_dominator (CDI_DOMINATORS, trp, chk);
  if (current_loops)
    add_bb_to_loop (trp, current_loops->tree_root);
}

/* Split edge E, and insert_check_and_trap (see above) in the
   newly-created block, using detached copies of LHS's and RHS's
   values (see detach_value above) for the COP compare.  */

static inline void
insert_edge_check_and_trap (location_t loc, edge e,
			    enum tree_code cop, tree lhs, tree rhs)
{
  int flags = e->flags;
  basic_block src = e->src;
  basic_block dest = e->dest;
  location_t eloc = e->goto_locus;

  basic_block chk = split_edge (e);
  e = NULL;

  single_pred_edge (chk)->goto_locus = loc;
  single_succ_edge (chk)->goto_locus = eloc;

  if (dump_file)
    fprintf (dump_file,
	     "Splitting edge %i->%i into block %i\n",
	     src->index, dest->index, chk->index);

  gimple_stmt_iterator gsik = gsi_after_labels (chk);

  bool same_p = (lhs == rhs);
  lhs = detach_value (loc, &gsik, lhs);
  rhs = same_p ? lhs : detach_value (loc, &gsik, rhs);

  insert_check_and_trap (loc, &gsik, flags, cop, lhs, rhs);
}

/* Harden cond stmts at the end of FUN's blocks.  */

unsigned int
pass_harden_conditional_branches::execute (function *fun)
{
  /* Record the preexisting blocks, to avoid visiting newly-created
     blocks.  */
  auto_sbitmap to_visit (last_basic_block_for_fn (fun));
  bitmap_clear (to_visit);

  basic_block bb;
  FOR_EACH_BB_FN (bb, fun)
    bitmap_set_bit (to_visit, bb->index);

  sbitmap_iterator it;
  unsigned i;
  EXECUTE_IF_SET_IN_BITMAP (to_visit, 0, i, it)
    {
      bb = BASIC_BLOCK_FOR_FN (fun, i);

      gimple_stmt_iterator gsi = gsi_last_bb (bb);

      if (gsi_end_p (gsi))
	continue;

      gcond *cond = dyn_cast <gcond *> (gsi_stmt (gsi));
      if (!cond)
	continue;

      /* Turn:

	 if (x op y) goto l1; else goto l2;

	 into:

	 if (x op y) goto l1'; else goto l2';
	 l1': if (x' cop y') goto l1'trap; else goto l1;
	 l1'trap: __builtin_trap ();
	 l2': if (x' cop y') goto l2; else goto l2'trap;
	 l2'trap: __builtin_trap ();

	 where cop is a complementary boolean operation to op; l1', l1'trap,
	 l2' and l2'trap are newly-created labels; and x' and y' hold the same
	 value as x and y, but in a way that does not enable the compiler to
	 optimize the redundant compare away.
      */

      enum tree_code op = gimple_cond_code (cond);
      tree lhs = gimple_cond_lhs (cond);
      tree rhs = gimple_cond_rhs (cond);
      location_t loc = gimple_location (cond);

      enum tree_code cop = invert_tree_comparison (op, HONOR_NANS (lhs));

      if (cop == ERROR_MARK)
	/* ??? Can we do better?  */
	continue;

      insert_edge_check_and_trap (loc, EDGE_SUCC (bb, 0), cop, lhs, rhs);
      insert_edge_check_and_trap (loc, EDGE_SUCC (bb, 1), cop, lhs, rhs);
    }

  return 0;
}

/* Instantiate a hardcbr pass.  */

gimple_opt_pass *
make_pass_harden_conditional_branches (gcc::context *ctxt)
{
  return new pass_harden_conditional_branches (ctxt);
}

/* Return the fallthru edge of a block whose other edge is an EH
   edge.  If EHP is not NULL, store the EH edge in it.  */
static inline edge
non_eh_succ_edge (basic_block bb, edge *ehp = NULL)
{
  gcc_checking_assert (EDGE_COUNT (bb->succs) == 2);

  edge ret = find_fallthru_edge (bb->succs);

  int eh_idx = EDGE_SUCC (bb, 0) == ret;
  edge eh = EDGE_SUCC (bb, eh_idx);

  gcc_checking_assert (!(ret->flags & EDGE_EH)
		       && (eh->flags & EDGE_EH));

  if (ehp)
    *ehp = eh;

  return ret;
}

/* Harden boolean-yielding compares in FUN.  */

unsigned int
pass_harden_compares::execute (function *fun)
{
  /* Record the preexisting blocks, to avoid visiting newly-created
     blocks.  */
  auto_sbitmap to_visit (last_basic_block_for_fn (fun));
  bitmap_clear (to_visit);

  basic_block bb;
  FOR_EACH_BB_FN (bb, fun)
    bitmap_set_bit (to_visit, bb->index);

  sbitmap_iterator it;
  unsigned i;
  EXECUTE_IF_SET_IN_BITMAP (to_visit, 0, i, it)
    {
      bb = BASIC_BLOCK_FOR_FN (fun, i);

      for (gimple_stmt_iterator gsi = gsi_last_bb (bb);
	   !gsi_end_p (gsi); gsi_prev (&gsi))
	{
	  gassign *asgn = dyn_cast <gassign *> (gsi_stmt (gsi));
	  if (!asgn)
	    continue;

	  /* Turn:

	     z = x op y;

	     into:

	     z = x op y;
	     z' = x' cop y';
	     if (z == z') __builtin_trap ();

	     where cop is a complementary boolean operation to op; and x'
	     and y' hold the same value as x and y, but in a way that does
	     not enable the compiler to optimize the redundant compare
	     away.
	  */

	  enum tree_code op = gimple_assign_rhs_code (asgn);

	  enum tree_code cop;

	  switch (op)
	    {
	    case EQ_EXPR:
	    case NE_EXPR:
	    case GT_EXPR:
	    case GE_EXPR:
	    case LT_EXPR:
	    case LE_EXPR:
	    case LTGT_EXPR:
	    case UNEQ_EXPR:
	    case UNGT_EXPR:
	    case UNGE_EXPR:
	    case UNLT_EXPR:
	    case UNLE_EXPR:
	    case ORDERED_EXPR:
	    case UNORDERED_EXPR:
	      cop = invert_tree_comparison (op,
					    HONOR_NANS
					    (gimple_assign_rhs1 (asgn)));

	      if (cop == ERROR_MARK)
		/* ??? Can we do better?  */
		continue;

	      break;

	      /* ??? Maybe handle these too?  */
	    case TRUTH_NOT_EXPR:
	      /* ??? The code below assumes binary ops, it would have to
		 be adjusted for TRUTH_NOT_EXPR, since it's unary.  */
	    case TRUTH_ANDIF_EXPR:
	    case TRUTH_ORIF_EXPR:
	    case TRUTH_AND_EXPR:
	    case TRUTH_OR_EXPR:
	    case TRUTH_XOR_EXPR:
	    default:
	      continue;
	    }

	  /* These are the operands for the verification.  */
	  tree lhs = gimple_assign_lhs (asgn);
	  tree op1 = gimple_assign_rhs1 (asgn);
	  tree op2 = gimple_assign_rhs2 (asgn);
	  location_t loc = gimple_location (asgn);

	  /* Vector booleans can't be used in conditional branches.  ???
	     Can we do better?  How to reduce compare and
	     reversed-compare result vectors to a single boolean?  */
	  if (VECTOR_TYPE_P (TREE_TYPE (op1)))
	    continue;

	  /* useless_type_conversion_p enables conversions from 1-bit
	     integer types to boolean to be discarded.  */
	  gcc_checking_assert (TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE
			       || (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
				   && TYPE_PRECISION (TREE_TYPE (lhs)) == 1));

	  tree rhs = copy_ssa_name (lhs);

	  gimple_stmt_iterator gsi_split = gsi;
	  /* Don't separate the original assignment from debug stmts
	     that might be associated with it, and arrange to split the
	     block after debug stmts, so as to make sure the split block
	     won't be debug stmts only.  */
	  gsi_next_nondebug (&gsi_split);

	  bool throwing_compare_p = stmt_ends_bb_p (asgn);
	  if (throwing_compare_p)
	    {
	      basic_block nbb = split_edge (non_eh_succ_edge
					    (gimple_bb (asgn)));
	      gsi_split = gsi_start_bb (nbb);

	      if (dump_file)
		fprintf (dump_file,
			 "Splitting non-EH edge from block %i into %i"
			 " after a throwing compare\n",
			 gimple_bb (asgn)->index, nbb->index);
	    }

	  bool same_p = (op1 == op2);
	  op1 = detach_value (loc, &gsi_split, op1);
	  op2 = same_p ? op1 : detach_value (loc, &gsi_split, op2);

	  gassign *asgnck = gimple_build_assign (rhs, cop, op1, op2);
	  gimple_set_location (asgnck, loc);
	  gsi_insert_before (&gsi_split, asgnck, GSI_SAME_STMT);

	  /* We wish to insert a cond_expr after the compare, so arrange
	     for it to be at the end of a block if it isn't, and for it
	     to have a single successor in case there's more than
	     one, as in PR104975.  */
	  if (!gsi_end_p (gsi_split)
	      || !single_succ_p (gsi_bb (gsi_split)))
	    {
	      if (!gsi_end_p (gsi_split))
		gsi_prev (&gsi_split);
	      else
		gsi_split = gsi_last_bb (gsi_bb (gsi_split));
	      basic_block obb = gsi_bb (gsi_split);
	      basic_block nbb = split_block (obb, gsi_stmt (gsi_split))->dest;
	      gsi_next (&gsi_split);
	      gcc_checking_assert (gsi_end_p (gsi_split));

	      single_succ_edge (bb)->goto_locus = loc;

	      if (dump_file)
		fprintf (dump_file,
			 "Splitting block %i into %i"
			 " before the conditional trap branch\n",
			 obb->index, nbb->index);
	    }

	  /* If the check assignment must end a basic block, we can't
	     insert the conditional branch in the same block, so split
	     the block again, and prepare to insert the conditional
	     branch in the new block.

	     Also assign an EH region to the compare.  Even though it's
	     unlikely that the hardening compare will throw after the
	     original compare didn't, the compiler won't even know that
	     it's the same compare operands, so add the EH edge anyway.  */
	  if (throwing_compare_p)
	    {
	      add_stmt_to_eh_lp (asgnck, lookup_stmt_eh_lp (asgn));
	      make_eh_edges (asgnck);

	      edge ckeh;
	      basic_block nbb = split_edge (non_eh_succ_edge
					    (gimple_bb (asgnck), &ckeh));
	      gsi_split = gsi_start_bb (nbb);

	      if (dump_file)
		fprintf (dump_file,
			 "Splitting non-EH edge from block %i into %i after"
			 " the newly-inserted reversed throwing compare\n",
			 gimple_bb (asgnck)->index, nbb->index);

	      if (!gimple_seq_empty_p (phi_nodes (ckeh->dest)))
		{
		  edge aseh;
		  non_eh_succ_edge (gimple_bb (asgn), &aseh);

		  gcc_checking_assert (aseh->dest == ckeh->dest);

		  for (gphi_iterator psi = gsi_start_phis (ckeh->dest);
		       !gsi_end_p (psi); gsi_next (&psi))
		    {
		      gphi *phi = psi.phi ();
		      add_phi_arg (phi, PHI_ARG_DEF_FROM_EDGE (phi, aseh), ckeh,
				   gimple_phi_arg_location_from_edge (phi, aseh));
		    }

		  if (dump_file)
		    fprintf (dump_file,
			     "Copying PHI args in EH block %i from %i to %i\n",
			     aseh->dest->index, aseh->src->index,
			     ckeh->src->index);
		}
	    }

	  gcc_checking_assert (single_succ_p (gsi_bb (gsi_split)));

	  insert_check_and_trap (loc, &gsi_split, EDGE_TRUE_VALUE,
				 EQ_EXPR, lhs, rhs);
	}
    }

  return 0;
}

/* Instantiate a hardcmp pass.  */

gimple_opt_pass *
make_pass_harden_compares (gcc::context *ctxt)
{
  return new pass_harden_compares (ctxt);
}
