/* Code coverage instrumentation for fuzzing.
   Copyright (C) 2015-2018 Free Software Foundation, Inc.
   Contributed by Dmitry Vyukov <dvyukov@google.com> and
   Wish Wu <wishwu007@gmail.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 "tree.h"
#include "gimple.h"
#include "basic-block.h"
#include "options.h"
#include "flags.h"
#include "memmodel.h"
#include "tm_p.h"
#include "stmt.h"
#include "gimple-iterator.h"
#include "gimple-builder.h"
#include "tree-cfg.h"
#include "tree-pass.h"
#include "tree-iterator.h"
#include "fold-const.h"
#include "stringpool.h"
#include "attribs.h"
#include "output.h"
#include "cgraph.h"
#include "asan.h"

namespace {

/* Instrument one comparison operation, which compares lhs and rhs.
   Call the instrumentation function with the comparison operand.
   For integral comparisons if exactly one of the comparison operands is
   constant, call __sanitizer_cov_trace_const_cmp* instead of
   __sanitizer_cov_trace_cmp*.  */

static void
instrument_comparison (gimple_stmt_iterator *gsi, tree lhs, tree rhs)
{
  tree type = TREE_TYPE (lhs);
  enum built_in_function fncode = END_BUILTINS;
  tree to_type = NULL_TREE;
  bool c = false;

  if (INTEGRAL_TYPE_P (type))
    {
      c = (is_gimple_min_invariant (lhs)
	   ^ is_gimple_min_invariant (rhs));
      switch (int_size_in_bytes (type))
	{
	case 1:
      	  fncode = c ? BUILT_IN_SANITIZER_COV_TRACE_CONST_CMP1
		     : BUILT_IN_SANITIZER_COV_TRACE_CMP1;
	  to_type = unsigned_char_type_node;
	  break;
	case 2:
      	  fncode = c ? BUILT_IN_SANITIZER_COV_TRACE_CONST_CMP2
		     : BUILT_IN_SANITIZER_COV_TRACE_CMP2;
	  to_type = uint16_type_node;
	  break;
	case 4:
      	  fncode = c ? BUILT_IN_SANITIZER_COV_TRACE_CONST_CMP4
		     : BUILT_IN_SANITIZER_COV_TRACE_CMP4;
	  to_type = uint32_type_node;
	  break;
	default:
      	  fncode = c ? BUILT_IN_SANITIZER_COV_TRACE_CONST_CMP8
		     : BUILT_IN_SANITIZER_COV_TRACE_CMP8;
	  to_type = uint64_type_node;
	  break;
	}
    }
  else if (SCALAR_FLOAT_TYPE_P (type))
    {
      if (TYPE_MODE (type) == TYPE_MODE (float_type_node))
	{
      	  fncode = BUILT_IN_SANITIZER_COV_TRACE_CMPF;
	  to_type = float_type_node;
	}
      else if (TYPE_MODE (type) == TYPE_MODE (double_type_node))
	{
      	  fncode = BUILT_IN_SANITIZER_COV_TRACE_CMPD;
	  to_type = double_type_node;
	}
    }

  if (to_type != NULL_TREE)
    {
      gimple_seq seq = NULL;

      if (!useless_type_conversion_p (to_type, type))
	{
	  if (TREE_CODE (lhs) == INTEGER_CST)
	    lhs = fold_convert (to_type, lhs);
	  else
	    {
	      gimple_seq_add_stmt (&seq, build_type_cast (to_type, lhs));
	      lhs = gimple_assign_lhs (gimple_seq_last_stmt (seq));
	    }

	  if (TREE_CODE (rhs) == INTEGER_CST)
	    rhs = fold_convert (to_type, rhs);
	  else
	    {
	      gimple_seq_add_stmt (&seq, build_type_cast (to_type, rhs));
	      rhs = gimple_assign_lhs (gimple_seq_last_stmt (seq));
	    }
	}

      if (c && !is_gimple_min_invariant (lhs))
	std::swap (lhs, rhs);

      tree fndecl = builtin_decl_implicit (fncode);
      gimple *gcall = gimple_build_call (fndecl, 2, lhs, rhs);
      gimple_seq_add_stmt (&seq, gcall);

      gimple_seq_set_location (seq, gimple_location (gsi_stmt (*gsi)));
      gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT);
    }
}

