OLD | NEW |
(Empty) | |
| 1 /* Code coverage instrumentation for fuzzing. |
| 2 Copyright (C) 2015 Free Software Foundation, Inc. |
| 3 Contributed by Dmitry Vyukov <dvyukov@google.com> |
| 4 |
| 5 This file is part of GCC. |
| 6 |
| 7 GCC is free software; you can redistribute it and/or modify it under |
| 8 the terms of the GNU General Public License as published by the Free |
| 9 Software Foundation; either version 3, or (at your option) any later |
| 10 version. |
| 11 |
| 12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
| 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 15 for more details. |
| 16 |
| 17 You should have received a copy of the GNU General Public License |
| 18 along with GCC; see the file COPYING3. If not see |
| 19 <http://www.gnu.org/licenses/>. */ |
| 20 |
| 21 |
| 22 #include "config.h" |
| 23 #include "system.h" |
| 24 #include "coretypes.h" |
| 25 #include "alias.h" |
| 26 #include "backend.h" |
| 27 #include "tree.h" |
| 28 #include "gimple.h" |
| 29 #include "basic-block.h" |
| 30 #include "rtl.h" |
| 31 #include "options.h" |
| 32 #include "flags.h" |
| 33 #include "stmt.h" |
| 34 #include "expr.h" |
| 35 #include "gimple-iterator.h" |
| 36 #include "tree-cfg.h" |
| 37 #include "tree-pass.h" |
| 38 #include "tree-iterator.h" |
| 39 #include "stringpool.h" |
| 40 |
| 41 namespace { |
| 42 |
| 43 static tree |
| 44 coverage_callback (void) |
| 45 { |
| 46 tree fn_type; |
| 47 static tree def; |
| 48 |
| 49 if (def != NULL) |
| 50 return def; |
| 51 |
| 52 fn_type = build_function_type_list (void_type_node, NULL_TREE); |
| 53 def = build_fn_decl ("__fuzz_coverage", fn_type); |
| 54 TREE_NOTHROW (def) = 1; |
| 55 DECL_ATTRIBUTES (def) = tree_cons (get_identifier ("leaf"), NULL, DECL_ATTRIBU
TES (def)); |
| 56 DECL_ASSEMBLER_NAME (def); |
| 57 return def; |
| 58 } |
| 59 |
| 60 unsigned fuzz_pass (void) |
| 61 { |
| 62 basic_block bb; |
| 63 gimple_stmt_iterator gsi; |
| 64 gimple *stmt, *f; |
| 65 |
| 66 FOR_EACH_BB_FN (bb, cfun) |
| 67 { |
| 68 gsi = gsi_start_bb (bb); |
| 69 stmt = gsi_stmt (gsi); |
| 70 while (stmt && dyn_cast <glabel *> (stmt)) |
| 71 { |
| 72 gsi_next (&gsi); |
| 73 stmt = gsi_stmt (gsi); |
| 74 } |
| 75 if (!stmt) |
| 76 continue; |
| 77 f = gimple_build_call (coverage_callback (), 0); |
| 78 gimple_set_location (f, gimple_location (stmt)); |
| 79 gsi_insert_before (&gsi, f, GSI_SAME_STMT); |
| 80 } |
| 81 return 0; |
| 82 } |
| 83 |
| 84 const pass_data pass_data_fuzz = |
| 85 { |
| 86 GIMPLE_PASS, /* type */ |
| 87 "fuzz", /* name */ |
| 88 OPTGROUP_NONE, /* optinfo_flags */ |
| 89 TV_NONE, /* tv_id */ |
| 90 ( PROP_cfg ), /* properties_required */ |
| 91 0, /* properties_provided */ |
| 92 0, /* properties_destroyed */ |
| 93 0, /* todo_flags_start */ |
| 94 TODO_update_ssa, /* todo_flags_finish */ |
| 95 }; |
| 96 |
| 97 class pass_fuzz : public gimple_opt_pass |
| 98 { |
| 99 public: |
| 100 pass_fuzz (gcc::context *ctxt) |
| 101 : gimple_opt_pass (pass_data_fuzz, ctxt) |
| 102 {} |
| 103 |
| 104 opt_pass * clone () { return new pass_fuzz (m_ctxt); } |
| 105 virtual bool gate (function *) { return fuzzing_coverage_flag; } |
| 106 virtual unsigned int execute (function *) { return fuzz_pass (); } |
| 107 }; // class pass_fuzz |
| 108 |
| 109 } // anon namespace |
| 110 |
| 111 gimple_opt_pass * |
| 112 make_pass_fuzz_coverage (gcc::context *ctxt) |
| 113 { |
| 114 return new pass_fuzz (ctxt); |
| 115 } |
OLD | NEW |