/* 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 "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 () { return new pass_harden_compares (m_ctxt); }
  virtual bool gate (function *) {
    return flag_harden_compares;
  }
  virtual unsigned int execute (function *);
};

/* 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 () { return new pass_harden_conditional_branches (m_ctxt); }
  virtual bool gate (function *) {
    return flag_harden_conditional_branches;
  }
  virtual unsigned int execute (function *);
};

}

/* 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;
  edge e = make_edge (chk, trp, true_false_flag);
  e->goto_locus = loc;

  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)
{
  basic_block bb;
  FOR_EACH_BB_REVERSE_FN (bb, fun)
    {
      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)
{
  basic_block bb;
  /* Go backwards over BBs and stmts, so that, even if we split the
     block multiple times to insert a cond_expr after each compare we
     find, we remain in the same block, visiting every preexisting
     stmt exactly once, and not visiting newly-added blocks or
     stmts.  */
  FOR_EACH_BB_REVERSE_FN (bb, fun)
    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);
}
