On Thu, Dec 3, 2015 at 7:34 PM, Dmitry Vyukov <dvyu...@google.com> wrote: > I've attached updated patch (also reuploaded > https://codereview.appspot.com/280140043). > Fixed ChangeLog. > Added invoke.texi. > Fixed style issues. > > The function is defined only in kernel at the moment. Here is my patch: > https://github.com/dvyukov/linux/commit/f86eda0c895c47ea02ee37e981aeade7b03014d7 > It is not mailed yet, for kernel asan people requested submit to gcc > first, then to kernel. > > It will also be supported by libsanitizer later (Kostya?). But it is > not yet there. > > Regarding plugins, we did tsan first as gcc plugin. It was difficult > to support, difficult to use, difficult to distribute. I maintain this > patch for a month, two people complained that it does not build > (because they synched to slightly different revisions).
Added missing: stmt = gsi_stmt (gsi); Now actually run tests and compiled kernel with it.
Index: ChangeLog =================================================================== --- ChangeLog (revision 231234) +++ ChangeLog (working copy) @@ -1,3 +1,15 @@ +2015-12-03 Dmitry Vyukov <dvyu...@google.com> + + * sancov.c: New file. + * Makefile.in (OBJS): Add sancov.o. + * invoke.texi (-fsanitize-coverage=trace-pc): Describe. + * passes.def (sancov_pass): Add. + * tree-pass.h (sancov_pass): Add. + * common.opt (-fsanitize-coverage=trace-pc): Add. + * sanitizer.def (BUILT_IN_SANITIZER_COV_TRACE_PC): Add. + * builtins.def (DEF_SANITIZER_BUILTIN): Enable for + flag_sanitize_coverage. + 2015-12-03 Evandro Menezes <e.mene...@samsung.com> * config/aarch64/aarch64-cores.def: Use the Exynos M1 cost model. @@ -360,7 +372,6 @@ * tree-ssa-structalias.c (find_func_aliases_for_builtin_call) (find_func_clobbers, ipa_pta_execute): Handle BUILT_IN_GOACC_PARALLEL. ->>>>>>> .r231221 2015-12-02 Segher Boessenkool <seg...@kernel.crashing.org> * config/rs6000/rs6000.md (cstore_si_as_di): New expander. Index: Makefile.in =================================================================== --- Makefile.in (revision 231234) +++ Makefile.in (working copy) @@ -1427,6 +1427,7 @@ tsan.o \ ubsan.o \ sanopt.o \ + sancov.o \ tree-call-cdce.o \ tree-cfg.o \ tree-cfgcleanup.o \ @@ -2400,6 +2401,7 @@ $(srcdir)/ubsan.c \ $(srcdir)/tsan.c \ $(srcdir)/sanopt.c \ + $(srcdir)/sancov.c \ $(srcdir)/ipa-devirt.c \ $(srcdir)/internal-fn.h \ @all_gtfiles@ Index: builtins.def =================================================================== --- builtins.def (revision 231234) +++ builtins.def (working copy) @@ -210,7 +210,8 @@ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ true, true, true, ATTRS, true, \ (flag_sanitize & (SANITIZE_ADDRESS | SANITIZE_THREAD \ - | SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT))) + | SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT) \ + || flag_sanitize_coverage)) #undef DEF_CILKPLUS_BUILTIN #define DEF_CILKPLUS_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ Index: common.opt =================================================================== --- common.opt (revision 231234) +++ common.opt (working copy) @@ -225,6 +225,11 @@ Variable unsigned int flag_sanitize_recover = SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT | SANITIZE_KERNEL_ADDRESS +fsanitize-coverage=trace-pc +Common Report Var(flag_sanitize_coverage) +Enable coverage-guided fuzzing code instrumentation. +Inserts call to __sanitizer_cov_trace_pc into every basic block. + ; Flag whether a prefix has been added to dump_base_name Variable bool dump_base_name_prefixed = false Index: doc/invoke.texi =================================================================== --- doc/invoke.texi (revision 231234) +++ doc/invoke.texi (working copy) @@ -6135,6 +6135,11 @@ @code{libubsan} library is not needed and is not linked in, so this is usable even in freestanding environments. +@item -fsanitize-coverage=trace-pc +@opindex fsanitize-coverage=trace-pc +Enable coverage-guided fuzzing code instrumentation. +Inserts call to __sanitizer_cov_trace_pc into every basic block. + @item -fcheck-pointer-bounds @opindex fcheck-pointer-bounds @opindex fno-check-pointer-bounds Index: passes.def =================================================================== --- passes.def (revision 231234) +++ passes.def (working copy) @@ -237,6 +237,7 @@ NEXT_PASS (pass_split_crit_edges); NEXT_PASS (pass_pre); NEXT_PASS (pass_sink_code); + NEXT_PASS (pass_sancov); NEXT_PASS (pass_asan); NEXT_PASS (pass_tsan); /* Pass group that runs when 1) enabled, 2) there are loops @@ -346,6 +347,7 @@ to forward object-size and builtin folding results properly. */ NEXT_PASS (pass_copy_prop); NEXT_PASS (pass_dce); + NEXT_PASS (pass_sancov); NEXT_PASS (pass_asan); NEXT_PASS (pass_tsan); /* ??? We do want some kind of loop invariant motion, but we possibly @@ -369,6 +371,7 @@ NEXT_PASS (pass_lower_vaarg); NEXT_PASS (pass_lower_vector); NEXT_PASS (pass_lower_complex_O0); + NEXT_PASS (pass_sancov_O0); NEXT_PASS (pass_asan_O0); NEXT_PASS (pass_tsan_O0); NEXT_PASS (pass_sanopt); Index: sancov.c =================================================================== --- sancov.c (revision 0) +++ sancov.c (working copy) @@ -0,0 +1,110 @@ +/* Code coverage instrumentation for fuzzing. + Copyright (C) 2015 Free Software Foundation, Inc. + Contributed by Dmitry Vyukov <dvyu...@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 "backend.h" +#include "tree.h" +#include "gimple.h" +#include "basic-block.h" +#include "options.h" +#include "flags.h" +#include "stmt.h" +#include "gimple-iterator.h" +#include "tree-cfg.h" +#include "tree-pass.h" +#include "tree-iterator.h" +#include "asan.h" + +namespace { + +unsigned sancov_pass (function *fun) +{ + basic_block bb; + gimple_stmt_iterator gsi; + gimple *stmt, *f; + static bool inited; + + if (!inited) + { + inited = true; + initialize_sanitizer_builtins (); + } + + /* Insert callback into beginning of every BB. */ + FOR_EACH_BB_FN (bb, fun) + { + gsi = gsi_after_labels (bb); + if (gsi_end_p (gsi)) + continue; + stmt = gsi_stmt (gsi); + f = gimple_build_call (builtin_decl_implicit ( + BUILT_IN_SANITIZER_COV_TRACE_PC), 0); + gimple_set_location (f, gimple_location (stmt)); + gsi_insert_before (&gsi, f, GSI_SAME_STMT); + } + 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); +} Index: sanitizer.def =================================================================== --- sanitizer.def (revision 231234) +++ sanitizer.def (working copy) @@ -510,3 +510,8 @@ "__ubsan_handle_dynamic_type_cache_miss_abort", BT_FN_VOID_PTR_PTR_PTR, ATTR_COLD_NOTHROW_LEAF_LIST) + +/* Sanitizer coverage */ +DEF_SANITIZER_BUILTIN(BUILT_IN_SANITIZER_COV_TRACE_PC, + "__sanitizer_cov_trace_pc", + BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST) Index: testsuite/gcc.dg/sancov/asan.c =================================================================== --- testsuite/gcc.dg/sancov/asan.c (revision 0) +++ testsuite/gcc.dg/sancov/asan.c (working copy) @@ -0,0 +1,21 @@ +/* Test coverage/asan interaction: + - coverage instruments __asan_init ctor (thus 4 covarage callbacks) + - coverage does not instrument asan-emitted basic blocks + - asan considers coverage callback as "nonfreeing" (thus 1 asan store + callback. */ +/* { dg-do compile } */ +/* { dg-options "-fsanitize-coverage=trace-pc -fsanitize=address" } */ + +void notailcall (); + +void foo(volatile int *a, int *b) +{ + *a = 1; + if (*b) + *a = 2; + notailcall (); +} + +/* { dg-final { scan-assembler-times "call __sanitizer_cov_trace_pc" 4 } } */ +/* { dg-final { scan-assembler-times "call __asan_report_load4" 1 } } */ +/* { dg-final { scan-assembler-times "call __asan_report_store4" 1 } } */ Index: testsuite/gcc.dg/sancov/basic0.c =================================================================== --- testsuite/gcc.dg/sancov/basic0.c (revision 0) +++ testsuite/gcc.dg/sancov/basic0.c (working copy) @@ -0,0 +1,12 @@ +/* Basic test on number of inserted callbacks. */ +/* { dg-do compile } */ +/* { dg-options "-fsanitize-coverage=trace-pc" } */ + +void notailcall (); + +void foo(void) +{ + notailcall (); +} + +/* { dg-final { scan-assembler-times "call __sanitizer_cov_trace_pc" 1 } } */ Index: testsuite/gcc.dg/sancov/basic1.c =================================================================== --- testsuite/gcc.dg/sancov/basic1.c (revision 0) +++ testsuite/gcc.dg/sancov/basic1.c (working copy) @@ -0,0 +1,15 @@ +/* Basic test on number of inserted callbacks. */ +/* { dg-do compile } */ +/* { dg-options "-fsanitize-coverage=trace-pc" } */ + +void notailcall (); + +void foo (int *a, int *b, int *c) +{ + *a = 1; + if (*b) + *c = 2; + notailcall (); +} + +/* { dg-final { scan-assembler-times "call __sanitizer_cov_trace_pc" 3 } } */ Index: testsuite/gcc.dg/sancov/basic2.c =================================================================== --- testsuite/gcc.dg/sancov/basic2.c (revision 0) +++ testsuite/gcc.dg/sancov/basic2.c (working copy) @@ -0,0 +1,17 @@ +/* Basic test on number of inserted callbacks. */ +/* { dg-do compile } */ +/* { dg-options "-fsanitize-coverage=trace-pc" } */ + +void notailcall (); + +void foo(int *a, int *b, int *c, int *d) +{ + *a = 1; + if (*b) + *c = 2; + else + *d = 3; + notailcall (); +} + +/* { dg-final { scan-assembler-times "call __sanitizer_cov_trace_pc" 4 } } */ Index: testsuite/gcc.dg/sancov/sancov.exp =================================================================== --- testsuite/gcc.dg/sancov/sancov.exp (revision 0) +++ testsuite/gcc.dg/sancov/sancov.exp (working copy) @@ -0,0 +1,37 @@ +# Copyright (C) 2015 Free Software Foundation, Inc. +# +# 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/>. + +load_lib gcc-dg.exp +load_lib torture-options.exp + +dg-init +torture-init +set-torture-options [list \ + { -O0 } \ + { -O1 } \ + { -O2 } \ + { -O3 } \ + { -O0 -g } \ + { -O1 -g } \ + { -O2 -g } \ + { -O3 -g } ] + +gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c]] "" "" + +torture-finish +dg-finish Index: tree-pass.h =================================================================== --- tree-pass.h (revision 231234) +++ tree-pass.h (working copy) @@ -351,6 +351,8 @@ extern gimple_opt_pass *make_pass_asan_O0 (gcc::context *ctxt); extern gimple_opt_pass *make_pass_tsan (gcc::context *ctxt); extern gimple_opt_pass *make_pass_tsan_O0 (gcc::context *ctxt); +extern gimple_opt_pass *make_pass_sancov (gcc::context *ctxt); +extern gimple_opt_pass *make_pass_sancov_O0 (gcc::context *ctxt); extern gimple_opt_pass *make_pass_lower_cf (gcc::context *ctxt); extern gimple_opt_pass *make_pass_refactor_eh (gcc::context *ctxt); extern gimple_opt_pass *make_pass_lower_eh (gcc::context *ctxt);