diff mbox

Add fuzzing coverage support

Message ID CACT4Y+bfjShs3h2_SrbFE8Y=aV3Ocw8hfpScrhdoWLR1Ww=oLw@mail.gmail.com
State New
Headers show

Commit Message

Dmitry Vyukov Dec. 3, 2015, 7:17 p.m. UTC
On Thu, Dec 3, 2015 at 7:34 PM, Dmitry Vyukov <dvyukov@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.

Comments

Jakub Jelinek Dec. 4, 2015, 1:41 p.m. UTC | #1
Hi!

While this has been posted after stage1 closed and I'm not really happy
that it missed the deadline, I'm willing to grant an exception, the patch
is small enough that it is ok at this point of stage3.  That said, next time
please try to submit new features in time.

Are there any plans for GCC 7 for the other -fsanitize-coverage= options,
or are those just LLVM alternatives to GCC's gcov/-fprofile-generate etc.?

On Thu, Dec 03, 2015 at 08:17:06PM +0100, Dmitry Vyukov wrote:
> +unsigned sancov_pass (function *fun)

Formatting:
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 ();
> +    }

You can call this unconditionally, it will return as the first thing
if it is already initialized, no need for another guard.

> +
> +  /* 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);

I (personally) prefer no ( at the end of line unless really needed.
In this case you can just do:
      tree fndecl = builtin_decl_implicit (BUILT_IN_SANITIZER_COV_TRACE_PC);
      gimple *g = gimple_build_call (fndecl, 0);
which is same number of lines, but looks nicer.
Also, please move also the gsi, stmt and f (better g or gcall)
declarations to the first assignment to them, they aren't used outside of
the loop.

> --- 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 } } */

I don't like these, we have lots of targets, and different targets have
different instructions for making calls, different whitespace in between
the insn name and called function, sometimes some extra decoration on the fn
name, (say sometimes an extra _ prefix), etc.  IMHO much better to add
-fdump-tree-optimized and scan-tree-dump-times instead for the calls in the
optimized dump.  Affects all tests.

Please repost a patch with these changes fixed, it will be hopefully ackable
then.

	Jakub
Yury Gribov Dec. 4, 2015, 1:45 p.m. UTC | #2
On 12/04/2015 04:41 PM, Jakub Jelinek wrote:
> Hi!
>
> While this has been posted after stage1 closed and I'm not really happy
> that it missed the deadline, I'm willing to grant an exception, the patch
> is small enough that it is ok at this point of stage3.  That said, next time
> please try to submit new features in time.
>
> Are there any plans for GCC 7 for the other -fsanitize-coverage= options,
> or are those just LLVM alternatives to GCC's gcov/-fprofile-generate etc.?
>
> On Thu, Dec 03, 2015 at 08:17:06PM +0100, Dmitry Vyukov wrote:
>> +unsigned sancov_pass (function *fun)
>
> Formatting:
> 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 ();
>> +    }
>
> You can call this unconditionally, it will return as the first thing
> if it is already initialized, no need for another guard.
>
>> +
>> +  /* 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);
>
> I (personally) prefer no ( at the end of line unless really needed.
> In this case you can just do:
>        tree fndecl = builtin_decl_implicit (BUILT_IN_SANITIZER_COV_TRACE_PC);
>        gimple *g = gimple_build_call (fndecl, 0);
> which is same number of lines, but looks nicer.
> Also, please move also the gsi, stmt and f (better g or gcall)
> declarations to the first assignment to them, they aren't used outside of
> the loop.

Also FYI clang-format config has been recently added to contrib/ 
(https://gcc.gnu.org/ml/gcc-patches/2015-11/msg02214.html).

>
>> --- 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 } } */
>
> I don't like these, we have lots of targets, and different targets have
> different instructions for making calls, different whitespace in between
> the insn name and called function, sometimes some extra decoration on the fn
> name, (say sometimes an extra _ prefix), etc.  IMHO much better to add
> -fdump-tree-optimized and scan-tree-dump-times instead for the calls in the
> optimized dump.  Affects all tests.
>
> Please repost a patch with these changes fixed, it will be hopefully ackable
> then.
>
> 	Jakub
>
>
Dmitry Vyukov Dec. 4, 2015, 5:33 p.m. UTC | #3
On Fri, Dec 4, 2015 at 2:45 PM, Yury Gribov <y.gribov@samsung.com> wrote:
> On 12/04/2015 04:41 PM, Jakub Jelinek wrote:
>>
>> Hi!
>>
>> While this has been posted after stage1 closed and I'm not really happy
>> that it missed the deadline, I'm willing to grant an exception, the patch
>> is small enough that it is ok at this point of stage3.  That said, next
>> time
>> please try to submit new features in time.
>>
>> Are there any plans for GCC 7 for the other -fsanitize-coverage= options,
>> or are those just LLVM alternatives to GCC's gcov/-fprofile-generate etc.?
>>
>> On Thu, Dec 03, 2015 at 08:17:06PM +0100, Dmitry Vyukov wrote:
>>>
>>> +unsigned sancov_pass (function *fun)
>>
>>
>> Formatting:
>> 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 ();
>>> +    }
>>
>>
>> You can call this unconditionally, it will return as the first thing
>> if it is already initialized, no need for another guard.
>>
>>> +
>>> +  /* 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);
>>
>>
>> I (personally) prefer no ( at the end of line unless really needed.
>> In this case you can just do:
>>        tree fndecl = builtin_decl_implicit
>> (BUILT_IN_SANITIZER_COV_TRACE_PC);
>>        gimple *g = gimple_build_call (fndecl, 0);
>> which is same number of lines, but looks nicer.
>> Also, please move also the gsi, stmt and f (better g or gcall)
>> declarations to the first assignment to them, they aren't used outside of
>> the loop.
>
>
> Also FYI clang-format config has been recently added to contrib/
> (https://gcc.gnu.org/ml/gcc-patches/2015-11/msg02214.html).

Rock-n-roll!

Applied to sancov.c
diff mbox

Patch

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 231234)
+++ ChangeLog	(working copy)
@@ -1,3 +1,15 @@ 
+2015-12-03  Dmitry Vyukov  <dvyukov@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.menezes@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  <segher@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 <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 "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);