/* Instrument switch statement.  Call __sanitizer_cov_trace_switch with
   the value of the index and array that contains number of case values,
   the bitsize of the index and the case values converted to uint64_t.  */

static void
instrument_switch (gimple_stmt_iterator *gsi, gimple *stmt, function *fun)
{
  gswitch *switch_stmt = as_a<gswitch *> (stmt);
  tree index = gimple_switch_index (switch_stmt);
  HOST_WIDE_INT size_in_bytes = int_size_in_bytes (TREE_TYPE (index));
  if (size_in_bytes == -1 || size_in_bytes > 8)
    return;

  location_t loc = gimple_location (stmt);
  unsigned i, n = gimple_switch_num_labels (switch_stmt), num = 0;
  for (i = 1; i < n; ++i)
    {
      tree label = gimple_switch_label (switch_stmt, i);

      tree low_case = CASE_LOW (label);
      if (low_case != NULL_TREE)
	num++;

      tree high_case = CASE_HIGH (label);
      if (high_case != NULL_TREE)
	num++;
    }

  tree case_array_type
   = build_array_type (build_type_variant (uint64_type_node, 1, 0),
		       build_index_type (size_int (num + 2 - 1)));

  char name[64];
  static size_t case_array_count = 0;
  ASM_GENERATE_INTERNAL_LABEL (name, "LCASEARRAY", case_array_count++);
  tree case_array_var = build_decl (loc, VAR_DECL, get_identifier (name),
				    case_array_type);
  TREE_STATIC (case_array_var) = 1;
  TREE_PUBLIC (case_array_var) = 0;
  TREE_CONSTANT (case_array_var) = 1;
  TREE_READONLY (case_array_var) = 1;
  DECL_EXTERNAL (case_array_var) = 0;
  DECL_ARTIFICIAL (case_array_var) = 1;
  DECL_IGNORED_P (case_array_var) = 1;

  vec <constructor_elt, va_gc> *v = NULL;
  vec_alloc (v, num + 2);
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
			  build_int_cst (uint64_type_node, num));
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
			  build_int_cst (uint64_type_node,
					 size_in_bytes * BITS_PER_UNIT));
  for (i = 1; i < n; ++i)
    {
      tree label = gimple_switch_label (switch_stmt, i);

      tree low_case = CASE_LOW (label);
      if (low_case != NULL_TREE)
	CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
				fold_convert (uint64_type_node, low_case));

      tree high_case = CASE_HIGH (label);
      if (high_case != NULL_TREE)
	CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
				fold_convert (uint64_type_node, high_case));
    }
  tree ctor = build_constructor (case_array_type, v);
  TREE_STATIC (ctor) = 1;
  TREE_PUBLIC (ctor) = 0;
  TREE_CONSTANT (ctor) = 1;
  TREE_READONLY (ctor) = 1;
  DECL_INITIAL (case_array_var) = ctor;
  varpool_node::finalize_decl (case_array_var);
  add_local_decl (fun, case_array_var);

  gimple_seq seq = NULL;

  if (!useless_type_conversion_p (uint64_type_node, TREE_TYPE (index)))
    {
      if (TREE_CODE (index) == INTEGER_CST)
	index = fold_convert (uint64_type_node, index);
      else
	{
	  gimple_seq_add_stmt (&seq, build_type_cast (uint64_type_node, index));
	  index = gimple_assign_lhs (gimple_seq_last_stmt (seq));
	}
    }

  tree fndecl = builtin_decl_implicit (BUILT_IN_SANITIZER_COV_TRACE_SWITCH);
  gimple *gcall = gimple_build_call (fndecl, 2, index,
				     build_fold_addr_expr (case_array_var));
  gimple_seq_add_stmt (&seq, gcall);

  gimple_seq_set_location (seq, loc);
  gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT);
}

