This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Add support to trace comparison instructions and switch statements


On Tue, Jul 11, 2017 at 1:59 PM, Wish Wu <wishwu007@gmail.com> wrote:
> Hi
>
> I wrote a test for "-fsanitize-coverage=trace-cmp" .
>
> Is there anybody tells me if these codes could be merged into gcc ?


Nice!

We are currently working on Linux kernel fuzzing that use the
comparison tracing. We use clang at the moment, but having this
support in gcc would be great for kernel land.

One concern I have: do we want to do some final refinements to the API
before we implement this in both compilers?

2 things we considered from our perspective:
 - communicating to the runtime which operands are constants
 - communicating to the runtime which comparisons are counting loop checks

First is useful if you do "find one operand in input and replace with
the other one" thing. Second is useful because counting loop checks
are usually not useful (at least all but one).
In the original Go implementation I also conveyed signedness of
operands, exact comparison operation (<, >, etc):
https://github.com/dvyukov/go-fuzz/blob/master/go-fuzz-defs/defs.go#L13
But I did not find any use for that.
I also gave all comparisons unique IDs:
https://github.com/dvyukov/go-fuzz/blob/master/go-fuzz-dep/sonar.go#L24
That turned out to be useful. And there are chances we will want this
for C/C++ as well.

Kostya, did anything like this pop up in your work on libfuzzer?
Can we still change the clang API? At least add an additional argument
to the callbacks?

At the very least I would suggest that we add an additional arg that
contains some flags (1/2 arg is a const, this is counting loop check,
etc). If we do that we can also have just 1 callback that accepts
uint64's for args because we can pass operand size in the flags:

void __sanitizer_cov_trace_cmp(uint64 arg1, uint64 arg2, uint64 flags);

But I wonder if 3 uint64 args will be too inefficient for 32 bit archs?...

If we create a global per comparison then we could put the flags into
the global:

void __sanitizer_cov_trace_cmp(uint64 arg1, uint64 arg2, something_t *global);

Thoughts?




