Commit 8946c29e by Yury Gribov Committed by Yury Gribov

New asan-instrumentation-with-call-threshold parameter.

2014-06-16  Yury Gribov  <y.gribov@samsung.com>

	New asan-instrumentation-with-call-threshold parameter.

	gcc/
	* asan.c (check_func): New function.
	(maybe_create_ssa_name): Likewise.
	(build_check_stmt_with_calls): Likewise.
	(use_calls_p): Likewise.
	(report_error_func): Change interface.
	(build_check_stmt): Allow non-integer lengths; add support
	for new parameter.
	(asan_instrument): Likewise.
	(instrument_mem_region_access): Moved code to
	build_check_stmt.
	(instrument_derefs): Likewise.
	(instrument_strlen_call): Likewise.
	* cfgcleanup.c (old_insns_match_p): Add support for new
	functions.
	* doc/invoke.texi: Describe new parameter.
	* params.def: Define new parameter.
	* params.h: Likewise.
	* sanitizer.def: Describe new builtins.

	gcc/testsuite/
	* c-c++-common/asan/instrument-with-calls-1.c: New test.
	* c-c++-common/asan/instrument-with-calls-2.c: Likewise.
	* c-c++-common/asan/instrument-with-calls-3.c: Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-1.c: Update
	test patterns.
	* c-c++-common/asan/no-redundant-instrumentation-2.c:
	Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-4.c:
	Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-5.c:
	Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-6.c:
	Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-7.c:
	Likewise.
	* c-c++-common/asan/no-redundant-instrumentation-8.c:
	Likewise.

