mirror of
https://gcc.gnu.org/git/gcc.git
synced 2025-01-05 18:43:52 +08:00
Add fuzzing coverage support
* 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. From-SVN: r231296
This commit is contained in:
parent
f58101cf28
commit
95e7bbb8d6
@ -1,3 +1,15 @@
|
||||
2015-12-04 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-04 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
PR middle-end/65958
|
||||
|
@ -1427,6 +1427,7 @@ OBJS = \
|
||||
tsan.o \
|
||||
ubsan.o \
|
||||
sanopt.o \
|
||||
sancov.o \
|
||||
tree-call-cdce.o \
|
||||
tree-cfg.o \
|
||||
tree-cfgcleanup.o \
|
||||
@ -2400,6 +2401,7 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
|
||||
$(srcdir)/ubsan.c \
|
||||
$(srcdir)/tsan.c \
|
||||
$(srcdir)/sanopt.c \
|
||||
$(srcdir)/sancov.c \
|
||||
$(srcdir)/ipa-devirt.c \
|
||||
$(srcdir)/internal-fn.h \
|
||||
@all_gtfiles@
|
||||
|
@ -210,7 +210,8 @@ along with GCC; see the file COPYING3. If not see
|
||||
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) \
|
||||
|
@ -225,6 +225,11 @@ unsigned int flag_sanitize
|
||||
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
|
||||
|
@ -6136,6 +6136,11 @@ a @code{libubsan} library routine. The advantage of this is that the
|
||||
@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
|
||||
|
@ -237,6 +237,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
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 @@ along with GCC; see the file COPYING3. If not see
|
||||
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 @@ along with GCC; see the file COPYING3. If not see
|
||||
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);
|
||||
|
108
gcc/sancov.c
Normal file
108
gcc/sancov.c
Normal file
@ -0,0 +1,108 @@
|
||||
/* 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)
|
||||
{
|
||||
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, fun)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
@ -510,3 +510,8 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_DYNAMIC_TYPE_CACHE_MISS_ABORT,
|
||||
"__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)
|
||||
|
18
gcc/testsuite/gcc.dg/sancov/asan.c
Normal file
18
gcc/testsuite/gcc.dg/sancov/asan.c
Normal file
@ -0,0 +1,18 @@
|
||||
/* 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 -fdump-tree-optimized" } */
|
||||
|
||||
void foo(volatile int *a, int *b)
|
||||
{
|
||||
*a = 1;
|
||||
if (*b)
|
||||
*a = 2;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "__builtin___sanitizer_cov_trace_pc \\(\\)" 4 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4 \\(" 1 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store4 \\(" 1 "optimized" } } */
|
9
gcc/testsuite/gcc.dg/sancov/basic0.c
Normal file
9
gcc/testsuite/gcc.dg/sancov/basic0.c
Normal file
@ -0,0 +1,9 @@
|
||||
/* Basic test on number of inserted callbacks. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fsanitize-coverage=trace-pc -fdump-tree-optimized" } */
|
||||
|
||||
void foo(void)
|
||||
{
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "__builtin___sanitizer_cov_trace_pc \\(\\)" 1 "optimized" } } */
|
12
gcc/testsuite/gcc.dg/sancov/basic1.c
Normal file
12
gcc/testsuite/gcc.dg/sancov/basic1.c
Normal file
@ -0,0 +1,12 @@
|
||||
/* Basic test on number of inserted callbacks. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fsanitize-coverage=trace-pc -fdump-tree-optimized" } */
|
||||
|
||||
void foo (int *a, int *b, int *c)
|
||||
{
|
||||
*a = 1;
|
||||
if (*b)
|
||||
*c = 2;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "__builtin___sanitizer_cov_trace_pc \\(\\)" 3 "optimized" } } */
|
14
gcc/testsuite/gcc.dg/sancov/basic2.c
Normal file
14
gcc/testsuite/gcc.dg/sancov/basic2.c
Normal file
@ -0,0 +1,14 @@
|
||||
/* Basic test on number of inserted callbacks. */
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-fsanitize-coverage=trace-pc -fdump-tree-optimized" } */
|
||||
|
||||
void foo(int *a, int *b, int *c, int *d)
|
||||
{
|
||||
*a = 1;
|
||||
if (*b)
|
||||
*c = 2;
|
||||
else
|
||||
*d = 3;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "__builtin___sanitizer_cov_trace_pc \\(\\)" 4 "optimized" } } */
|
37
gcc/testsuite/gcc.dg/sancov/sancov.exp
Normal file
37
gcc/testsuite/gcc.dg/sancov/sancov.exp
Normal file
@ -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
|
@ -351,6 +351,8 @@ extern gimple_opt_pass *make_pass_asan (gcc::context *ctxt);
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user