-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The sancov gcc plugin inserts a __sanitizer_cov_trace_pc() call at the start of basic blocks. This plugin is a helper plugin for the kcov feature. It supports all gcc versions with plugin support (from gcc-4.5 on). It is based on the gcc commit "Add fuzzing coverage support" by Dmitry Vyukov (https://gcc.gnu.org/viewcvs/gcc?limit_changes=0&view=revision&revision=231296). Signed-off-by: Emese Revfy <re.emese@gmail.com> Acked-by: Kees Cook <keescook@chromium.org> Signed-off-by: Michal Marek <mmarek@suse.com>
- Loading branch information
1 parent
0dae776
commit 543c37c
Showing
7 changed files
with
184 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
/* | ||
* Copyright 2011-2016 by Emese Revfy <re.emese@gmail.com> | ||
* Licensed under the GPL v2, or (at your option) v3 | ||
* | ||
* Homepage: | ||
* https://github.com/ephox-gcc-plugins/sancov | ||
* | ||
* This plugin inserts a __sanitizer_cov_trace_pc() call at the start of basic blocks. | ||
* It supports all gcc versions with plugin support (from gcc-4.5 on). | ||
* It is based on the commit "Add fuzzing coverage support" by Dmitry Vyukov <dvyukov@google.com>. | ||
* | ||
* You can read about it more here: | ||
* https://gcc.gnu.org/viewcvs/gcc?limit_changes=0&view=revision&revision=231296 | ||
* http://lwn.net/Articles/674854/ | ||
* https://github.com/google/syzkaller | ||
* https://lwn.net/Articles/677764/ | ||
* | ||
* Usage: | ||
* make run | ||
*/ | ||
|
||
#include "gcc-common.h" | ||
|
||
int plugin_is_GPL_compatible; | ||
|
||
tree sancov_fndecl; | ||
|
||
static struct plugin_info sancov_plugin_info = { | ||
.version = "20160402", | ||
.help = "sancov plugin\n", | ||
}; | ||
|
||
static unsigned int sancov_execute(void) | ||
{ | ||
basic_block bb; | ||
|
||
/* Remove this line when this plugin and kcov will be in the kernel. | ||
if (!strcmp(DECL_NAME_POINTER(current_function_decl), DECL_NAME_POINTER(sancov_fndecl))) | ||
return 0; | ||
*/ | ||
|
||
FOR_EACH_BB_FN(bb, cfun) { | ||
const_gimple stmt; | ||
gcall *gcall; | ||
gimple_stmt_iterator gsi = gsi_after_labels(bb); | ||
|
||
if (gsi_end_p(gsi)) | ||
continue; | ||
|
||
stmt = gsi_stmt(gsi); | ||
gcall = as_a_gcall(gimple_build_call(sancov_fndecl, 0)); | ||
gimple_set_location(gcall, gimple_location(stmt)); | ||
gsi_insert_before(&gsi, gcall, GSI_SAME_STMT); | ||
} | ||
return 0; | ||
} | ||
|
||
#define PASS_NAME sancov | ||
|
||
#define NO_GATE | ||
#define TODO_FLAGS_FINISH TODO_dump_func | TODO_verify_stmts | TODO_update_ssa_no_phi | TODO_verify_flow | ||
|
||
#include "gcc-generate-gimple-pass.h" | ||
|
||
static void sancov_start_unit(void __unused *gcc_data, void __unused *user_data) | ||
{ | ||
tree leaf_attr, nothrow_attr; | ||
tree BT_FN_VOID = build_function_type_list(void_type_node, NULL_TREE); | ||
|
||
sancov_fndecl = build_fn_decl("__sanitizer_cov_trace_pc", BT_FN_VOID); | ||
|
||
DECL_ASSEMBLER_NAME(sancov_fndecl); | ||
TREE_PUBLIC(sancov_fndecl) = 1; | ||
DECL_EXTERNAL(sancov_fndecl) = 1; | ||
DECL_ARTIFICIAL(sancov_fndecl) = 1; | ||
DECL_PRESERVE_P(sancov_fndecl) = 1; | ||
DECL_UNINLINABLE(sancov_fndecl) = 1; | ||
TREE_USED(sancov_fndecl) = 1; | ||
|
||
nothrow_attr = tree_cons(get_identifier("nothrow"), NULL, NULL); | ||
decl_attributes(&sancov_fndecl, nothrow_attr, 0); | ||
gcc_assert(TREE_NOTHROW(sancov_fndecl)); | ||
#if BUILDING_GCC_VERSION > 4005 | ||
leaf_attr = tree_cons(get_identifier("leaf"), NULL, NULL); | ||
decl_attributes(&sancov_fndecl, leaf_attr, 0); | ||
#endif | ||
} | ||
|
||
int plugin_init(struct plugin_name_args *plugin_info, struct plugin_gcc_version *version) | ||
{ | ||
int i; | ||
struct register_pass_info sancov_plugin_pass_info; | ||
const char * const plugin_name = plugin_info->base_name; | ||
const int argc = plugin_info->argc; | ||
const struct plugin_argument * const argv = plugin_info->argv; | ||
bool enable = true; | ||
|
||
static const struct ggc_root_tab gt_ggc_r_gt_sancov[] = { | ||
{ | ||
.base = &sancov_fndecl, | ||
.nelt = 1, | ||
.stride = sizeof(sancov_fndecl), | ||
.cb = >_ggc_mx_tree_node, | ||
.pchw = >_pch_nx_tree_node | ||
}, | ||
LAST_GGC_ROOT_TAB | ||
}; | ||
|
||
/* BBs can be split afterwards?? */ | ||
sancov_plugin_pass_info.pass = make_sancov_pass(); | ||
#if BUILDING_GCC_VERSION >= 4009 | ||
sancov_plugin_pass_info.reference_pass_name = "asan"; | ||
#else | ||
sancov_plugin_pass_info.reference_pass_name = "nrv"; | ||
#endif | ||
sancov_plugin_pass_info.ref_pass_instance_number = 0; | ||
sancov_plugin_pass_info.pos_op = PASS_POS_INSERT_BEFORE; | ||
|
||
if (!plugin_default_version_check(version, &gcc_version)) { | ||
error(G_("incompatible gcc/plugin versions")); | ||
return 1; | ||
} | ||
|
||
for (i = 0; i < argc; ++i) { | ||
if (!strcmp(argv[i].key, "no-sancov")) { | ||
enable = false; | ||
continue; | ||
} | ||
error(G_("unkown option '-fplugin-arg-%s-%s'"), plugin_name, argv[i].key); | ||
} | ||
|
||
register_callback(plugin_name, PLUGIN_INFO, NULL, &sancov_plugin_info); | ||
|
||
if (!enable) | ||
return 0; | ||
|
||
#if BUILDING_GCC_VERSION < 6000 | ||
register_callback(plugin_name, PLUGIN_START_UNIT, &sancov_start_unit, NULL); | ||
register_callback(plugin_name, PLUGIN_REGISTER_GGC_ROOTS, NULL, (void *)>_ggc_r_gt_sancov); | ||
register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL, &sancov_plugin_pass_info); | ||
#endif | ||
|
||
return 0; | ||
} |