From-SVN: r211699
parent 5d5cb4d4
2014-06-16 Yury Gribov <y.gribov@samsung.com>
* asan.c (check_func): New function.
(maybe_create_ssa_name): Likewise.
(build_check_stmt_with_calls): Likewise.
(use_calls_p): Likewise.
(report_error_func): Change interface.
(build_check_stmt): Allow non-integer lengths; add support
for new parameter.
(asan_instrument): Likewise.
(instrument_mem_region_access): Moved code to
build_check_stmt.
(instrument_derefs): Likewise.
(instrument_strlen_call): Likewise.
* cfgcleanup.c (old_insns_match_p): Add support for new
functions.
* doc/invoke.texi: Describe new parameter.
* params.def: Define new parameter.
* params.h: Likewise.
* sanitizer.def: Describe new builtins.
2014-06-16 Richard Biener <rguenther@suse.de> 2014-06-16 Richard Biener <rguenther@suse.de>
* tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):
......
...@@ -1174,7 +1174,7 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2) ...@@ -1174,7 +1174,7 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
&& DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol)) && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol))
>= BUILT_IN_ASAN_REPORT_LOAD1 >= BUILT_IN_ASAN_REPORT_LOAD1
&& DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol)) && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol))
<= BUILT_IN_ASAN_REPORT_STORE16) <= BUILT_IN_ASAN_STOREN)
return dir_none; return dir_none;
} }
} }
......
...@@ -10244,6 +10244,12 @@ is enabled by default when using @option{-fsanitize=address} option. ...@@ -10244,6 +10244,12 @@ is enabled by default when using @option{-fsanitize=address} option.
To disable use-after-return detection use To disable use-after-return detection use
@option{--param asan-use-after-return=0}. @option{--param asan-use-after-return=0}.
@item asan-instrumentation-with-call-threshold
Once number of memory accesses in function becomes greater
or equal than this number, use callbacks instead of
generating inline code. E.g. to disable inline code use
@option{--param asan-instrumentation-with-call-threshold=0}.
@end table @end table
@end table @end table
......
...@@ -1090,6 +1090,12 @@ DEFPARAM (PARAM_ASAN_USE_AFTER_RETURN, ...@@ -1090,6 +1090,12 @@ DEFPARAM (PARAM_ASAN_USE_AFTER_RETURN,
"Enable asan builtin functions protection", "Enable asan builtin functions protection",
1, 0, 1) 1, 0, 1)
DEFPARAM (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,
"asan-instrumentation-with-call-threshold",
"Use callbacks instead of inline code once number of accesses "
" in function becomes greater or equal than this threshold",
10000, 0, INT_MAX)
DEFPARAM (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS, DEFPARAM (PARAM_UNINIT_CONTROL_DEP_ATTEMPTS,
"uninit-control-dep-attempts", "uninit-control-dep-attempts",
"Maximum number of nested calls to search for control dependencies " "Maximum number of nested calls to search for control dependencies "
......
...@@ -232,5 +232,7 @@ extern void init_param_values (int *params); ...@@ -232,5 +232,7 @@ extern void init_param_values (int *params);
PARAM_VALUE (PARAM_ASAN_MEMINTRIN) PARAM_VALUE (PARAM_ASAN_MEMINTRIN)
#define ASAN_USE_AFTER_RETURN \ #define ASAN_USE_AFTER_RETURN \
PARAM_VALUE (PARAM_ASAN_USE_AFTER_RETURN) PARAM_VALUE (PARAM_ASAN_USE_AFTER_RETURN)
#define ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD \
PARAM_VALUE (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD)
#endif /* ! GCC_PARAMS_H */ #endif /* ! GCC_PARAMS_H */
...@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see
/* Address Sanitizer */ /* Address Sanitizer */
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_INIT, "__asan_init_v3", DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_INIT, "__asan_init_v3",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST) BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
/* Do not reorder the BUILT_IN_ASAN_REPORT* builtins, e.g. cfgcleanup.c /* Do not reorder the BUILT_IN_ASAN_{REPORT,CHECK}* builtins, e.g. cfgcleanup.c
relies on this order. */ relies on this order. */
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD1, "__asan_report_load1", DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD1, "__asan_report_load1",
BT_FN_VOID_PTR, ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST) BT_FN_VOID_PTR, ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST)
...@@ -57,6 +57,30 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE16, "__asan_report_store16", ...@@ -57,6 +57,30 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE16, "__asan_report_store16",
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE_N, "__asan_report_store_n", DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE_N, "__asan_report_store_n",
BT_FN_VOID_PTR_PTRMODE, BT_FN_VOID_PTR_PTRMODE,
ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST) ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOAD1, "__asan_load1",
BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOAD2, "__asan_load2",
BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOAD4, "__asan_load4",
BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOAD8, "__asan_load8",
BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOAD16, "__asan_load16",
BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_LOADN, "__asan_loadN",
BT_FN_VOID_PTR_PTRMODE, ATTR_TMPURE_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STORE1, "__asan_store1",
BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STORE2, "__asan_store2",
BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STORE4, "__asan_store4",
BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STORE8, "__asan_store8",
BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STORE16, "__asan_store16",
BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_STOREN, "__asan_storeN",
BT_FN_VOID_PTR_PTRMODE, ATTR_TMPURE_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REGISTER_GLOBALS, DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REGISTER_GLOBALS,
"__asan_register_globals", "__asan_register_globals",
BT_FN_VOID_PTR_PTRMODE, ATTR_NOTHROW_LEAF_LIST) BT_FN_VOID_PTR_PTRMODE, ATTR_NOTHROW_LEAF_LIST)
......
2014-06-16 Yury Gribov <y.gribov@samsung.com>
* c-c++-common/asan/instrument-with-calls-1.c: New test.
* c-c++-common/asan/instrument-with-calls-2.c: Likewise.
* c-c++-common/asan/instrument-with-calls-3.c: Likewise.
* c-c++-common/asan/no-redundant-instrumentation-1.c: Update
test patterns.
* c-c++-common/asan/no-redundant-instrumentation-2.c:
Likewise.
* c-c++-common/asan/no-redundant-instrumentation-4.c:
Likewise.
* c-c++-common/asan/no-redundant-instrumentation-5.c:
Likewise.
* c-c++-common/asan/no-redundant-instrumentation-6.c:
Likewise.
* c-c++-common/asan/no-redundant-instrumentation-7.c:
Likewise.
* c-c++-common/asan/no-redundant-instrumentation-8.c:
Likewise.
2014-06-15 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> 2014-06-15 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR fortran/28484 PR fortran/28484
......
/* { dg-do assemble } */
/* { dg-options "--param asan-instrumentation-with-call-threshold=0 -save-temps" } */
void f(char *a, int *b) {
*b = *a;
}
/* { dg-final { scan-assembler "__asan_load1" } } */
/* { dg-final { scan-assembler "__asan_store4" } } */
/* { dg-final { cleanup-saved-temps } } */
/* { dg-do assemble } */
/* { dg-options "--param asan-instrumentation-with-call-threshold=1 -save-temps" } */
int x;
void f(int *a, int *b) {
*a = 0;
asm volatile ("" ::: "memory");
x = *b;
}
/* { dg-final { scan-assembler-not "__asan_store4" } } */
/* { dg-final { scan-assembler "__asan_report_store4" } } */
/* { dg-final { scan-assembler "__asan_load4" } } */
/* { dg-final { scan-assembler-not "__asan_report_load4" } } */
/* { dg-final { cleanup-saved-temps } } */
/* { dg-do assemble } */
/* { dg-options "--param asan-instrumentation-with-call-threshold=0 -save-temps" } */
struct A {
char x[7];
};
void f(struct A *x, struct A *y) {
*x = *y;
}
/* { dg-final { scan-assembler "__asan_loadN" } } */
/* { dg-final { scan-assembler "__asan_storeN" } } */
/* { dg-final { cleanup-saved-temps } } */
...@@ -16,12 +16,11 @@ test0 () ...@@ -16,12 +16,11 @@ test0 ()
tab[0] = 1; tab[0] = 1;
tab[1] = 2; tab[1] = 2;
/* __builtin___asan_report_load1 called 1 time for the store
below. */
char t0 = tab[1];
/* This load should not be instrumented because it is to the same /* This load should not be instrumented because it is to the same
memory location as above. */ memory location as above. */
char t0 = tab[1];
/* Likewise. */
char t1 = tab[1]; char t1 = tab[1];
return t0 + t1; return t0 + t1;
...@@ -36,7 +35,7 @@ test1 (int i) ...@@ -36,7 +35,7 @@ test1 (int i)
the initialization. */ the initialization. */
foo[i] = 1; foo[i] = 1;
/*__builtin___asan_report_store1 called 2 times here to instrument /*__builtin___asan_report_store_n called once here to instrument
the store to the memory region of tab. */ the store to the memory region of tab. */
__builtin_memset (tab, 3, sizeof (tab)); __builtin_memset (tab, 3, sizeof (tab));
...@@ -44,8 +43,8 @@ test1 (int i) ...@@ -44,8 +43,8 @@ test1 (int i)
__builtin_memset (tab, 4, sizeof (tab)); __builtin_memset (tab, 4, sizeof (tab));
__builtin_memset (tab, 5, sizeof (tab)); __builtin_memset (tab, 5, sizeof (tab));
/* There are 2 calls to __builtin___asan_report_store1 and 2 calls /* There is a call to __builtin___asan_report_store_n and a call
to __builtin___asan_report_load1 to instrument the store to to __builtin___asan_report_load_n to instrument the store to
(subset of) the memory region of tab. */ (subset of) the memory region of tab. */
__builtin_memcpy (&tab[1], foo + i, 3); __builtin_memcpy (&tab[1], foo + i, 3);
...@@ -53,7 +52,7 @@ test1 (int i) ...@@ -53,7 +52,7 @@ test1 (int i)
the reference to tab[1] has been already instrumented above. */ the reference to tab[1] has been already instrumented above. */
return tab[1]; return tab[1];
/* So for these function, there should be 7 calls to /* So for these functions, there should be 3 calls to
__builtin___asan_report_store1. */ __builtin___asan_report_store1. */
} }
...@@ -63,6 +62,7 @@ main () ...@@ -63,6 +62,7 @@ main ()
return test0 () && test1 (0); return test0 () && test1 (0);
} }
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 7 "asan0" } } */ /* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 3 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load" 2 "asan0" } } */ /* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load" 1 "asan0" } } */
/* { dg-final { cleanup-tree-dump "asan0" } } */ /* { dg-final { cleanup-tree-dump "asan0" } } */
...@@ -20,6 +20,7 @@ main () ...@@ -20,6 +20,7 @@ main ()
__builtin_memset (tab, 1, 3); __builtin_memset (tab, 1, 3);
} }
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 3 "asan0" } } */ /* { dg-final { scan-tree-dump-times "& 7" 3 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report" 3 "asan0" } } */ /* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report" 2 "asan0" } } */
/* { dg-final { cleanup-tree-dump "asan0" } } */ /* { dg-final { cleanup-tree-dump "asan0" } } */
...@@ -5,9 +5,13 @@ ...@@ -5,9 +5,13 @@
void void
foo (int *a, char *b, char *c) foo (int *a, char *b, char *c)
{ {
/* One check for c[0], one check for a[], one check for c, two checks for b. */
__builtin_memmove (c, b, a[c[0]]); __builtin_memmove (c, b, a[c[0]]);
/* For a total of 5 checks. */
} }
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 3 "asan0" } } */ /* { dg-final { scan-tree-dump-times "& 7" 5 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 1 "asan0" } } */ /* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "asan0" } } */
/* { dg-final { cleanup-tree-dump "asan0" } } */ /* { dg-final { cleanup-tree-dump "asan0" } } */
...@@ -5,9 +5,14 @@ ...@@ -5,9 +5,14 @@
void void
foo (int *a, char *b, char *c) foo (int *a, char *b, char *c)
{ {
/* One check for b[0], one check for a[], 2 checks for c and one checks for b. */
__builtin_memmove (c, b, a[b[0]]); __builtin_memmove (c, b, a[b[0]]);
/* For a total of 5 checks. */
} }
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 2 "asan0" } } */ /* { dg-final { scan-tree-dump-times "& 7" 5 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 2 "asan0" } } */ /* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 1 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "asan0" } } */
/* { dg-final { cleanup-tree-dump "asan0" } } */ /* { dg-final { cleanup-tree-dump "asan0" } } */
...@@ -5,10 +5,16 @@ ...@@ -5,10 +5,16 @@
void void
foo (int *a, char *b, char *c) foo (int *a, char *b, char *c)
{ {
/* One check for c[0], one check for a[], one check for c and 2 checks for b. */
__builtin_memmove (c, b, a[c[0]]); __builtin_memmove (c, b, a[c[0]]);
/* One check for a[], one check for c and one check for b. */
__builtin_memmove (c, b, a[b[0]]); __builtin_memmove (c, b, a[b[0]]);
/* For a total of 8 checks. */
} }
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 5 "asan0" } } */ /* { dg-final { scan-tree-dump-times "& 7" 8 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 2 "asan0" } } */ /* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 2 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 2 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 2 "asan0" } } */
/* { dg-final { cleanup-tree-dump "asan0" } } */ /* { dg-final { cleanup-tree-dump "asan0" } } */
...@@ -13,11 +13,15 @@ struct S ...@@ -13,11 +13,15 @@ struct S
int int
foo (int *a, char *b, char *c) foo (int *a, char *b, char *c)
{ {
/* 2 checks for s.a, 2 checks for e. */
int d = __builtin_memcmp (s.a, e, 100); int d = __builtin_memcmp (s.a, e, 100);
/* One check for s.a and one check for e. */
d += __builtin_memcmp (s.a, e, 200); d += __builtin_memcmp (s.a, e, 200);
/* For a total of 6 checks. */
return d; return d;
} }
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load" 6 "asan0" } } */ /* { dg-final { scan-tree-dump-times "& 7" 6 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 4 "asan0" } } */
/* { dg-final { scan-tree-dump-not "__builtin___asan_report_store" "asan0" } } */ /* { dg-final { scan-tree-dump-not "__builtin___asan_report_store" "asan0" } } */
/* { dg-final { cleanup-tree-dump "asan0" } } */ /* { dg-final { cleanup-tree-dump "asan0" } } */
...@@ -5,10 +5,16 @@ ...@@ -5,10 +5,16 @@
char char
foo (int *a, char *b, char *c) foo (int *a, char *b, char *c)
{ {
/* One check for b[0], one check for a[], two checks for c and one check for b. */
__builtin_memmove (c, b, a[b[0]]); __builtin_memmove (c, b, a[b[0]]);
/* No checks here. */
return c[0] + b[0]; return c[0] + b[0];
/* For a total of 5 checks. */
} }
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 3 "asan0" } } */ /* { dg-final { scan-tree-dump-times "& 7" 5 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store1" 2 "asan0" } } */ /* { dg-final { scan-tree-dump-times "__builtin___asan_report_load1" 1 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load4" 1 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_load_n" 1 "asan0" } } */
/* { dg-final { scan-tree-dump-times "__builtin___asan_report_store_n" 1 "asan0" } } */
/* { dg-final { cleanup-tree-dump "asan0" } } */ /* { dg-final { cleanup-tree-dump "asan0" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment