* [PATCH] Add no_sanitize_coverage attribute. @ 2021-05-20 8:33 Martin Liška 2021-05-20 8:45 ` Marco Elver 0 siblings, 1 reply; 9+ messages in thread From: Martin Liška @ 2021-05-20 8:33 UTC (permalink / raw) To: gcc-patches; +Cc: Marco Elver, Nick Desaulniers Hello. The patch implements one missing attribute which can be used for per-function disabling of coverage sanitization. Patch can bootstrap on x86_64-linux-gnu and survives regression tests. Ready to be installed? Thanks, Martin gcc/ChangeLog: * asan.h (sanitize_coverage_p): New function. * doc/extend.texi: Document it. * fold-const.c (fold_range_test): Use sanitize_flags_p instead of flag_sanitize_coverage. (fold_truth_andor): Likewise. * sancov.c: Likewise. * tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise. gcc/c-family/ChangeLog: * c-attribs.c (handle_no_sanitize_coverage_attribute): New. gcc/testsuite/ChangeLog: * gcc.dg/sancov/attribute.c: New test. --- gcc/asan.h | 10 ++++++++++ gcc/c-family/c-attribs.c | 20 ++++++++++++++++++++ gcc/doc/extend.texi | 6 ++++++ gcc/fold-const.c | 4 ++-- gcc/sancov.c | 4 ++-- gcc/testsuite/gcc.dg/sancov/attribute.c | 15 +++++++++++++++ gcc/tree-ssa-ifcombine.c | 4 +++- 7 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/sancov/attribute.c diff --git a/gcc/asan.h b/gcc/asan.h index f110f1db563..8c0b2baf170 100644 --- a/gcc/asan.h +++ b/gcc/asan.h @@ -249,4 +249,14 @@ sanitize_flags_p (unsigned int flag, const_tree fn = current_function_decl) return result_flags; } +/* Return true when coverage sanitization should happend for FN function. */ + +static inline bool +sanitize_coverage_p (const_tree fn = current_function_decl) +{ + return (flag_sanitize_coverage + && lookup_attribute ("no_sanitize_coverage", + DECL_ATTRIBUTES (fn)) == NULL_TREE); +} + #endif /* TREE_ASAN */ diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index ccf9e4ccf0b..671b27c3200 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -62,6 +62,8 @@ static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree, int, bool *); static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int, bool *); +static tree handle_no_sanitize_coverage_attribute (tree *, tree, tree, int, + bool *); static tree handle_asan_odr_indicator_attribute (tree *, tree, tree, int, bool *); static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *); @@ -449,6 +451,8 @@ const struct attribute_spec c_common_attribute_table[] = handle_no_sanitize_thread_attribute, NULL }, { "no_sanitize_undefined", 0, 0, true, false, false, false, handle_no_sanitize_undefined_attribute, NULL }, + { "no_sanitize_coverage", 0, 0, true, false, false, false, + handle_no_sanitize_coverage_attribute, NULL }, { "asan odr indicator", 0, 0, true, false, false, false, handle_asan_odr_indicator_attribute, NULL }, { "warning", 1, 1, true, false, false, false, @@ -1211,6 +1215,22 @@ handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int, return NULL_TREE; } +/* Handle a "no_sanitize_coverage" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_no_sanitize_coverage_attribute (tree *node, tree name, tree, int, + bool *no_add_attrs) +{ + if (TREE_CODE (*node) != FUNCTION_DECL) + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + + return NULL_TREE; +} + /* Handle an "asan odr indicator" attribute; arguments as in struct attribute_spec.handler. */ diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 826804e6149..3ddeb0dee3a 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -3415,6 +3415,12 @@ The @code{no_sanitize_undefined} attribute on functions is used to inform the compiler that it should not check for undefined behavior in the function when compiling with the @option{-fsanitize=undefined} option. +@item no_sanitize_coverage +@cindex @code{no_sanitize_coverage} function attribute +The @code{no_sanitize_coverage} attribute on functions is used +to inform the compiler that it should not do coverage-guided +fuzzing code instrumentation (@option{-fsanitize-coverage}). + @item no_split_stack @cindex @code{no_split_stack} function attribute @opindex fsplit-stack diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 3be9c15e6b2..d088187a057 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -6016,7 +6016,7 @@ fold_range_test (location_t loc, enum tree_code code, tree type, logical_op_non_short_circuit = param_logical_op_non_short_circuit; if (logical_op_non_short_circuit - && !flag_sanitize_coverage + && !sanitize_coverage_p () && lhs != 0 && rhs != 0 && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR) && operand_equal_p (lhs, rhs, 0)) @@ -9652,7 +9652,7 @@ fold_truth_andor (location_t loc, enum tree_code code, tree type, logical_op_non_short_circuit = param_logical_op_non_short_circuit; if (logical_op_non_short_circuit - && !flag_sanitize_coverage + && !sanitize_coverage_p () && (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR || code == TRUTH_OR_EXPR diff --git a/gcc/sancov.c b/gcc/sancov.c index d656c37cae9..9cfbd425def 100644 --- a/gcc/sancov.c +++ b/gcc/sancov.c @@ -313,9 +313,9 @@ public: return new pass_sancov<O0> (m_ctxt); } virtual bool - gate (function *) + gate (function *fun) { - return flag_sanitize_coverage && (!O0 || !optimize); + return sanitize_coverage_p (fun->decl) && (!O0 || !optimize); } virtual unsigned int execute (function *fun) diff --git a/gcc/testsuite/gcc.dg/sancov/attribute.c b/gcc/testsuite/gcc.dg/sancov/attribute.c new file mode 100644 index 00000000000..bf6dbd4bae7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/sancov/attribute.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-fsanitize-coverage=trace-pc -fdump-tree-optimized" } */ + +void foo(void) +{ +} + +void +__attribute__((no_sanitize_coverage)) +bar(void) +{ +} + + +/* { dg-final { scan-tree-dump-times "__builtin___sanitizer_cov_trace_pc \\(\\)" 1 "optimized" } } */ diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c index 836a12d6b80..f93e04aa4df 100644 --- a/gcc/tree-ssa-ifcombine.c +++ b/gcc/tree-ssa-ifcombine.c @@ -40,6 +40,8 @@ along with GCC; see the file COPYING3. If not see #include "gimplify-me.h" #include "tree-cfg.h" #include "tree-ssa.h" +#include "attribs.h" +#include "asan.h" #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT #define LOGICAL_OP_NON_SHORT_CIRCUIT \ @@ -567,7 +569,7 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv, if (param_logical_op_non_short_circuit != -1) logical_op_non_short_circuit = param_logical_op_non_short_circuit; - if (!logical_op_non_short_circuit || flag_sanitize_coverage) + if (!logical_op_non_short_circuit || sanitize_coverage_p ()) return false; /* Only do this optimization if the inner bb contains only the conditional. */ if (!gsi_one_before_end_p (gsi_start_nondebug_after_labels_bb (inner_cond_bb))) -- 2.31.1 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Add no_sanitize_coverage attribute. 2021-05-20 8:33 [PATCH] Add no_sanitize_coverage attribute Martin Liška @ 2021-05-20 8:45 ` Marco Elver 2021-05-20 9:08 ` Martin Liška 0 siblings, 1 reply; 9+ messages in thread From: Marco Elver @ 2021-05-20 8:45 UTC (permalink / raw) To: Martin Liška; +Cc: GCC Patches, Nick Desaulniers On Thu, 20 May 2021 at 10:33, Martin Liška <mliska@suse.cz> wrote: > Hello. > > The patch implements one missing attribute which can be used for per-function > disabling of coverage sanitization. > > Patch can bootstrap on x86_64-linux-gnu and survives regression tests. Thanks for implementing this so quickly. One thing I just have to double check, is if this works with always_inline (not instrumented if inlined into no_sanitize), and inline (not inlined if inline fn is no_sanitize_coverage). Just like the other no_sanitize* do. The test doesn't mention them. Thanks, -- Marco > Ready to be installed? > Thanks, > Martin > > gcc/ChangeLog: > > * asan.h (sanitize_coverage_p): New function. > * doc/extend.texi: Document it. > * fold-const.c (fold_range_test): Use sanitize_flags_p > instead of flag_sanitize_coverage. > (fold_truth_andor): Likewise. > * sancov.c: Likewise. > * tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise. > > gcc/c-family/ChangeLog: > > * c-attribs.c (handle_no_sanitize_coverage_attribute): New. > > gcc/testsuite/ChangeLog: > > * gcc.dg/sancov/attribute.c: New test. > --- > gcc/asan.h | 10 ++++++++++ > gcc/c-family/c-attribs.c | 20 ++++++++++++++++++++ > gcc/doc/extend.texi | 6 ++++++ > gcc/fold-const.c | 4 ++-- > gcc/sancov.c | 4 ++-- > gcc/testsuite/gcc.dg/sancov/attribute.c | 15 +++++++++++++++ > gcc/tree-ssa-ifcombine.c | 4 +++- > 7 files changed, 58 insertions(+), 5 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/sancov/attribute.c > > diff --git a/gcc/asan.h b/gcc/asan.h > index f110f1db563..8c0b2baf170 100644 > --- a/gcc/asan.h > +++ b/gcc/asan.h > @@ -249,4 +249,14 @@ sanitize_flags_p (unsigned int flag, const_tree fn = current_function_decl) > return result_flags; > } > > +/* Return true when coverage sanitization should happend for FN function. */ > + > +static inline bool > +sanitize_coverage_p (const_tree fn = current_function_decl) > +{ > + return (flag_sanitize_coverage > + && lookup_attribute ("no_sanitize_coverage", > + DECL_ATTRIBUTES (fn)) == NULL_TREE); > +} > + > #endif /* TREE_ASAN */ > diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c > index ccf9e4ccf0b..671b27c3200 100644 > --- a/gcc/c-family/c-attribs.c > +++ b/gcc/c-family/c-attribs.c > @@ -62,6 +62,8 @@ static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree, > int, bool *); > static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int, > bool *); > +static tree handle_no_sanitize_coverage_attribute (tree *, tree, tree, int, > + bool *); > static tree handle_asan_odr_indicator_attribute (tree *, tree, tree, int, > bool *); > static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *); > @@ -449,6 +451,8 @@ const struct attribute_spec c_common_attribute_table[] = > handle_no_sanitize_thread_attribute, NULL }, > { "no_sanitize_undefined", 0, 0, true, false, false, false, > handle_no_sanitize_undefined_attribute, NULL }, > + { "no_sanitize_coverage", 0, 0, true, false, false, false, > + handle_no_sanitize_coverage_attribute, NULL }, > { "asan odr indicator", 0, 0, true, false, false, false, > handle_asan_odr_indicator_attribute, NULL }, > { "warning", 1, 1, true, false, false, false, > @@ -1211,6 +1215,22 @@ handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int, > return NULL_TREE; > } > > +/* Handle a "no_sanitize_coverage" attribute; arguments as in > + struct attribute_spec.handler. */ > + > +static tree > +handle_no_sanitize_coverage_attribute (tree *node, tree name, tree, int, > + bool *no_add_attrs) > +{ > + if (TREE_CODE (*node) != FUNCTION_DECL) > + { > + warning (OPT_Wattributes, "%qE attribute ignored", name); > + *no_add_attrs = true; > + } > + > + return NULL_TREE; > +} > + > /* Handle an "asan odr indicator" attribute; arguments as in > struct attribute_spec.handler. */ > > diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi > index 826804e6149..3ddeb0dee3a 100644 > --- a/gcc/doc/extend.texi > +++ b/gcc/doc/extend.texi > @@ -3415,6 +3415,12 @@ The @code{no_sanitize_undefined} attribute on functions is used > to inform the compiler that it should not check for undefined behavior > in the function when compiling with the @option{-fsanitize=undefined} option. > > +@item no_sanitize_coverage > +@cindex @code{no_sanitize_coverage} function attribute > +The @code{no_sanitize_coverage} attribute on functions is used > +to inform the compiler that it should not do coverage-guided > +fuzzing code instrumentation (@option{-fsanitize-coverage}). > + > @item no_split_stack > @cindex @code{no_split_stack} function attribute > @opindex fsplit-stack > diff --git a/gcc/fold-const.c b/gcc/fold-const.c > index 3be9c15e6b2..d088187a057 100644 > --- a/gcc/fold-const.c > +++ b/gcc/fold-const.c > @@ -6016,7 +6016,7 @@ fold_range_test (location_t loc, enum tree_code code, tree type, > logical_op_non_short_circuit > = param_logical_op_non_short_circuit; > if (logical_op_non_short_circuit > - && !flag_sanitize_coverage > + && !sanitize_coverage_p () > && lhs != 0 && rhs != 0 > && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR) > && operand_equal_p (lhs, rhs, 0)) > @@ -9652,7 +9652,7 @@ fold_truth_andor (location_t loc, enum tree_code code, tree type, > logical_op_non_short_circuit > = param_logical_op_non_short_circuit; > if (logical_op_non_short_circuit > - && !flag_sanitize_coverage > + && !sanitize_coverage_p () > && (code == TRUTH_AND_EXPR > || code == TRUTH_ANDIF_EXPR > || code == TRUTH_OR_EXPR > diff --git a/gcc/sancov.c b/gcc/sancov.c > index d656c37cae9..9cfbd425def 100644 > --- a/gcc/sancov.c > +++ b/gcc/sancov.c > @@ -313,9 +313,9 @@ public: > return new pass_sancov<O0> (m_ctxt); > } > virtual bool > - gate (function *) > + gate (function *fun) > { > - return flag_sanitize_coverage && (!O0 || !optimize); > + return sanitize_coverage_p (fun->decl) && (!O0 || !optimize); > } > virtual unsigned int > execute (function *fun) > diff --git a/gcc/testsuite/gcc.dg/sancov/attribute.c b/gcc/testsuite/gcc.dg/sancov/attribute.c > new file mode 100644 > index 00000000000..bf6dbd4bae7 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/sancov/attribute.c > @@ -0,0 +1,15 @@ > +/* { dg-do compile } */ > +/* { dg-options "-fsanitize-coverage=trace-pc -fdump-tree-optimized" } */ > + > +void foo(void) > +{ > +} > + > +void > +__attribute__((no_sanitize_coverage)) > +bar(void) > +{ > +} > + > + > +/* { dg-final { scan-tree-dump-times "__builtin___sanitizer_cov_trace_pc \\(\\)" 1 "optimized" } } */ > diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c > index 836a12d6b80..f93e04aa4df 100644 > --- a/gcc/tree-ssa-ifcombine.c > +++ b/gcc/tree-ssa-ifcombine.c > @@ -40,6 +40,8 @@ along with GCC; see the file COPYING3. If not see > #include "gimplify-me.h" > #include "tree-cfg.h" > #include "tree-ssa.h" > +#include "attribs.h" > +#include "asan.h" > > #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT > #define LOGICAL_OP_NON_SHORT_CIRCUIT \ > @@ -567,7 +569,7 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv, > if (param_logical_op_non_short_circuit != -1) > logical_op_non_short_circuit > = param_logical_op_non_short_circuit; > - if (!logical_op_non_short_circuit || flag_sanitize_coverage) > + if (!logical_op_non_short_circuit || sanitize_coverage_p ()) > return false; > /* Only do this optimization if the inner bb contains only the conditional. */ > if (!gsi_one_before_end_p (gsi_start_nondebug_after_labels_bb (inner_cond_bb))) > -- > 2.31.1 > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Add no_sanitize_coverage attribute. 2021-05-20 8:45 ` Marco Elver @ 2021-05-20 9:08 ` Martin Liška 2021-05-20 10:55 ` Marco Elver 0 siblings, 1 reply; 9+ messages in thread From: Martin Liška @ 2021-05-20 9:08 UTC (permalink / raw) To: Marco Elver; +Cc: GCC Patches, Nick Desaulniers On 5/20/21 10:45 AM, Marco Elver wrote: > On Thu, 20 May 2021 at 10:33, Martin Liška <mliska@suse.cz> wrote: >> Hello. >> >> The patch implements one missing attribute which can be used for per-function >> disabling of coverage sanitization. >> >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > > Thanks for implementing this so quickly. One thing I just have to > double check, is if this works with always_inline (not instrumented if > inlined into no_sanitize), No, in this case it's instrumented (if caller has not set the attribute). > and inline (not inlined if inline fn is > no_sanitize_coverage). No again, it's not blocking inlining. > Just like the other no_sanitize* do. The test doesn't mention them. It's aligned with similar issue that was discussed some time ago: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94722#c9 Martin > > Thanks, > -- Marco > >> Ready to be installed? >> Thanks, >> Martin >> >> gcc/ChangeLog: >> >> * asan.h (sanitize_coverage_p): New function. >> * doc/extend.texi: Document it. >> * fold-const.c (fold_range_test): Use sanitize_flags_p >> instead of flag_sanitize_coverage. >> (fold_truth_andor): Likewise. >> * sancov.c: Likewise. >> * tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise. >> >> gcc/c-family/ChangeLog: >> >> * c-attribs.c (handle_no_sanitize_coverage_attribute): New. >> >> gcc/testsuite/ChangeLog: >> >> * gcc.dg/sancov/attribute.c: New test. >> --- >> gcc/asan.h | 10 ++++++++++ >> gcc/c-family/c-attribs.c | 20 ++++++++++++++++++++ >> gcc/doc/extend.texi | 6 ++++++ >> gcc/fold-const.c | 4 ++-- >> gcc/sancov.c | 4 ++-- >> gcc/testsuite/gcc.dg/sancov/attribute.c | 15 +++++++++++++++ >> gcc/tree-ssa-ifcombine.c | 4 +++- >> 7 files changed, 58 insertions(+), 5 deletions(-) >> create mode 100644 gcc/testsuite/gcc.dg/sancov/attribute.c >> >> diff --git a/gcc/asan.h b/gcc/asan.h >> index f110f1db563..8c0b2baf170 100644 >> --- a/gcc/asan.h >> +++ b/gcc/asan.h >> @@ -249,4 +249,14 @@ sanitize_flags_p (unsigned int flag, const_tree fn = current_function_decl) >> return result_flags; >> } >> >> +/* Return true when coverage sanitization should happend for FN function. */ >> + >> +static inline bool >> +sanitize_coverage_p (const_tree fn = current_function_decl) >> +{ >> + return (flag_sanitize_coverage >> + && lookup_attribute ("no_sanitize_coverage", >> + DECL_ATTRIBUTES (fn)) == NULL_TREE); >> +} >> + >> #endif /* TREE_ASAN */ >> diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c >> index ccf9e4ccf0b..671b27c3200 100644 >> --- a/gcc/c-family/c-attribs.c >> +++ b/gcc/c-family/c-attribs.c >> @@ -62,6 +62,8 @@ static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree, >> int, bool *); >> static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int, >> bool *); >> +static tree handle_no_sanitize_coverage_attribute (tree *, tree, tree, int, >> + bool *); >> static tree handle_asan_odr_indicator_attribute (tree *, tree, tree, int, >> bool *); >> static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *); >> @@ -449,6 +451,8 @@ const struct attribute_spec c_common_attribute_table[] = >> handle_no_sanitize_thread_attribute, NULL }, >> { "no_sanitize_undefined", 0, 0, true, false, false, false, >> handle_no_sanitize_undefined_attribute, NULL }, >> + { "no_sanitize_coverage", 0, 0, true, false, false, false, >> + handle_no_sanitize_coverage_attribute, NULL }, >> { "asan odr indicator", 0, 0, true, false, false, false, >> handle_asan_odr_indicator_attribute, NULL }, >> { "warning", 1, 1, true, false, false, false, >> @@ -1211,6 +1215,22 @@ handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int, >> return NULL_TREE; >> } >> >> +/* Handle a "no_sanitize_coverage" attribute; arguments as in >> + struct attribute_spec.handler. */ >> + >> +static tree >> +handle_no_sanitize_coverage_attribute (tree *node, tree name, tree, int, >> + bool *no_add_attrs) >> +{ >> + if (TREE_CODE (*node) != FUNCTION_DECL) >> + { >> + warning (OPT_Wattributes, "%qE attribute ignored", name); >> + *no_add_attrs = true; >> + } >> + >> + return NULL_TREE; >> +} >> + >> /* Handle an "asan odr indicator" attribute; arguments as in >> struct attribute_spec.handler. */ >> >> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi >> index 826804e6149..3ddeb0dee3a 100644 >> --- a/gcc/doc/extend.texi >> +++ b/gcc/doc/extend.texi >> @@ -3415,6 +3415,12 @@ The @code{no_sanitize_undefined} attribute on functions is used >> to inform the compiler that it should not check for undefined behavior >> in the function when compiling with the @option{-fsanitize=undefined} option. >> >> +@item no_sanitize_coverage >> +@cindex @code{no_sanitize_coverage} function attribute >> +The @code{no_sanitize_coverage} attribute on functions is used >> +to inform the compiler that it should not do coverage-guided >> +fuzzing code instrumentation (@option{-fsanitize-coverage}). >> + >> @item no_split_stack >> @cindex @code{no_split_stack} function attribute >> @opindex fsplit-stack >> diff --git a/gcc/fold-const.c b/gcc/fold-const.c >> index 3be9c15e6b2..d088187a057 100644 >> --- a/gcc/fold-const.c >> +++ b/gcc/fold-const.c >> @@ -6016,7 +6016,7 @@ fold_range_test (location_t loc, enum tree_code code, tree type, >> logical_op_non_short_circuit >> = param_logical_op_non_short_circuit; >> if (logical_op_non_short_circuit >> - && !flag_sanitize_coverage >> + && !sanitize_coverage_p () >> && lhs != 0 && rhs != 0 >> && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR) >> && operand_equal_p (lhs, rhs, 0)) >> @@ -9652,7 +9652,7 @@ fold_truth_andor (location_t loc, enum tree_code code, tree type, >> logical_op_non_short_circuit >> = param_logical_op_non_short_circuit; >> if (logical_op_non_short_circuit >> - && !flag_sanitize_coverage >> + && !sanitize_coverage_p () >> && (code == TRUTH_AND_EXPR >> || code == TRUTH_ANDIF_EXPR >> || code == TRUTH_OR_EXPR >> diff --git a/gcc/sancov.c b/gcc/sancov.c >> index d656c37cae9..9cfbd425def 100644 >> --- a/gcc/sancov.c >> +++ b/gcc/sancov.c >> @@ -313,9 +313,9 @@ public: >> return new pass_sancov<O0> (m_ctxt); >> } >> virtual bool >> - gate (function *) >> + gate (function *fun) >> { >> - return flag_sanitize_coverage && (!O0 || !optimize); >> + return sanitize_coverage_p (fun->decl) && (!O0 || !optimize); >> } >> virtual unsigned int >> execute (function *fun) >> diff --git a/gcc/testsuite/gcc.dg/sancov/attribute.c b/gcc/testsuite/gcc.dg/sancov/attribute.c >> new file mode 100644 >> index 00000000000..bf6dbd4bae7 >> --- /dev/null >> +++ b/gcc/testsuite/gcc.dg/sancov/attribute.c >> @@ -0,0 +1,15 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-fsanitize-coverage=trace-pc -fdump-tree-optimized" } */ >> + >> +void foo(void) >> +{ >> +} >> + >> +void >> +__attribute__((no_sanitize_coverage)) >> +bar(void) >> +{ >> +} >> + >> + >> +/* { dg-final { scan-tree-dump-times "__builtin___sanitizer_cov_trace_pc \\(\\)" 1 "optimized" } } */ >> diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c >> index 836a12d6b80..f93e04aa4df 100644 >> --- a/gcc/tree-ssa-ifcombine.c >> +++ b/gcc/tree-ssa-ifcombine.c >> @@ -40,6 +40,8 @@ along with GCC; see the file COPYING3. If not see >> #include "gimplify-me.h" >> #include "tree-cfg.h" >> #include "tree-ssa.h" >> +#include "attribs.h" >> +#include "asan.h" >> >> #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT >> #define LOGICAL_OP_NON_SHORT_CIRCUIT \ >> @@ -567,7 +569,7 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv, >> if (param_logical_op_non_short_circuit != -1) >> logical_op_non_short_circuit >> = param_logical_op_non_short_circuit; >> - if (!logical_op_non_short_circuit || flag_sanitize_coverage) >> + if (!logical_op_non_short_circuit || sanitize_coverage_p ()) >> return false; >> /* Only do this optimization if the inner bb contains only the conditional. */ >> if (!gsi_one_before_end_p (gsi_start_nondebug_after_labels_bb (inner_cond_bb))) >> -- >> 2.31.1 >> ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Add no_sanitize_coverage attribute. 2021-05-20 9:08 ` Martin Liška @ 2021-05-20 10:55 ` Marco Elver 2021-05-21 8:50 ` Martin Liška 0 siblings, 1 reply; 9+ messages in thread From: Marco Elver @ 2021-05-20 10:55 UTC (permalink / raw) To: Martin Liška; +Cc: GCC Patches, Nick Desaulniers On Thu, 20 May 2021 at 11:08, Martin Liška <mliska@suse.cz> wrote: > On 5/20/21 10:45 AM, Marco Elver wrote: > > On Thu, 20 May 2021 at 10:33, Martin Liška <mliska@suse.cz> wrote: > >> Hello. > >> > >> The patch implements one missing attribute which can be used for per-function > >> disabling of coverage sanitization. > >> > >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > > > > Thanks for implementing this so quickly. One thing I just have to > > double check, is if this works with always_inline (not instrumented if > > inlined into no_sanitize), > > No, in this case it's instrumented (if caller has not set the attribute). This one I'm not sure of, because in too many places, we assume always_inline behaves like a macro (see below). > > and inline (not inlined if inline fn is > > no_sanitize_coverage). > > No again, it's not blocking inlining. I think that's fine, as long as the inlined code is still instrumented according to the attribute (which I think is the case based on what you say above). I think this came up with other no_sanitize [1] based on what I had written to you last year [2]. [1] https://gcc.gnu.org/pipermail/gcc-patches/2020-June/547618.html [2] https://lore.kernel.org/lkml/CANpmjNNRz5OVKb6PE7K6GjfoGbht_ZhyPkNG9aD+KjNDzK7hGg@mail.gmail.com/ > > Just like the other no_sanitize* do. The test doesn't mention them. > > It's aligned with similar issue that was discussed some time ago: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94722#c9 That's fair, but keep in mind all -fsanitize are not for use in production, unlike stack protector. no_sanitize_coverage needs to be aligned with the behavior of other existing no_sanitize*. Of course, whether to inline or not I don't mind, as long as no_sanitize means the code is never instrumented as discussed in [2]. AFAIK, it just so happens that to achieve that for the other sanitizers, the easiest option was to not inline "inline no_sanitize*" functions. But always_inline needs to behave in line with other no_sanitize*, i.e. if inlined into no_sanitize_coverage, never instrument: https://lore.kernel.org/lkml/CANpmjNMTsY_8241bS7=XAfqvZHFLrVEkv_uM4aDUWE_kh3Rvbw@mail.gmail.com/ This is also what Clang will do for no_sanitize_coverage. Thanks, -- Marco > Martin > > > > > Thanks, > > -- Marco > > > >> Ready to be installed? > >> Thanks, > >> Martin > >> > >> gcc/ChangeLog: > >> > >> * asan.h (sanitize_coverage_p): New function. > >> * doc/extend.texi: Document it. > >> * fold-const.c (fold_range_test): Use sanitize_flags_p > >> instead of flag_sanitize_coverage. > >> (fold_truth_andor): Likewise. > >> * sancov.c: Likewise. > >> * tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise. > >> > >> gcc/c-family/ChangeLog: > >> > >> * c-attribs.c (handle_no_sanitize_coverage_attribute): New. > >> > >> gcc/testsuite/ChangeLog: > >> > >> * gcc.dg/sancov/attribute.c: New test. > >> --- > >> gcc/asan.h | 10 ++++++++++ > >> gcc/c-family/c-attribs.c | 20 ++++++++++++++++++++ > >> gcc/doc/extend.texi | 6 ++++++ > >> gcc/fold-const.c | 4 ++-- > >> gcc/sancov.c | 4 ++-- > >> gcc/testsuite/gcc.dg/sancov/attribute.c | 15 +++++++++++++++ > >> gcc/tree-ssa-ifcombine.c | 4 +++- > >> 7 files changed, 58 insertions(+), 5 deletions(-) > >> create mode 100644 gcc/testsuite/gcc.dg/sancov/attribute.c > >> > >> diff --git a/gcc/asan.h b/gcc/asan.h > >> index f110f1db563..8c0b2baf170 100644 > >> --- a/gcc/asan.h > >> +++ b/gcc/asan.h > >> @@ -249,4 +249,14 @@ sanitize_flags_p (unsigned int flag, const_tree fn = current_function_decl) > >> return result_flags; > >> } > >> > >> +/* Return true when coverage sanitization should happend for FN function. */ > >> + > >> +static inline bool > >> +sanitize_coverage_p (const_tree fn = current_function_decl) > >> +{ > >> + return (flag_sanitize_coverage > >> + && lookup_attribute ("no_sanitize_coverage", > >> + DECL_ATTRIBUTES (fn)) == NULL_TREE); > >> +} > >> + > >> #endif /* TREE_ASAN */ > >> diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c > >> index ccf9e4ccf0b..671b27c3200 100644 > >> --- a/gcc/c-family/c-attribs.c > >> +++ b/gcc/c-family/c-attribs.c > >> @@ -62,6 +62,8 @@ static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree, > >> int, bool *); > >> static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int, > >> bool *); > >> +static tree handle_no_sanitize_coverage_attribute (tree *, tree, tree, int, > >> + bool *); > >> static tree handle_asan_odr_indicator_attribute (tree *, tree, tree, int, > >> bool *); > >> static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *); > >> @@ -449,6 +451,8 @@ const struct attribute_spec c_common_attribute_table[] = > >> handle_no_sanitize_thread_attribute, NULL }, > >> { "no_sanitize_undefined", 0, 0, true, false, false, false, > >> handle_no_sanitize_undefined_attribute, NULL }, > >> + { "no_sanitize_coverage", 0, 0, true, false, false, false, > >> + handle_no_sanitize_coverage_attribute, NULL }, > >> { "asan odr indicator", 0, 0, true, false, false, false, > >> handle_asan_odr_indicator_attribute, NULL }, > >> { "warning", 1, 1, true, false, false, false, > >> @@ -1211,6 +1215,22 @@ handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int, > >> return NULL_TREE; > >> } > >> > >> +/* Handle a "no_sanitize_coverage" attribute; arguments as in > >> + struct attribute_spec.handler. */ > >> + > >> +static tree > >> +handle_no_sanitize_coverage_attribute (tree *node, tree name, tree, int, > >> + bool *no_add_attrs) > >> +{ > >> + if (TREE_CODE (*node) != FUNCTION_DECL) > >> + { > >> + warning (OPT_Wattributes, "%qE attribute ignored", name); > >> + *no_add_attrs = true; > >> + } > >> + > >> + return NULL_TREE; > >> +} > >> + > >> /* Handle an "asan odr indicator" attribute; arguments as in > >> struct attribute_spec.handler. */ > >> > >> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi > >> index 826804e6149..3ddeb0dee3a 100644 > >> --- a/gcc/doc/extend.texi > >> +++ b/gcc/doc/extend.texi > >> @@ -3415,6 +3415,12 @@ The @code{no_sanitize_undefined} attribute on functions is used > >> to inform the compiler that it should not check for undefined behavior > >> in the function when compiling with the @option{-fsanitize=undefined} option. > >> > >> +@item no_sanitize_coverage > >> +@cindex @code{no_sanitize_coverage} function attribute > >> +The @code{no_sanitize_coverage} attribute on functions is used > >> +to inform the compiler that it should not do coverage-guided > >> +fuzzing code instrumentation (@option{-fsanitize-coverage}). > >> + > >> @item no_split_stack > >> @cindex @code{no_split_stack} function attribute > >> @opindex fsplit-stack > >> diff --git a/gcc/fold-const.c b/gcc/fold-const.c > >> index 3be9c15e6b2..d088187a057 100644 > >> --- a/gcc/fold-const.c > >> +++ b/gcc/fold-const.c > >> @@ -6016,7 +6016,7 @@ fold_range_test (location_t loc, enum tree_code code, tree type, > >> logical_op_non_short_circuit > >> = param_logical_op_non_short_circuit; > >> if (logical_op_non_short_circuit > >> - && !flag_sanitize_coverage > >> + && !sanitize_coverage_p () > >> && lhs != 0 && rhs != 0 > >> && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR) > >> && operand_equal_p (lhs, rhs, 0)) > >> @@ -9652,7 +9652,7 @@ fold_truth_andor (location_t loc, enum tree_code code, tree type, > >> logical_op_non_short_circuit > >> = param_logical_op_non_short_circuit; > >> if (logical_op_non_short_circuit > >> - && !flag_sanitize_coverage > >> + && !sanitize_coverage_p () > >> && (code == TRUTH_AND_EXPR > >> || code == TRUTH_ANDIF_EXPR > >> || code == TRUTH_OR_EXPR > >> diff --git a/gcc/sancov.c b/gcc/sancov.c > >> index d656c37cae9..9cfbd425def 100644 > >> --- a/gcc/sancov.c > >> +++ b/gcc/sancov.c > >> @@ -313,9 +313,9 @@ public: > >> return new pass_sancov<O0> (m_ctxt); > >> } > >> virtual bool > >> - gate (function *) > >> + gate (function *fun) > >> { > >> - return flag_sanitize_coverage && (!O0 || !optimize); > >> + return sanitize_coverage_p (fun->decl) && (!O0 || !optimize); > >> } > >> virtual unsigned int > >> execute (function *fun) > >> diff --git a/gcc/testsuite/gcc.dg/sancov/attribute.c b/gcc/testsuite/gcc.dg/sancov/attribute.c > >> new file mode 100644 > >> index 00000000000..bf6dbd4bae7 > >> --- /dev/null > >> +++ b/gcc/testsuite/gcc.dg/sancov/attribute.c > >> @@ -0,0 +1,15 @@ > >> +/* { dg-do compile } */ > >> +/* { dg-options "-fsanitize-coverage=trace-pc -fdump-tree-optimized" } */ > >> + > >> +void foo(void) > >> +{ > >> +} > >> + > >> +void > >> +__attribute__((no_sanitize_coverage)) > >> +bar(void) > >> +{ > >> +} > >> + > >> + > >> +/* { dg-final { scan-tree-dump-times "__builtin___sanitizer_cov_trace_pc \\(\\)" 1 "optimized" } } */ > >> diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c > >> index 836a12d6b80..f93e04aa4df 100644 > >> --- a/gcc/tree-ssa-ifcombine.c > >> +++ b/gcc/tree-ssa-ifcombine.c > >> @@ -40,6 +40,8 @@ along with GCC; see the file COPYING3. If not see > >> #include "gimplify-me.h" > >> #include "tree-cfg.h" > >> #include "tree-ssa.h" > >> +#include "attribs.h" > >> +#include "asan.h" > >> > >> #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT > >> #define LOGICAL_OP_NON_SHORT_CIRCUIT \ > >> @@ -567,7 +569,7 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv, > >> if (param_logical_op_non_short_circuit != -1) > >> logical_op_non_short_circuit > >> = param_logical_op_non_short_circuit; > >> - if (!logical_op_non_short_circuit || flag_sanitize_coverage) > >> + if (!logical_op_non_short_circuit || sanitize_coverage_p ()) > >> return false; > >> /* Only do this optimization if the inner bb contains only the conditional. */ > >> if (!gsi_one_before_end_p (gsi_start_nondebug_after_labels_bb (inner_cond_bb))) > >> -- > >> 2.31.1 > >> > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Add no_sanitize_coverage attribute. 2021-05-20 10:55 ` Marco Elver @ 2021-05-21 8:50 ` Martin Liška 2021-05-21 12:39 ` Marco Elver 0 siblings, 1 reply; 9+ messages in thread From: Martin Liška @ 2021-05-21 8:50 UTC (permalink / raw) To: Marco Elver; +Cc: GCC Patches, Nick Desaulniers [-- Attachment #1: Type: text/plain, Size: 491 bytes --] On 5/20/21 12:55 PM, Marco Elver wrote: > I think this came up with other no_sanitize [1] based on what I had > written to you last year [2]. > > [1]https://gcc.gnu.org/pipermail/gcc-patches/2020-June/547618.html > [2]https://lore.kernel.org/lkml/CANpmjNNRz5OVKb6PE7K6GjfoGbht_ZhyPkNG9aD+KjNDzK7hGg@mail.gmail.com/ Ah, you're right. I've just updated the patch to address that. Patch can bootstrap on x86_64-linux-gnu and survives regression tests. Ready to be installed? Thanks, Martin [-- Attachment #2: 0001-Add-no_sanitize_coverage-attribute.patch --] [-- Type: text/x-patch, Size: 7696 bytes --] From b7f9f6c9722e7cb1b81b96ec646cadb5706b1038 Mon Sep 17 00:00:00 2001 From: Martin Liska <mliska@suse.cz> Date: Thu, 20 May 2021 09:32:29 +0200 Subject: [PATCH] Add no_sanitize_coverage attribute. gcc/ChangeLog: * asan.h (sanitize_coverage_p): New function. * doc/extend.texi: Document it. * fold-const.c (fold_range_test): Use sanitize_flags_p instead of flag_sanitize_coverage. (fold_truth_andor): Likewise. * sancov.c: Likewise. * tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise. * ipa-inline.c (sanitize_attrs_match_for_inline_p): Handle -fsanitize-coverage when inlining. gcc/c-family/ChangeLog: * c-attribs.c (handle_no_sanitize_coverage_attribute): New. gcc/testsuite/ChangeLog: * gcc.dg/sancov/attribute.c: New test. --- gcc/asan.h | 10 ++++++++++ gcc/c-family/c-attribs.c | 20 ++++++++++++++++++++ gcc/doc/extend.texi | 6 ++++++ gcc/fold-const.c | 4 ++-- gcc/ipa-inline.c | 3 +++ gcc/sancov.c | 4 ++-- gcc/testsuite/gcc.dg/sancov/attribute.c | 15 +++++++++++++++ gcc/tree-ssa-ifcombine.c | 4 +++- 8 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/sancov/attribute.c diff --git a/gcc/asan.h b/gcc/asan.h index f110f1db563..8c0b2baf170 100644 --- a/gcc/asan.h +++ b/gcc/asan.h @@ -249,4 +249,14 @@ sanitize_flags_p (unsigned int flag, const_tree fn = current_function_decl) return result_flags; } +/* Return true when coverage sanitization should happend for FN function. */ + +static inline bool +sanitize_coverage_p (const_tree fn = current_function_decl) +{ + return (flag_sanitize_coverage + && lookup_attribute ("no_sanitize_coverage", + DECL_ATTRIBUTES (fn)) == NULL_TREE); +} + #endif /* TREE_ASAN */ diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index ccf9e4ccf0b..671b27c3200 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -62,6 +62,8 @@ static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree, int, bool *); static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int, bool *); +static tree handle_no_sanitize_coverage_attribute (tree *, tree, tree, int, + bool *); static tree handle_asan_odr_indicator_attribute (tree *, tree, tree, int, bool *); static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *); @@ -449,6 +451,8 @@ const struct attribute_spec c_common_attribute_table[] = handle_no_sanitize_thread_attribute, NULL }, { "no_sanitize_undefined", 0, 0, true, false, false, false, handle_no_sanitize_undefined_attribute, NULL }, + { "no_sanitize_coverage", 0, 0, true, false, false, false, + handle_no_sanitize_coverage_attribute, NULL }, { "asan odr indicator", 0, 0, true, false, false, false, handle_asan_odr_indicator_attribute, NULL }, { "warning", 1, 1, true, false, false, false, @@ -1211,6 +1215,22 @@ handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int, return NULL_TREE; } +/* Handle a "no_sanitize_coverage" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_no_sanitize_coverage_attribute (tree *node, tree name, tree, int, + bool *no_add_attrs) +{ + if (TREE_CODE (*node) != FUNCTION_DECL) + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + + return NULL_TREE; +} + /* Handle an "asan odr indicator" attribute; arguments as in struct attribute_spec.handler. */ diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 826804e6149..3ddeb0dee3a 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -3415,6 +3415,12 @@ The @code{no_sanitize_undefined} attribute on functions is used to inform the compiler that it should not check for undefined behavior in the function when compiling with the @option{-fsanitize=undefined} option. +@item no_sanitize_coverage +@cindex @code{no_sanitize_coverage} function attribute +The @code{no_sanitize_coverage} attribute on functions is used +to inform the compiler that it should not do coverage-guided +fuzzing code instrumentation (@option{-fsanitize-coverage}). + @item no_split_stack @cindex @code{no_split_stack} function attribute @opindex fsplit-stack diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 3be9c15e6b2..d088187a057 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -6016,7 +6016,7 @@ fold_range_test (location_t loc, enum tree_code code, tree type, logical_op_non_short_circuit = param_logical_op_non_short_circuit; if (logical_op_non_short_circuit - && !flag_sanitize_coverage + && !sanitize_coverage_p () && lhs != 0 && rhs != 0 && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR) && operand_equal_p (lhs, rhs, 0)) @@ -9652,7 +9652,7 @@ fold_truth_andor (location_t loc, enum tree_code code, tree type, logical_op_non_short_circuit = param_logical_op_non_short_circuit; if (logical_op_non_short_circuit - && !flag_sanitize_coverage + && !sanitize_coverage_p () && (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR || code == TRUTH_OR_EXPR diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index f15c4828958..9d896beb2ac 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -283,6 +283,9 @@ sanitize_attrs_match_for_inline_p (const_tree caller, const_tree callee) != sanitize_flags_p (codes[i], callee)) return false; + if (sanitize_coverage_p (caller) != sanitize_coverage_p (callee)) + return false; + return true; } diff --git a/gcc/sancov.c b/gcc/sancov.c index d656c37cae9..9cfbd425def 100644 --- a/gcc/sancov.c +++ b/gcc/sancov.c @@ -313,9 +313,9 @@ public: return new pass_sancov<O0> (m_ctxt); } virtual bool - gate (function *) + gate (function *fun) { - return flag_sanitize_coverage && (!O0 || !optimize); + return sanitize_coverage_p (fun->decl) && (!O0 || !optimize); } virtual unsigned int execute (function *fun) diff --git a/gcc/testsuite/gcc.dg/sancov/attribute.c b/gcc/testsuite/gcc.dg/sancov/attribute.c new file mode 100644 index 00000000000..bf6dbd4bae7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/sancov/attribute.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-fsanitize-coverage=trace-pc -fdump-tree-optimized" } */ + +void foo(void) +{ +} + +void +__attribute__((no_sanitize_coverage)) +bar(void) +{ +} + + +/* { dg-final { scan-tree-dump-times "__builtin___sanitizer_cov_trace_pc \\(\\)" 1 "optimized" } } */ diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c index 836a12d6b80..f93e04aa4df 100644 --- a/gcc/tree-ssa-ifcombine.c +++ b/gcc/tree-ssa-ifcombine.c @@ -40,6 +40,8 @@ along with GCC; see the file COPYING3. If not see #include "gimplify-me.h" #include "tree-cfg.h" #include "tree-ssa.h" +#include "attribs.h" +#include "asan.h" #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT #define LOGICAL_OP_NON_SHORT_CIRCUIT \ @@ -567,7 +569,7 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv, if (param_logical_op_non_short_circuit != -1) logical_op_non_short_circuit = param_logical_op_non_short_circuit; - if (!logical_op_non_short_circuit || flag_sanitize_coverage) + if (!logical_op_non_short_circuit || sanitize_coverage_p ()) return false; /* Only do this optimization if the inner bb contains only the conditional. */ if (!gsi_one_before_end_p (gsi_start_nondebug_after_labels_bb (inner_cond_bb))) -- 2.31.1 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Add no_sanitize_coverage attribute. 2021-05-21 8:50 ` Martin Liška @ 2021-05-21 12:39 ` Marco Elver 2021-05-24 8:03 ` Martin Liška 0 siblings, 1 reply; 9+ messages in thread From: Marco Elver @ 2021-05-21 12:39 UTC (permalink / raw) To: Martin Liška; +Cc: GCC Patches, Nick Desaulniers On Fri, May 21, 2021 at 10:50AM +0200, Martin Liška wrote: > On 5/20/21 12:55 PM, Marco Elver wrote: > > I think this came up with other no_sanitize [1] based on what I had > > written to you last year [2]. > > > > [1]https://gcc.gnu.org/pipermail/gcc-patches/2020-June/547618.html > > [2]https://lore.kernel.org/lkml/CANpmjNNRz5OVKb6PE7K6GjfoGbht_ZhyPkNG9aD+KjNDzK7hGg@mail.gmail.com/ > > Ah, you're right. I've just updated the patch to address that. > > Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > > Ready to be installed? Looks good, I also just built a kernel with the no_sanitize_coverage attribute (without the objtool nop-workaround) and works as expected. Not sure if required, but would such an additional test be useful: --- diff --git a/gcc/testsuite/gcc.dg/sancov/attribute.c b/gcc/testsuite/gcc.dg/sancov/attribute.c index bf6dbd4bae7..7cfa9134ff1 100644 --- a/gcc/testsuite/gcc.dg/sancov/attribute.c +++ b/gcc/testsuite/gcc.dg/sancov/attribute.c @@ -11,5 +11,17 @@ bar(void) { } +static void inline +__attribute__((always_inline)) +inline_fn(void) +{ +} + +void +__attribute__((no_sanitize_coverage)) +baz(void) +{ + inline_fn(); +} /* { dg-final { scan-tree-dump-times "__builtin___sanitizer_cov_trace_pc \\(\\)" 1 "optimized" } } */ --- Otherwise, please go ahead. I assume this is targeting GCC 12? Thanks, -- Marco ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Add no_sanitize_coverage attribute. 2021-05-21 12:39 ` Marco Elver @ 2021-05-24 8:03 ` Martin Liška 2021-05-24 8:07 ` Marco Elver 2021-05-25 9:55 ` Richard Biener 0 siblings, 2 replies; 9+ messages in thread From: Martin Liška @ 2021-05-24 8:03 UTC (permalink / raw) To: Marco Elver; +Cc: GCC Patches, Nick Desaulniers [-- Attachment #1: Type: text/plain, Size: 1621 bytes --] On 5/21/21 2:39 PM, Marco Elver wrote: > On Fri, May 21, 2021 at 10:50AM +0200, Martin Liška wrote: >> On 5/20/21 12:55 PM, Marco Elver wrote: >>> I think this came up with other no_sanitize [1] based on what I had >>> written to you last year [2]. >>> >>> [1]https://gcc.gnu.org/pipermail/gcc-patches/2020-June/547618.html >>> [2]https://lore.kernel.org/lkml/CANpmjNNRz5OVKb6PE7K6GjfoGbht_ZhyPkNG9aD+KjNDzK7hGg@mail.gmail.com/ >> >> Ah, you're right. I've just updated the patch to address that. >> >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests. >> >> Ready to be installed? > > Looks good, I also just built a kernel with the no_sanitize_coverage > attribute (without the objtool nop-workaround) and works as expected. Good, thanks! > > Not sure if required, but would such an additional test be useful: Yes, it is, thanks for it. > > --- > > diff --git a/gcc/testsuite/gcc.dg/sancov/attribute.c b/gcc/testsuite/gcc.dg/sancov/attribute.c > index bf6dbd4bae7..7cfa9134ff1 100644 > --- a/gcc/testsuite/gcc.dg/sancov/attribute.c > +++ b/gcc/testsuite/gcc.dg/sancov/attribute.c > @@ -11,5 +11,17 @@ bar(void) > { > } > > +static void inline > +__attribute__((always_inline)) > +inline_fn(void) > +{ > +} > + > +void > +__attribute__((no_sanitize_coverage)) > +baz(void) > +{ > + inline_fn(); > +} > > /* { dg-final { scan-tree-dump-times "__builtin___sanitizer_cov_trace_pc \\(\\)" 1 "optimized" } } */ > > --- > > Otherwise, please go ahead. I assume this is targeting GCC 12? Yep. There's V3 I'm sending. Ready for master? Thanks, Martin > > Thanks, > -- Marco > [-- Attachment #2: 0001-Add-no_sanitize_coverage-attribute.patch --] [-- Type: text/x-patch, Size: 7858 bytes --] From 15053b32a870cd62641ad62a9e76a78558489f4a Mon Sep 17 00:00:00 2001 From: Martin Liska <mliska@suse.cz> Date: Thu, 20 May 2021 09:32:29 +0200 Subject: [PATCH] Add no_sanitize_coverage attribute. gcc/ChangeLog: * asan.h (sanitize_coverage_p): New function. * doc/extend.texi: Document it. * fold-const.c (fold_range_test): Use sanitize_flags_p instead of flag_sanitize_coverage. (fold_truth_andor): Likewise. * sancov.c: Likewise. * tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise. * ipa-inline.c (sanitize_attrs_match_for_inline_p): Handle -fsanitize-coverage when inlining. gcc/c-family/ChangeLog: * c-attribs.c (handle_no_sanitize_coverage_attribute): New. gcc/testsuite/ChangeLog: * gcc.dg/sancov/attribute.c: New test. --- gcc/asan.h | 10 +++++++++ gcc/c-family/c-attribs.c | 20 ++++++++++++++++++ gcc/doc/extend.texi | 6 ++++++ gcc/fold-const.c | 4 ++-- gcc/ipa-inline.c | 3 +++ gcc/sancov.c | 4 ++-- gcc/testsuite/gcc.dg/sancov/attribute.c | 27 +++++++++++++++++++++++++ gcc/tree-ssa-ifcombine.c | 4 +++- 8 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/sancov/attribute.c diff --git a/gcc/asan.h b/gcc/asan.h index f110f1db563..8c0b2baf170 100644 --- a/gcc/asan.h +++ b/gcc/asan.h @@ -249,4 +249,14 @@ sanitize_flags_p (unsigned int flag, const_tree fn = current_function_decl) return result_flags; } +/* Return true when coverage sanitization should happend for FN function. */ + +static inline bool +sanitize_coverage_p (const_tree fn = current_function_decl) +{ + return (flag_sanitize_coverage + && lookup_attribute ("no_sanitize_coverage", + DECL_ATTRIBUTES (fn)) == NULL_TREE); +} + #endif /* TREE_ASAN */ diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index ccf9e4ccf0b..671b27c3200 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -62,6 +62,8 @@ static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree, int, bool *); static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int, bool *); +static tree handle_no_sanitize_coverage_attribute (tree *, tree, tree, int, + bool *); static tree handle_asan_odr_indicator_attribute (tree *, tree, tree, int, bool *); static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *); @@ -449,6 +451,8 @@ const struct attribute_spec c_common_attribute_table[] = handle_no_sanitize_thread_attribute, NULL }, { "no_sanitize_undefined", 0, 0, true, false, false, false, handle_no_sanitize_undefined_attribute, NULL }, + { "no_sanitize_coverage", 0, 0, true, false, false, false, + handle_no_sanitize_coverage_attribute, NULL }, { "asan odr indicator", 0, 0, true, false, false, false, handle_asan_odr_indicator_attribute, NULL }, { "warning", 1, 1, true, false, false, false, @@ -1211,6 +1215,22 @@ handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int, return NULL_TREE; } +/* Handle a "no_sanitize_coverage" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_no_sanitize_coverage_attribute (tree *node, tree name, tree, int, + bool *no_add_attrs) +{ + if (TREE_CODE (*node) != FUNCTION_DECL) + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + + return NULL_TREE; +} + /* Handle an "asan odr indicator" attribute; arguments as in struct attribute_spec.handler. */ diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 826804e6149..3ddeb0dee3a 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -3415,6 +3415,12 @@ The @code{no_sanitize_undefined} attribute on functions is used to inform the compiler that it should not check for undefined behavior in the function when compiling with the @option{-fsanitize=undefined} option. +@item no_sanitize_coverage +@cindex @code{no_sanitize_coverage} function attribute +The @code{no_sanitize_coverage} attribute on functions is used +to inform the compiler that it should not do coverage-guided +fuzzing code instrumentation (@option{-fsanitize-coverage}). + @item no_split_stack @cindex @code{no_split_stack} function attribute @opindex fsplit-stack diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 3be9c15e6b2..d088187a057 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -6016,7 +6016,7 @@ fold_range_test (location_t loc, enum tree_code code, tree type, logical_op_non_short_circuit = param_logical_op_non_short_circuit; if (logical_op_non_short_circuit - && !flag_sanitize_coverage + && !sanitize_coverage_p () && lhs != 0 && rhs != 0 && (code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR) && operand_equal_p (lhs, rhs, 0)) @@ -9652,7 +9652,7 @@ fold_truth_andor (location_t loc, enum tree_code code, tree type, logical_op_non_short_circuit = param_logical_op_non_short_circuit; if (logical_op_non_short_circuit - && !flag_sanitize_coverage + && !sanitize_coverage_p () && (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR || code == TRUTH_OR_EXPR diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index f15c4828958..9d896beb2ac 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -283,6 +283,9 @@ sanitize_attrs_match_for_inline_p (const_tree caller, const_tree callee) != sanitize_flags_p (codes[i], callee)) return false; + if (sanitize_coverage_p (caller) != sanitize_coverage_p (callee)) + return false; + return true; } diff --git a/gcc/sancov.c b/gcc/sancov.c index d656c37cae9..9cfbd425def 100644 --- a/gcc/sancov.c +++ b/gcc/sancov.c @@ -313,9 +313,9 @@ public: return new pass_sancov<O0> (m_ctxt); } virtual bool - gate (function *) + gate (function *fun) { - return flag_sanitize_coverage && (!O0 || !optimize); + return sanitize_coverage_p (fun->decl) && (!O0 || !optimize); } virtual unsigned int execute (function *fun) diff --git a/gcc/testsuite/gcc.dg/sancov/attribute.c b/gcc/testsuite/gcc.dg/sancov/attribute.c new file mode 100644 index 00000000000..7cfa9134ff1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/sancov/attribute.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-fsanitize-coverage=trace-pc -fdump-tree-optimized" } */ + +void foo(void) +{ +} + +void +__attribute__((no_sanitize_coverage)) +bar(void) +{ +} + +static void inline +__attribute__((always_inline)) +inline_fn(void) +{ +} + +void +__attribute__((no_sanitize_coverage)) +baz(void) +{ + inline_fn(); +} + +/* { dg-final { scan-tree-dump-times "__builtin___sanitizer_cov_trace_pc \\(\\)" 1 "optimized" } } */ diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c index 836a12d6b80..f93e04aa4df 100644 --- a/gcc/tree-ssa-ifcombine.c +++ b/gcc/tree-ssa-ifcombine.c @@ -40,6 +40,8 @@ along with GCC; see the file COPYING3. If not see #include "gimplify-me.h" #include "tree-cfg.h" #include "tree-ssa.h" +#include "attribs.h" +#include "asan.h" #ifndef LOGICAL_OP_NON_SHORT_CIRCUIT #define LOGICAL_OP_NON_SHORT_CIRCUIT \ @@ -567,7 +569,7 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv, if (param_logical_op_non_short_circuit != -1) logical_op_non_short_circuit = param_logical_op_non_short_circuit; - if (!logical_op_non_short_circuit || flag_sanitize_coverage) + if (!logical_op_non_short_circuit || sanitize_coverage_p ()) return false; /* Only do this optimization if the inner bb contains only the conditional. */ if (!gsi_one_before_end_p (gsi_start_nondebug_after_labels_bb (inner_cond_bb))) -- 2.31.1 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Add no_sanitize_coverage attribute. 2021-05-24 8:03 ` Martin Liška @ 2021-05-24 8:07 ` Marco Elver 2021-05-25 9:55 ` Richard Biener 1 sibling, 0 replies; 9+ messages in thread From: Marco Elver @ 2021-05-24 8:07 UTC (permalink / raw) To: Martin Liška; +Cc: GCC Patches, Nick Desaulniers On Mon, 24 May 2021 at 10:03, Martin Liška <mliska@suse.cz> wrote: > On 5/21/21 2:39 PM, Marco Elver wrote: > > On Fri, May 21, 2021 at 10:50AM +0200, Martin Liška wrote: > >> On 5/20/21 12:55 PM, Marco Elver wrote: > >>> I think this came up with other no_sanitize [1] based on what I had > >>> written to you last year [2]. > >>> > >>> [1]https://gcc.gnu.org/pipermail/gcc-patches/2020-June/547618.html > >>> [2]https://lore.kernel.org/lkml/CANpmjNNRz5OVKb6PE7K6GjfoGbht_ZhyPkNG9aD+KjNDzK7hGg@mail.gmail.com/ > >> > >> Ah, you're right. I've just updated the patch to address that. > >> > >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > >> > >> Ready to be installed? > > > > Looks good, I also just built a kernel with the no_sanitize_coverage > > attribute (without the objtool nop-workaround) and works as expected. > > Good, thanks! > > > > > Not sure if required, but would such an additional test be useful: > > Yes, it is, thanks for it. [...] > > Otherwise, please go ahead. I assume this is targeting GCC 12? > > Yep. > > There's V3 I'm sending. > > Ready for master? From my side this looks good. Thank you! -- Marco ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Add no_sanitize_coverage attribute. 2021-05-24 8:03 ` Martin Liška 2021-05-24 8:07 ` Marco Elver @ 2021-05-25 9:55 ` Richard Biener 1 sibling, 0 replies; 9+ messages in thread From: Richard Biener @ 2021-05-25 9:55 UTC (permalink / raw) To: Martin Liška; +Cc: Marco Elver, Nick Desaulniers, GCC Patches On Mon, May 24, 2021 at 10:27 AM Martin Liška <mliska@suse.cz> wrote: > > On 5/21/21 2:39 PM, Marco Elver wrote: > > On Fri, May 21, 2021 at 10:50AM +0200, Martin Liška wrote: > >> On 5/20/21 12:55 PM, Marco Elver wrote: > >>> I think this came up with other no_sanitize [1] based on what I had > >>> written to you last year [2]. > >>> > >>> [1]https://gcc.gnu.org/pipermail/gcc-patches/2020-June/547618.html > >>> [2]https://lore.kernel.org/lkml/CANpmjNNRz5OVKb6PE7K6GjfoGbht_ZhyPkNG9aD+KjNDzK7hGg@mail.gmail.com/ > >> > >> Ah, you're right. I've just updated the patch to address that. > >> > >> Patch can bootstrap on x86_64-linux-gnu and survives regression tests. > >> > >> Ready to be installed? > > > > Looks good, I also just built a kernel with the no_sanitize_coverage > > attribute (without the objtool nop-workaround) and works as expected. > > Good, thanks! > > > > > Not sure if required, but would such an additional test be useful: > > Yes, it is, thanks for it. > > > > > --- > > > > diff --git a/gcc/testsuite/gcc.dg/sancov/attribute.c b/gcc/testsuite/gcc.dg/sancov/attribute.c > > index bf6dbd4bae7..7cfa9134ff1 100644 > > --- a/gcc/testsuite/gcc.dg/sancov/attribute.c > > +++ b/gcc/testsuite/gcc.dg/sancov/attribute.c > > @@ -11,5 +11,17 @@ bar(void) > > { > > } > > > > +static void inline > > +__attribute__((always_inline)) > > +inline_fn(void) > > +{ > > +} > > + > > +void > > +__attribute__((no_sanitize_coverage)) > > +baz(void) > > +{ > > + inline_fn(); > > +} > > > > /* { dg-final { scan-tree-dump-times "__builtin___sanitizer_cov_trace_pc \\(\\)" 1 "optimized" } } */ > > > > --- > > > > Otherwise, please go ahead. I assume this is targeting GCC 12? > > Yep. > > There's V3 I'm sending. > > Ready for master? OK. Thanks, Richard. > Thanks, > Martin > > > > > Thanks, > > -- Marco > > > ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2021-05-25 9:55 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-05-20 8:33 [PATCH] Add no_sanitize_coverage attribute Martin Liška 2021-05-20 8:45 ` Marco Elver 2021-05-20 9:08 ` Martin Liška 2021-05-20 10:55 ` Marco Elver 2021-05-21 8:50 ` Martin Liška 2021-05-21 12:39 ` Marco Elver 2021-05-24 8:03 ` Martin Liška 2021-05-24 8:07 ` Marco Elver 2021-05-25 9:55 ` Richard Biener
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).