> Index: gcc/testsuite/gcc.dg/sancov/basic3.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/sancov/basic3.c (nonexistent)
> +++ gcc/testsuite/gcc.dg/sancov/basic3.c (working copy)
> @@ -0,0 +1,42 @@
> +/* Basic test on number of inserted callbacks.  */
> +/* { dg-do compile } */
> +/* { dg-options "-fsanitize-coverage=trace-cmp -fdump-tree-optimized" } */
> +
> +void foo(char *a, short *b, int *c, long long *d, float *e, double *f)
> +{
> +  if (*a)
> +    *a += 1;
> +  if (*b)
> +    *b = *a;
> +  if (*c)
> +    *c += 1;
> +  if(*d)
> +    *d = *c;
> +  if(*e == *c)
> +    *e = *c;
> +  if(*f == *e)
> +    *f = *e;
> +  switch(*a)
> +    {
> +    case 2:
> +      *b += 2;
> +      break;
> +    default:
> +      break;
> +    }
> +  switch(*d)
> +    {
> +    case 3:
> +      *d += 3;
> +    case -4:
> +      *d -= 4;
> +    }
> +}
> +
> +/* { dg-final { scan-tree-dump-times
> "__builtin___sanitizer_cov_trace_cmp1 \\(" 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times
> "__builtin___sanitizer_cov_trace_cmp2 \\(" 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times
> "__builtin___sanitizer_cov_trace_cmp4 \\(" 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times
> "__builtin___sanitizer_cov_trace_cmp8 \\(" 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times
> "__builtin___sanitizer_cov_trace_cmpf \\(" 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times
> "__builtin___sanitizer_cov_trace_cmpd \\(" 1 "optimized" } } */
> +/* { dg-final { scan-tree-dump-times
> "__builtin___sanitizer_cov_trace_switch \\(" 2 "optimized" } } */
>
>
> With Regards
> Wish Wu
>
> On Mon, Jul 10, 2017 at 8:07 PM, 吴潍浠(此彼) <weixi.wwx@antfin.com> wrote:
>> Hi
>>
>> I write some codes to make gcc support comparison-guided fuzzing.
>> It is very like http://clang.llvm.org/docs/SanitizerCoverage.html#tracing-data-flow .
>> With -fsanitize-coverage=trace-cmp the compiler will insert extra instrumentation around comparison instructions and switch statements.
>> I think it is useful for fuzzing.  :D
>>
>> Patch is below, I may supply test cases later.
>>
>> With Regards
>> Wish Wu
>>
>> Index: gcc/asan.c
>> ===================================================================
>> --- gcc/asan.c  (revision 250082)
>> +++ gcc/asan.c  (working copy)
>> @@ -2705,6 +2705,29 @@ initialize_sanitizer_builtins (void)
>>    tree BT_FN_SIZE_CONST_PTR_INT
>>      = build_function_type_list (size_type_node, const_ptr_type_node,
>>                                 integer_type_node, NULL_TREE);
>> +
>> +  tree BT_FN_VOID_UINT8_UINT8
>> +    = build_function_type_list (void_type_node, unsigned_char_type_node,
>> +                               unsigned_char_type_node, NULL_TREE);
>> +  tree BT_FN_VOID_UINT16_UINT16
>> +    = build_function_type_list (void_type_node, uint16_type_node,
>> +                               uint16_type_node, NULL_TREE);
>> +  tree BT_FN_VOID_UINT32_UINT32
>> +    = build_function_type_list (void_type_node, uint32_type_node,
>> +                               uint32_type_node, NULL_TREE);
>> +  tree BT_FN_VOID_UINT64_UINT64
>> +    = build_function_type_list (void_type_node, uint64_type_node,
>> +                               uint64_type_node, NULL_TREE);
>> +  tree BT_FN_VOID_FLOAT_FLOAT
>> +    = build_function_type_list (void_type_node, float_type_node,
>> +                               float_type_node, NULL_TREE);
>> +  tree BT_FN_VOID_DOUBLE_DOUBLE
>> +    = build_function_type_list (void_type_node, double_type_node,
>> +                               double_type_node, NULL_TREE);
>> +  tree BT_FN_VOID_UINT64_PTR
>> +    = build_function_type_list (void_type_node, uint64_type_node,
>> +                               ptr_type_node, NULL_TREE);
>> +
>>    tree BT_FN_BOOL_VPTR_PTR_IX_INT_INT[5];
>>    tree BT_FN_IX_CONST_VPTR_INT[5];
>>    tree BT_FN_IX_VPTR_IX_INT[5];
>> Index: gcc/builtin-types.def
>> ===================================================================
>> --- gcc/builtin-types.def       (revision 250082)
>> +++ gcc/builtin-types.def       (working copy)
>> @@ -338,8 +338,20 @@ DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTRMODE_PTR,
>>                      BT_VOID, BT_PTRMODE, BT_PTR)
>>  DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTR_PTRMODE,
>>                      BT_VOID, BT_PTR, BT_PTRMODE)
>> +DEF_FUNCTION_TYPE_2 (BT_FN_VOID_UINT8_UINT8,
>> +                    BT_VOID, BT_UINT8, BT_UINT8)
>> +DEF_FUNCTION_TYPE_2 (BT_FN_VOID_UINT16_UINT16,
>> +                    BT_VOID, BT_UINT16, BT_UINT16)
>> +DEF_FUNCTION_TYPE_2 (BT_FN_VOID_UINT32_UINT32,
>> +                    BT_VOID, BT_UINT32, BT_UINT32)
>>  DEF_FUNCTION_TYPE_2 (BT_FN_VOID_UINT64_UINT64,
>>                      BT_VOID, BT_UINT64, BT_UINT64)
>> +DEF_FUNCTION_TYPE_2 (BT_FN_VOID_FLOAT_FLOAT,
>> +                    BT_VOID, BT_FLOAT, BT_FLOAT)
>> +DEF_FUNCTION_TYPE_2 (BT_FN_VOID_DOUBLE_DOUBLE,
>> +                    BT_VOID, BT_DOUBLE, BT_DOUBLE)
>> +DEF_FUNCTION_TYPE_2 (BT_FN_VOID_UINT64_PTR,
>> +                    BT_VOID, BT_UINT64, BT_PTR)
>>  DEF_FUNCTION_TYPE_2 (BT_FN_VOID_VALIST_REF_VALIST_ARG,
>>                      BT_VOID, BT_VALIST_REF, BT_VALIST_ARG)
>>  DEF_FUNCTION_TYPE_2 (BT_FN_LONG_LONG_LONG,
>> Index: gcc/common.opt
>> ===================================================================
>> --- gcc/common.opt      (revision 250082)
>> +++ gcc/common.opt      (working copy)
>> @@ -226,10 +226,9 @@ unsigned int flag_sanitize
>>  Variable
>>  unsigned int flag_sanitize_recover = (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT | SANITIZE_KERNEL_ADDRESS) & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN)
>>
>> -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.
>> +; What the coverage sanitizers should instrument
>> +Variable
>> +unsigned int flag_sanitize_coverage
>>
>>  ; Flag whether a prefix has been added to dump_base_name
>>  Variable
>> @@ -975,6 +974,10 @@ fsanitize=
>>  Common Driver Report Joined
>>  Select what to sanitize.
>>
>> +fsanitize-coverage=
>> +Common Driver Report Joined
>> +Select what to coverage sanitize.
>> +
>>  fasan-shadow-offset=
>>  Common Joined RejectNegative Var(common_deferred_options) Defer
>>  -fasan-shadow-offset=<number>  Use custom shadow memory offset.
>> Index: gcc/flag-types.h
>> ===================================================================
>> --- gcc/flag-types.h    (revision 250082)
>> +++ gcc/flag-types.h    (working copy)
>> @@ -250,6 +250,14 @@ enum sanitize_code {
>>                                   | SANITIZE_BOUNDS_STRICT
>>  };
>>
>> +/* Different trace modes */
>> +enum sanitize_coverage_code {
>> +  /* Trace PC */
>> +  SANITIZE_COV_TRACE_PC = 1UL << 0,
>> +  /* Trace Compare */
>> +  SANITIZE_COV_TRACE_CMP = 1UL << 1
>> +};
>> +
>>  /* flag_vtable_verify initialization levels. */
>>  enum vtv_priority {
>>    VTV_NO_PRIORITY       = 0,  /* i.E. Do NOT do vtable verification. */
>> Index: gcc/opts.c
>> ===================================================================
>> --- gcc/opts.c  (revision 250082)
>> +++ gcc/opts.c  (working copy)
>> @@ -1518,6 +1518,17 @@ const struct sanitizer_opts_s sanitizer_opts[] =
>>    { NULL, 0U, 0UL, false }
>>  };
>>
>> +/* -f{,no-}sanitize-coverage= suboptions.  */
>> +const struct sanitizer_opts_s coverage_sanitizer_opts[] =
>> +{
>> +#define SANITIZER_OPT(name, flags, recover) \
>> +    { #name, flags, sizeof #name - 1, recover }
>> +  SANITIZER_OPT (trace-pc, SANITIZE_COV_TRACE_PC, false),
>> +  SANITIZER_OPT (trace-cmp, SANITIZE_COV_TRACE_CMP, false),
>> +#undef SANITIZER_OPT
>> +  { NULL, 0U, 0UL, false }
>> +};
>> +
>>  /* A struct for describing a run of chars within a string.  */
>>
>>  struct string_fragment
>> @@ -1665,6 +1676,85 @@ parse_sanitizer_options (const char *p, location_t
>>    return flags;
>>  }
>>
>> +/* Given ARG, an unrecognized coverage sanitizer option, return the best
>> +   matching coverage sanitizer option, or NULL if there isn't one.
>> +   VALUE is non-zero for the regular form of the option, zero
>> +   for the "no-" form (e.g. "-fno-sanitize-coverage=").  */
>> +
>> +static const char *
>> +get_closest_coverage_sanitizer_option (const string_fragment &arg, int value)
>> +{
>> +  best_match <const string_fragment &, const char*> bm (arg);
>> +  for (int i = 0; coverage_sanitizer_opts[i].name != NULL; ++i)
>> +    {
>> +      bm.consider (coverage_sanitizer_opts[i].name);
>> +    }
>> +  return bm.get_best_meaningful_candidate ();
>> +}
>> +
>> +/* Parse comma separated sanitizer suboptions from P for option SCODE,
>> +   adjust previous FLAGS and return new ones.  If COMPLAIN is false,
>> +   don't issue diagnostics.  */
>> +
>> +unsigned int
>> +parse_coverage_sanitizer_options (const char *p, location_t loc,
>> +                        unsigned int flags, int value, bool complain)
>> +{
>> +  while (*p != 0)
>> +    {
>> +      size_t len, i;
>> +      bool found = false;
>> +      const char *comma = strchr (p, ',');
>> +
>> +      if (comma == NULL)
>> +       len = strlen (p);
>> +      else
>> +       len = comma - p;
>> +      if (len == 0)
>> +       {
>> +         p = comma + 1;
>> +         continue;
>> +       }
>> +
>> +      /* Check to see if the string matches an option class name.  */
>> +      for (i = 0; coverage_sanitizer_opts[i].name != NULL; ++i)
>> +       if (len == coverage_sanitizer_opts[i].len
>> +           && memcmp (p, coverage_sanitizer_opts[i].name, len) == 0)
>> +         {
>> +           if (value)
>> +             flags |= coverage_sanitizer_opts[i].flag;
>> +           else
>> +             flags &= ~coverage_sanitizer_opts[i].flag;
>> +           found = true;
>> +           break;
>> +         }
>> +
>> +      if (! found && complain)
>> +       {
>> +         const char *hint
>> +           = get_closest_coverage_sanitizer_option (string_fragment (p, len),
>> +                                                    value);
>> +
>> +         if (hint)
>> +           error_at (loc,
>> +                     "unrecognized argument to -f%ssanitize-coverage= option: %q.*s;"
>> +                     " did you mean %qs?",
>> +                     value ? "" : "no-",
>> +                     (int) len, p, hint);
>> +         else
>> +           error_at (loc,
>> +                     "unrecognized argument to -f%ssanitize-coverage= option: %q.*s",
>> +                     value ? "" : "no-",
>> +                     (int) len, p);
>> +       }
>> +
>> +      if (comma == NULL)
>> +       break;
>> +      p = comma + 1;
>> +    }
>> +  return flags;
>> +}
>> +
>>  /* Parse string values of no_sanitize attribute passed in VALUE.
>>     Values are separated with comma.  Wrong argument is stored to
>>     WRONG_ARGUMENT variable.  */
>> @@ -1942,6 +2032,12 @@ common_handle_option (struct gcc_options *opts,
>>           &= ~(SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
>>        break;
>>
>> +    case OPT_fsanitize_coverage_:
>> +      opts->x_flag_sanitize_coverage
>> +       = parse_coverage_sanitizer_options (arg, loc,
>> +                                  opts->x_flag_sanitize_coverage, value, true);
>> +      break;
>> +
>>      case OPT_O:
>>      case OPT_Os:
>>      case OPT_Ofast:
>> Index: gcc/sancov.c
>> ===================================================================
>> --- gcc/sancov.c        (revision 250082)
>> +++ gcc/sancov.c        (working copy)
>> @@ -29,31 +29,194 @@ along with GCC; see the file COPYING3.  If not see
>>  #include "flags.h"
>>  #include "stmt.h"
>>  #include "gimple-iterator.h"
>> +#include "tree-core.h"
>>  #include "tree-cfg.h"
>>  #include "tree-pass.h"
>>  #include "tree-iterator.h"
>> +#include "fold-const.h"
>> +#include "stringpool.h"
>> +#include "output.h"
>> +#include "cgraph.h"
>>  #include "asan.h"
>>
>>  namespace {
>>
>> +static void
>> +instrument_cond (gimple_stmt_iterator *gsi, gimple *stmt)
>> +{
>> +  tree lhs = gimple_cond_lhs (stmt);
>> +  tree rhs = gimple_cond_rhs (stmt);
>> +  unsigned int bitno = TYPE_PRECISION (TREE_TYPE (lhs)) > TYPE_PRECISION (TREE_TYPE (rhs)) ?
>> +                      TYPE_PRECISION (TREE_TYPE (lhs)) : TYPE_PRECISION (TREE_TYPE (rhs));
>> +  if (TREE_CODE (TREE_TYPE (lhs)) == INTEGER_TYPE)
>> +    {
>> +      enum built_in_function fncode;
>> +      switch (bitno)
>> +       {
>> +       case 8:
>> +         fncode = BUILT_IN_SANITIZER_COV_TRACE_CMP1;
>> +         break;
>> +
>> +       case 16:
>> +         fncode = BUILT_IN_SANITIZER_COV_TRACE_CMP2;
>> +         break;
>> +
>> +       case 32:
>> +         fncode = BUILT_IN_SANITIZER_COV_TRACE_CMP4;
>> +         break;
>> +
>> +       case 64:
>> +         fncode = BUILT_IN_SANITIZER_COV_TRACE_CMP8;
>> +         break;
>> +
>> +       default:
>> +         return;
>> +         break;
>> +       }
>> +      tree fndecl = builtin_decl_implicit (fncode);
>> +      gimple *gcall = gimple_build_call (fndecl, 2, lhs, rhs);
>> +      gimple_set_location (gcall, gimple_location (stmt));
>> +      gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
>> +    }
>> +  else if (TREE_CODE (TREE_TYPE (lhs)) == REAL_TYPE)
>> +    {
>> +      enum built_in_function fncode;
>> +      switch (bitno)
>> +       {
>> +       case 32:
>> +         fncode = BUILT_IN_SANITIZER_COV_TRACE_CMPF;
>> +         break;
>> +
>> +       case 64:
>> +         fncode = BUILT_IN_SANITIZER_COV_TRACE_CMPD;
>> +         break;
>> +
>> +       default:
>> +         return;
>> +         break;
>> +        }
>> +      tree fndecl = builtin_decl_implicit (fncode);
>> +      gimple *gcall = gimple_build_call (fndecl, 2, lhs, rhs);
>> +      gimple_set_location (gcall, gimple_location (stmt));
>> +      gsi_insert_before (gsi, gcall, GSI_SAME_STMT);
>> +    }
>> +}
>> +
>> +static void
>> +instrument_switch (gimple_stmt_iterator *gsi, gimple *stmt, function *fun)
>> +{
>> +  gswitch *switch_stmt = as_a<gswitch *> (stmt);
>> +  tree index = gimple_switch_index (switch_stmt);
>> +  unsigned bitno = TYPE_PRECISION (TREE_TYPE (index));
>> +  unsigned i, n = gimple_switch_num_labels (switch_stmt), num = 0;
>> +  for (i = 0; i < n; ++i)
>> +    {
>> +      tree label = gimple_switch_label (switch_stmt, i);
>> +      tree low_case = CASE_LOW (label);
>> +      if (low_case != NULL_TREE)
>> +          num++;
>> +      tree high_case = CASE_HIGH (label);
>> +      if (high_case != NULL_TREE)
>> +          num++;
>> +    }
>> +
>> +  tree case_array_elem_type = build_type_variant (uint64_type_node, 1, 0);
>> +  tree case_array_type = build_array_type (case_array_elem_type,
>> +                                          build_index_type (size_int (num + 2 - 1)));
>> +  char name[64];
>> +  static size_t case_array_count = 0;
>> +  snprintf(name, sizeof(name) - 1, "__sanitizer_cov_trace_switch_array%lu", case_array_count++);
>> +  tree case_array_var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
>> +                                   get_identifier (name), case_array_type);
>> +  TREE_STATIC (case_array_var) = 1;
>> +  TREE_PUBLIC (case_array_var) = 0;
>> +  TREE_CONSTANT (case_array_var) = 1;
>> +  TREE_READONLY (case_array_var) = 1;
>> +  DECL_EXTERNAL (case_array_var) = 0;
>> +  DECL_ARTIFICIAL (case_array_var) = 1;
>> +  DECL_IGNORED_P (case_array_var) = 1;
>> +
>> +  vec <constructor_elt, va_gc> *v = NULL;
>> +  vec_alloc (v, num + 2);
>> +  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (uint64_type_node, num));
>> +  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (uint64_type_node, bitno));
>> +  for (i = 0; i < n; ++i)
>> +    {
>> +      tree label = gimple_switch_label (switch_stmt, i);
>> +
>> +      tree low_case = CASE_LOW (label);
>> +      if (low_case != NULL_TREE)
>> +        CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
>> +                               build_int_cst (uint64_type_node, TREE_INT_CST_LOW (low_case)));
>> +
>> +      tree high_case = CASE_HIGH (label);
>> +      if (high_case != NULL_TREE)
>> +        CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
>> +                               build_int_cst (uint64_type_node, TREE_INT_CST_LOW (high_case)));
>> +    }
>> +  tree ctor = build_constructor (case_array_type, v);
>> +  TREE_STATIC (ctor) = 1;
>> +  TREE_PUBLIC (ctor) = 0;
>> +  TREE_CONSTANT (ctor) = 1;
>> +  TREE_READONLY (ctor) = 1;
>> +  DECL_EXTERNAL (ctor) = 0;
>> +  DECL_INITIAL (case_array_var) = ctor;
>> +  varpool_node::finalize_decl (case_array_var);
>> +
>> +  tree case_array_var_ref = build_fold_addr_expr (case_array_var);
>> +  add_local_decl (fun, case_array_var);
>> +  tree fndecl = builtin_decl_implicit (BUILT_IN_SANITIZER_COV_TRACE_SWITCH);
>> +  gimple *gcall = gimple_build_call (fndecl, 2, index, case_array_var_ref);
>> +  gimple_set_location (gcall, gimple_location (stmt));
>> +  gsi_insert_before(gsi, gcall, GSI_SAME_STMT);
>> +}
>> +
>>  unsigned
>>  sancov_pass (function *fun)
>>  {
>>    initialize_sanitizer_builtins ();
>>
>> +  basic_block bb;
>> +
>>    /* 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)
>> +  if (flag_sanitize_coverage & SANITIZE_COV_TRACE_PC)
>>      {
>> -      gimple_stmt_iterator gsi = gsi_start_nondebug_after_labels_bb (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);
>> +      tree fndecl = builtin_decl_implicit (BUILT_IN_SANITIZER_COV_TRACE_PC);
>> +      FOR_EACH_BB_FN (bb, fun)
>> +        {
>> +          gimple_stmt_iterator gsi = gsi_start_nondebug_after_labels_bb (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);
>> +        }
>>      }
>> +
>> +  /* Insert callback to every compare statments. */
>> +  if (flag_sanitize_coverage & SANITIZE_COV_TRACE_CMP)
>> +    {
>> +      FOR_EACH_BB_FN (bb, fun)
>> +       {
>> +          gimple_stmt_iterator gsi;
>> +          for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
>> +           {
>> +              gimple *stmt = gsi_stmt (gsi);
>> +              switch (gimple_code (stmt))
>> +               {
>> +                case GIMPLE_COND:
>> +                 instrument_cond (&gsi, stmt);
>> +                 break;
>> +               case GIMPLE_SWITCH:
>> +                 instrument_switch (&gsi, stmt, fun);
>> +                 break;
>> +               default:
>> +                 break;
>> +               }
>> +            }
>> +        }
>> +    }
>>    return 0;
>>  }
>>
>> Index: gcc/sanitizer.def
>> ===================================================================
>> --- gcc/sanitizer.def   (revision 250082)
>> +++ gcc/sanitizer.def   (working copy)
>> @@ -529,6 +529,27 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_DYNAMI
>>  DEF_SANITIZER_BUILTIN(BUILT_IN_SANITIZER_COV_TRACE_PC,
>>                       "__sanitizer_cov_trace_pc",
>>                       BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
>> +DEF_SANITIZER_BUILTIN(BUILT_IN_SANITIZER_COV_TRACE_CMP1,
>> +                     "__sanitizer_cov_trace_cmp1",
>> +                     BT_FN_VOID_UINT8_UINT8, ATTR_NOTHROW_LEAF_LIST)
>> +DEF_SANITIZER_BUILTIN(BUILT_IN_SANITIZER_COV_TRACE_CMP2,
>> +                     "__sanitizer_cov_trace_cmp2",
>> +                     BT_FN_VOID_UINT16_UINT16, ATTR_NOTHROW_LEAF_LIST)
>> +DEF_SANITIZER_BUILTIN(BUILT_IN_SANITIZER_COV_TRACE_CMP4,
>> +                     "__sanitizer_cov_trace_cmp4",
>> +                     BT_FN_VOID_UINT32_UINT32, ATTR_NOTHROW_LEAF_LIST)
>> +DEF_SANITIZER_BUILTIN(BUILT_IN_SANITIZER_COV_TRACE_CMP8,
>> +                     "__sanitizer_cov_trace_cmp8",
>> +                     BT_FN_VOID_UINT64_UINT64, ATTR_NOTHROW_LEAF_LIST)
>> +DEF_SANITIZER_BUILTIN(BUILT_IN_SANITIZER_COV_TRACE_CMPF,
>> +                     "__sanitizer_cov_trace_cmpf",
>> +                     BT_FN_VOID_FLOAT_FLOAT, ATTR_NOTHROW_LEAF_LIST)
>> +DEF_SANITIZER_BUILTIN(BUILT_IN_SANITIZER_COV_TRACE_CMPD,
>> +                     "__sanitizer_cov_trace_cmpd",
>> +                     BT_FN_VOID_DOUBLE_DOUBLE, ATTR_NOTHROW_LEAF_LIST)
>> +DEF_SANITIZER_BUILTIN(BUILT_IN_SANITIZER_COV_TRACE_SWITCH,
>> +                     "__sanitizer_cov_trace_switch",
>> +                     BT_FN_VOID_UINT64_PTR, ATTR_NOTHROW_LEAF_LIST)
>>
>>  /* This has to come after all the sanitizer builtins.  */
>>  DEF_BUILTIN_STUB(END_SANITIZER_BUILTINS, (const char *)0)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]