unsigned
sancov_pass (function *fun)
{
  initialize_sanitizer_builtins ();

  /* Insert callback into beginning of every BB. */
  if (flag_sanitize_coverage & SANITIZE_COV_TRACE_PC)
    {
      basic_block bb;
      tree fndecl = builtin_decl_implicit (BUILT_IN_SANITIZER_COV_TRACE_PC);
      FOR_EACH_BB_FN (bb, fun)
	{
	  gimple_stmt_iterator gsi = gsi_start_nondebug_after_labels_bb (bb);
	  if (gsi_end_p (gsi))
	    continue;
	  gimple *stmt = gsi_stmt (gsi);
	  gimple *gcall = gimple_build_call (fndecl, 0);
	  gimple_set_location (gcall, gimple_location (stmt));
	  gsi_insert_before (&gsi, gcall, GSI_SAME_STMT);
	}
    }

  /* Insert callback into every comparison related operation.  */
  if (flag_sanitize_coverage & SANITIZE_COV_TRACE_CMP)
    {
      basic_block bb;
      FOR_EACH_BB_FN (bb, fun)
	{
	  gimple_stmt_iterator gsi;
	  for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
	    {
	      gimple *stmt = gsi_stmt (gsi);
	      enum tree_code rhs_code;
	      switch (gimple_code (stmt))
		{
		case GIMPLE_ASSIGN:
		  rhs_code = gimple_assign_rhs_code (stmt);
		  if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
		    instrument_comparison (&gsi,
					   gimple_assign_rhs1 (stmt),
					   gimple_assign_rhs2 (stmt));
		  else if (rhs_code == COND_EXPR
			   && COMPARISON_CLASS_P (gimple_assign_rhs1 (stmt)))
		    {
		      tree cond = gimple_assign_rhs1 (stmt);
		      instrument_comparison (&gsi, TREE_OPERAND (cond, 0),
					     TREE_OPERAND (cond, 1));
		    }
		  break;
		case GIMPLE_COND:
		  instrument_comparison (&gsi,
					 gimple_cond_lhs (stmt),
					 gimple_cond_rhs (stmt));
		  break;

		case GIMPLE_SWITCH:
		  instrument_switch (&gsi, stmt, fun);
		  break;

		default:
		  break;
		}
	    }
	}
    }
  return 0;
}

template <bool O0> class pass_sancov : public gimple_opt_pass
{
public:
  pass_sancov (gcc::context *ctxt) : gimple_opt_pass (data, ctxt) {}

  static const pass_data data;
  opt_pass *
  clone ()
  {
    return new pass_sancov<O0> (m_ctxt);
  }
  virtual bool
  gate (function *)
  {
    return flag_sanitize_coverage && (!O0 || !optimize);
  }
  virtual unsigned int
  execute (function *fun)
  {
    return sancov_pass (fun);
  }
}; // class pass_sancov

template <bool O0>
const pass_data pass_sancov<O0>::data = {
  GIMPLE_PASS,		       /* type */
  O0 ? "sancov_O0" : "sancov", /* name */
  OPTGROUP_NONE,	       /* optinfo_flags */
  TV_NONE,		       /* tv_id */
  (PROP_cfg),		       /* properties_required */
  0,			       /* properties_provided */
  0,			       /* properties_destroyed */
  0,			       /* todo_flags_start */
  TODO_update_ssa,	     /* todo_flags_finish */
};

} // anon namespace

gimple_opt_pass *
make_pass_sancov (gcc::context *ctxt)
{
  return new pass_sancov<false> (ctxt);
}

gimple_opt_pass *
make_pass_sancov_O0 (gcc::context *ctxt)
{
  return new pass_sancov<true> (ctxt);
}
