From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 111022 invoked by alias); 11 Jul 2017 12:00:28 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 105367 invoked by uid 89); 11 Jul 2017 12:00:04 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.3 required=5.0 tests=BAYES_00,BODY_8BITS,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,GARBLED_BODY,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_ASCII_DIVIDERS,RCVD_IN_DNSWL_NONE,RCVD_IN_SORBS_SPAM,SPF_PASS autolearn=ham version=3.3.2 spammy= X-Spam-User: qpsmtpd, 2 recipients X-HELO: mail-qk0-f178.google.com Received: from mail-qk0-f178.google.com (HELO mail-qk0-f178.google.com) (209.85.220.178) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 11 Jul 2017 12:00:00 +0000 Received: by mail-qk0-f178.google.com with SMTP id p21so100566259qke.3; Tue, 11 Jul 2017 05:00:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=ChrnxoMkiWRFnLs9QFcpWWW644NPFlSCAgwPyVCC0OA=; b=GTXpB+7BRpY25oge/fIygwxOd+UfeolrcXI9k8ZJ4GJeM51TnX0HbvdCaD1NU2ZZVx obs7LOYc93Uh9JWPEkX3fyGqpMaZhCVyfwcGLFr4DRSTAMcfM3g3zdkz6QK+vNgbZcIf uov9e7bTtn1uaYxIxzMAsrY/t9FW9iF1FO628EBTjhVsmdg94ns7PfDSZM8oiwhWf4HB bNTT3kLhYZ0lX5LJM3zHw+j0DzhIowQLSuSRrBkyT8HMJLJ2/O0qLyalNmMkWfkWI3Bs MJsIFW9uGgPnhzmTX3+/aDUfFPw6EIfUSIv5dx0RrB75bM3TjrwXMRlg/+Z8s7bo8cUt EEDA== X-Gm-Message-State: AIVw110Sqdfkqd8GjqbkL9adLOS2nLMJ+lpxdX4bzyAo6nZYztkLTDtQ cKCVqHBQ1PBxyUbXghIQdmnTBId/ybJhLbM= X-Received: by 10.55.76.71 with SMTP id z68mr9405257qka.8.1499774398448; Tue, 11 Jul 2017 04:59:58 -0700 (PDT) MIME-Version: 1.0 Received: by 10.140.30.163 with HTTP; Tue, 11 Jul 2017 04:59:58 -0700 (PDT) In-Reply-To: <234840fd-a06a-4dfd-a1c5-254e26144754.weixi.wwx@antfin.com> References: <234840fd-a06a-4dfd-a1c5-254e26144754.weixi.wwx@antfin.com> From: Wish Wu Date: Tue, 11 Jul 2017 12:00:00 -0000 Message-ID: Subject: Re: Add support to trace comparison instructions and switch statements To: gcc , gcc-patches Cc: weixi.wwx@antfin.com Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-SW-Source: 2017-07/txt/msg00512.txt.bz2 Hi I wrote a test for "-fsanitize-coverage=3Dtrace-cmp" . Is there anybody tells me if these codes could be merged into gcc ? Index: gcc/testsuite/gcc.dg/sancov/basic3.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- 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=3Dtrace-cmp -fdump-tree-optimized" } = */ + +void foo(char *a, short *b, int *c, long long *d, float *e, double *f) +{ + if (*a) + *a +=3D 1; + if (*b) + *b =3D *a; + if (*c) + *c +=3D 1; + if(*d) + *d =3D *c; + if(*e =3D=3D *c) + *e =3D *c; + if(*f =3D=3D *e) + *f =3D *e; + switch(*a) + { + case 2: + *b +=3D 2; + break; + default: + break; + } + switch(*d) + { + case 3: + *d +=3D 3; + case -4: + *d -=3D 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, =E5=90=B4=E6=BD=8D=E6=B5=A0(=E6=AD=A4=E5= =BD=BC) 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=3Dtrace-cmp the compiler will insert extra instr= umentation 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 > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- 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 > =3D build_function_type_list (size_type_node, const_ptr_type_node, > integer_type_node, NULL_TREE); > + > + tree BT_FN_VOID_UINT8_UINT8 > + =3D build_function_type_list (void_type_node, unsigned_char_type_nod= e, > + unsigned_char_type_node, NULL_TREE); > + tree BT_FN_VOID_UINT16_UINT16 > + =3D build_function_type_list (void_type_node, uint16_type_node, > + uint16_type_node, NULL_TREE); > + tree BT_FN_VOID_UINT32_UINT32 > + =3D build_function_type_list (void_type_node, uint32_type_node, > + uint32_type_node, NULL_TREE); > + tree BT_FN_VOID_UINT64_UINT64 > + =3D build_function_type_list (void_type_node, uint64_type_node, > + uint64_type_node, NULL_TREE); > + tree BT_FN_VOID_FLOAT_FLOAT > + =3D build_function_type_list (void_type_node, float_type_node, > + float_type_node, NULL_TREE); > + tree BT_FN_VOID_DOUBLE_DOUBLE > + =3D build_function_type_list (void_type_node, double_type_node, > + double_type_node, NULL_TREE); > + tree BT_FN_VOID_UINT64_PTR > + =3D 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 > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- 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 > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- gcc/common.opt (revision 250082) > +++ gcc/common.opt (working copy) > @@ -226,10 +226,9 @@ unsigned int flag_sanitize > Variable > unsigned int flag_sanitize_recover =3D (SANITIZE_UNDEFINED | SANITIZE_UN= DEFINED_NONDEFAULT | SANITIZE_KERNEL_ADDRESS) & ~(SANITIZE_UNREACHABLE | SA= NITIZE_RETURN) > > -fsanitize-coverage=3Dtrace-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=3D > Common Driver Report Joined > Select what to sanitize. > > +fsanitize-coverage=3D > +Common Driver Report Joined > +Select what to coverage sanitize. > + > fasan-shadow-offset=3D > Common Joined RejectNegative Var(common_deferred_options) Defer > -fasan-shadow-offset=3D Use custom shadow memory offset. > Index: gcc/flag-types.h > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- 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 =3D 1UL << 0, > + /* Trace Compare */ > + SANITIZE_COV_TRACE_CMP =3D 1UL << 1 > +}; > + > /* flag_vtable_verify initialization levels. */ > enum vtv_priority { > VTV_NO_PRIORITY =3D 0, /* i.E. Do NOT do vtable verification. */ > Index: gcc/opts.c > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- gcc/opts.c (revision 250082) > +++ gcc/opts.c (working copy) > @@ -1518,6 +1518,17 @@ const struct sanitizer_opts_s sanitizer_opts[] =3D > { NULL, 0U, 0UL, false } > }; > > +/* -f{,no-}sanitize-coverage=3D suboptions. */ > +const struct sanitizer_opts_s coverage_sanitizer_opts[] =3D > +{ > +#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=3D"). */ > + > +static const char * > +get_closest_coverage_sanitizer_option (const string_fragment &arg, int v= alue) > +{ > + best_match bm (arg); > + for (int i =3D 0; coverage_sanitizer_opts[i].name !=3D 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 !=3D 0) > + { > + size_t len, i; > + bool found =3D false; > + const char *comma =3D strchr (p, ','); > + > + if (comma =3D=3D NULL) > + len =3D strlen (p); > + else > + len =3D comma - p; > + if (len =3D=3D 0) > + { > + p =3D comma + 1; > + continue; > + } > + > + /* Check to see if the string matches an option class name. */ > + for (i =3D 0; coverage_sanitizer_opts[i].name !=3D NULL; ++i) > + if (len =3D=3D coverage_sanitizer_opts[i].len > + && memcmp (p, coverage_sanitizer_opts[i].name, len) =3D=3D 0) > + { > + if (value) > + flags |=3D coverage_sanitizer_opts[i].flag; > + else > + flags &=3D ~coverage_sanitizer_opts[i].flag; > + found =3D true; > + break; > + } > + > + if (! found && complain) > + { > + const char *hint > + =3D get_closest_coverage_sanitizer_option (string_fragment (p= , len), > + value); > + > + if (hint) > + error_at (loc, > + "unrecognized argument to -f%ssanitize-coverage=3D = option: %q.*s;" > + " did you mean %qs?", > + value ? "" : "no-", > + (int) len, p, hint); > + else > + error_at (loc, > + "unrecognized argument to -f%ssanitize-coverage=3D = option: %q.*s", > + value ? "" : "no-", > + (int) len, p); > + } > + > + if (comma =3D=3D NULL) > + break; > + p =3D 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, > &=3D ~(SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT); > break; > > + case OPT_fsanitize_coverage_: > + opts->x_flag_sanitize_coverage > + =3D 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 > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- 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 =3D gimple_cond_lhs (stmt); > + tree rhs =3D gimple_cond_rhs (stmt); > + unsigned int bitno =3D TYPE_PRECISION (TREE_TYPE (lhs)) > TYPE_PRECISI= ON (TREE_TYPE (rhs)) ? > + TYPE_PRECISION (TREE_TYPE (lhs)) : TYPE_PRECISION = (TREE_TYPE (rhs)); > + if (TREE_CODE (TREE_TYPE (lhs)) =3D=3D INTEGER_TYPE) > + { > + enum built_in_function fncode; > + switch (bitno) > + { > + case 8: > + fncode =3D BUILT_IN_SANITIZER_COV_TRACE_CMP1; > + break; > + > + case 16: > + fncode =3D BUILT_IN_SANITIZER_COV_TRACE_CMP2; > + break; > + > + case 32: > + fncode =3D BUILT_IN_SANITIZER_COV_TRACE_CMP4; > + break; > + > + case 64: > + fncode =3D BUILT_IN_SANITIZER_COV_TRACE_CMP8; > + break; > + > + default: > + return; > + break; > + } > + tree fndecl =3D builtin_decl_implicit (fncode); > + gimple *gcall =3D 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)) =3D=3D REAL_TYPE) > + { > + enum built_in_function fncode; > + switch (bitno) > + { > + case 32: > + fncode =3D BUILT_IN_SANITIZER_COV_TRACE_CMPF; > + break; > + > + case 64: > + fncode =3D BUILT_IN_SANITIZER_COV_TRACE_CMPD; > + break; > + > + default: > + return; > + break; > + } > + tree fndecl =3D builtin_decl_implicit (fncode); > + gimple *gcall =3D 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 *fu= n) > +{ > + gswitch *switch_stmt =3D as_a (stmt); > + tree index =3D gimple_switch_index (switch_stmt); > + unsigned bitno =3D TYPE_PRECISION (TREE_TYPE (index)); > + unsigned i, n =3D gimple_switch_num_labels (switch_stmt), num =3D 0; > + for (i =3D 0; i < n; ++i) > + { > + tree label =3D gimple_switch_label (switch_stmt, i); > + tree low_case =3D CASE_LOW (label); > + if (low_case !=3D NULL_TREE) > + num++; > + tree high_case =3D CASE_HIGH (label); > + if (high_case !=3D NULL_TREE) > + num++; > + } > + > + tree case_array_elem_type =3D build_type_variant (uint64_type_node, 1,= 0); > + tree case_array_type =3D build_array_type (case_array_elem_type, > + build_index_type (size_int (nu= m + 2 - 1))); > + char name[64]; > + static size_t case_array_count =3D 0; > + snprintf(name, sizeof(name) - 1, "__sanitizer_cov_trace_switch_array%l= u", case_array_count++); > + tree case_array_var =3D build_decl (UNKNOWN_LOCATION, VAR_DECL, > + get_identifier (name), case_array_typ= e); > + TREE_STATIC (case_array_var) =3D 1; > + TREE_PUBLIC (case_array_var) =3D 0; > + TREE_CONSTANT (case_array_var) =3D 1; > + TREE_READONLY (case_array_var) =3D 1; > + DECL_EXTERNAL (case_array_var) =3D 0; > + DECL_ARTIFICIAL (case_array_var) =3D 1; > + DECL_IGNORED_P (case_array_var) =3D 1; > + > + vec *v =3D 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 =3D 0; i < n; ++i) > + { > + tree label =3D gimple_switch_label (switch_stmt, i); > + > + tree low_case =3D CASE_LOW (label); > + if (low_case !=3D NULL_TREE) > + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, > + build_int_cst (uint64_type_node, TREE_INT= _CST_LOW (low_case))); > + > + tree high_case =3D CASE_HIGH (label); > + if (high_case !=3D NULL_TREE) > + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, > + build_int_cst (uint64_type_node, TREE_INT= _CST_LOW (high_case))); > + } > + tree ctor =3D build_constructor (case_array_type, v); > + TREE_STATIC (ctor) =3D 1; > + TREE_PUBLIC (ctor) =3D 0; > + TREE_CONSTANT (ctor) =3D 1; > + TREE_READONLY (ctor) =3D 1; > + DECL_EXTERNAL (ctor) =3D 0; > + DECL_INITIAL (case_array_var) =3D ctor; > + varpool_node::finalize_decl (case_array_var); > + > + tree case_array_var_ref =3D build_fold_addr_expr (case_array_var); > + add_local_decl (fun, case_array_var); > + tree fndecl =3D builtin_decl_implicit (BUILT_IN_SANITIZER_COV_TRACE_SW= ITCH); > + gimple *gcall =3D 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 =3D 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 =3D gsi_start_nondebug_after_labels_bb (b= b); > - if (gsi_end_p (gsi)) > - continue; > - gimple *stmt =3D gsi_stmt (gsi); > - gimple *gcall =3D gimple_build_call (fndecl, 0); > - gimple_set_location (gcall, gimple_location (stmt)); > - gsi_insert_before (&gsi, gcall, GSI_SAME_STMT); > + tree fndecl =3D builtin_decl_implicit (BUILT_IN_SANITIZER_COV_TRAC= E_PC); > + FOR_EACH_BB_FN (bb, fun) > + { > + gimple_stmt_iterator gsi =3D gsi_start_nondebug_after_labels_b= b (bb); > + if (gsi_end_p (gsi)) > + continue; > + gimple *stmt =3D gsi_stmt (gsi); > + gimple *gcall =3D 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 =3D gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&g= si)) > + { > + gimple *stmt =3D 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 > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > --- 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)