aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/sancov.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/sancov.c')
-rw-r--r--gcc-4.9/gcc/sancov.c146
1 files changed, 146 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/sancov.c b/gcc-4.9/gcc/sancov.c
new file mode 100644
index 000000000..8f2f3fde9
--- /dev/null
+++ b/gcc-4.9/gcc/sancov.c
@@ -0,0 +1,146 @@
+/* Code coverage instrumentation for fuzzing.
+ Copyright (C) 2015 Free Software Foundation, Inc.
+ Contributed by Dmitry Vyukov <dvyukov@google.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 "tree.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-expr.h"
+#include "is-a.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "tree-pass.h"
+#include "asan.h"
+
+unsigned
+sancov_pass ()
+{
+ initialize_sanitizer_builtins ();
+
+ /* Insert callback into beginning of every BB. */
+ tree fndecl = builtin_decl_implicit (BUILT_IN_SANITIZER_COV_TRACE_PC);
+ basic_block bb;
+ FOR_EACH_BB_FN (bb, cfun)
+ {
+ gimple_stmt_iterator gsi = gsi_after_labels (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);
+ }
+ return 0;
+}
+/* The pass's gate. */
+
+static bool
+sancov_gate (void)
+{
+ return flag_sanitize_coverage;
+}
+
+/* The pass descriptor. */
+
+namespace {
+
+const pass_data pass_data_sancov =
+{
+ GIMPLE_PASS, /* type */
+ "sancov", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ ( PROP_cfg ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_update_ssa ), /* todo_flags_finish */
+};
+
+class pass_sancov : public gimple_opt_pass
+{
+public:
+ pass_sancov (gcc::context *ctxt)
+ : gimple_opt_pass (pass_data_sancov, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_sancov (m_ctxt); }
+ bool gate () { return sancov_gate (); }
+ unsigned int execute () { return sancov_pass (); }
+
+}; // class pass_sancov
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_sancov (gcc::context *ctxt)
+{
+ return new pass_sancov (ctxt);
+}
+
+static bool
+sancov_gate_O0 (void)
+{
+ return flag_sanitize_coverage && !optimize;
+}
+
+namespace {
+
+const pass_data pass_data_sancov_O0 =
+{
+ GIMPLE_PASS, /* type */
+ "sancov0", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ ( PROP_cfg ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_update_ssa ), /* todo_flags_finish */
+};
+
+class pass_sancov_O0 : public gimple_opt_pass
+{
+public:
+ pass_sancov_O0 (gcc::context *ctxt)
+ : gimple_opt_pass (pass_data_sancov_O0, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return sancov_gate_O0 (); }
+ unsigned int execute () { return sancov_pass (); }
+
+}; // class pass_sancov_O0
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_sancov_O0 (gcc::context *ctxt)
+{
+ return new pass_sancov_O0 (ctxt);
+}