aboutsummaryrefslogtreecommitdiff
path: root/gcc/asan.c
diff options
context:
space:
mode:
authorYury Gribov <y.gribov@samsung.com>2014-10-28 10:33:04 +0000
committerYury Gribov <ygribov@gcc.gnu.org>2014-10-28 10:33:04 +0000
commitfed4de37b870faad50374a63aa1cf68a97963da6 (patch)
treed89db50eee01910485a109af95f83b25923b4462 /gcc/asan.c
parentfd960af2df5a437302039f248a542354ee4cddcf (diff)
downloadgcc-fed4de37b870faad50374a63aa1cf68a97963da6.zip
gcc-fed4de37b870faad50374a63aa1cf68a97963da6.tar.gz
gcc-fed4de37b870faad50374a63aa1cf68a97963da6.tar.bz2
Enable -fsanitize-recover for KASan.
2014-10-28 Yury Gribov <y.gribov@samsung.com> gcc/ * asan.c (report_error_func): Add noabort path. (check_func): Ditto. Formatting. (asan_expand_check_ifn): Handle noabort path. * common.opt (flag_sanitize_recover): Add SANITIZE_KERNEL_ADDRESS to default value. * doc/invoke.texi (-fsanitize-recover=): Mention KASan. * opts.c (finish_options): Reword comment. * sanitizer.def: Add noabort ASan builtins. gcc/testsuite/ * c-c++-common/asan/kasan-recover-1.c: New test. * c-c++-common/asan/kasan-recover-2.c: New test. * c-c++-common/asan/instrument-with-calls-1.c: Get rid of -save-temps. * c-c++-common/asan/instrument-with-calls-2.c: Likewise. * c-c++-common/asan/instrument-with-calls-3.c: Likewise. * c-c++-common/asan/kasan-recover-1.c: Likewise. * c-c++-common/asan/kasan-recover-2.c: Likewise. * c-c++-common/asan/no-asan-globals.c: Likewise. * c-c++-common/asan/no-instrument-reads.c: Likewise. * c-c++-common/asan/no-instrument-writes.c: Likewise. * c-c++-common/asan/no-use-after-return.c: Likewise. From-SVN: r216778
Diffstat (limited to 'gcc/asan.c')
-rw-r--r--gcc/asan.c81
1 files changed, 56 insertions, 25 deletions
diff --git a/gcc/asan.c b/gcc/asan.c
index 9080fc3..8612655 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -1392,44 +1392,72 @@ asan_protect_global (tree decl)
IS_STORE is either 1 (for a store) or 0 (for a load). */
static tree
-report_error_func (bool is_store, HOST_WIDE_INT size_in_bytes, int *nargs)
-{
- static enum built_in_function report[2][6]
- = { { BUILT_IN_ASAN_REPORT_LOAD1, BUILT_IN_ASAN_REPORT_LOAD2,
- BUILT_IN_ASAN_REPORT_LOAD4, BUILT_IN_ASAN_REPORT_LOAD8,
- BUILT_IN_ASAN_REPORT_LOAD16, BUILT_IN_ASAN_REPORT_LOAD_N },
- { BUILT_IN_ASAN_REPORT_STORE1, BUILT_IN_ASAN_REPORT_STORE2,
- BUILT_IN_ASAN_REPORT_STORE4, BUILT_IN_ASAN_REPORT_STORE8,
- BUILT_IN_ASAN_REPORT_STORE16, BUILT_IN_ASAN_REPORT_STORE_N } };
+report_error_func (bool is_store, bool recover_p, HOST_WIDE_INT size_in_bytes,
+ int *nargs)
+{
+ static enum built_in_function report[2][2][6]
+ = { { { BUILT_IN_ASAN_REPORT_LOAD1, BUILT_IN_ASAN_REPORT_LOAD2,
+ BUILT_IN_ASAN_REPORT_LOAD4, BUILT_IN_ASAN_REPORT_LOAD8,
+ BUILT_IN_ASAN_REPORT_LOAD16, BUILT_IN_ASAN_REPORT_LOAD_N },
+ { BUILT_IN_ASAN_REPORT_STORE1, BUILT_IN_ASAN_REPORT_STORE2,
+ BUILT_IN_ASAN_REPORT_STORE4, BUILT_IN_ASAN_REPORT_STORE8,
+ BUILT_IN_ASAN_REPORT_STORE16, BUILT_IN_ASAN_REPORT_STORE_N } },
+ { { BUILT_IN_ASAN_REPORT_LOAD1_NOABORT,
+ BUILT_IN_ASAN_REPORT_LOAD2_NOABORT,
+ BUILT_IN_ASAN_REPORT_LOAD4_NOABORT,
+ BUILT_IN_ASAN_REPORT_LOAD8_NOABORT,
+ BUILT_IN_ASAN_REPORT_LOAD16_NOABORT,
+ BUILT_IN_ASAN_REPORT_LOAD_N_NOABORT },
+ { BUILT_IN_ASAN_REPORT_STORE1_NOABORT,
+ BUILT_IN_ASAN_REPORT_STORE2_NOABORT,
+ BUILT_IN_ASAN_REPORT_STORE4_NOABORT,
+ BUILT_IN_ASAN_REPORT_STORE8_NOABORT,
+ BUILT_IN_ASAN_REPORT_STORE16_NOABORT,
+ BUILT_IN_ASAN_REPORT_STORE_N_NOABORT } } };
if (size_in_bytes == -1)
{
*nargs = 2;
- return builtin_decl_implicit (report[is_store][5]);
+ return builtin_decl_implicit (report[recover_p][is_store][5]);
}
*nargs = 1;
- return builtin_decl_implicit (report[is_store][exact_log2 (size_in_bytes)]);
+ int size_log2 = exact_log2 (size_in_bytes);
+ return builtin_decl_implicit (report[recover_p][is_store][size_log2]);
}
/* Construct a function tree for __asan_{load,store}{1,2,4,8,16,_n}.
IS_STORE is either 1 (for a store) or 0 (for a load). */
static tree
-check_func (bool is_store, int size_in_bytes, int *nargs)
-{
- static enum built_in_function check[2][6]
- = { { BUILT_IN_ASAN_LOAD1, BUILT_IN_ASAN_LOAD2,
- BUILT_IN_ASAN_LOAD4, BUILT_IN_ASAN_LOAD8,
- BUILT_IN_ASAN_LOAD16, BUILT_IN_ASAN_LOADN },
- { BUILT_IN_ASAN_STORE1, BUILT_IN_ASAN_STORE2,
- BUILT_IN_ASAN_STORE4, BUILT_IN_ASAN_STORE8,
- BUILT_IN_ASAN_STORE16, BUILT_IN_ASAN_STOREN } };
+check_func (bool is_store, bool recover_p, HOST_WIDE_INT size_in_bytes,
+ int *nargs)
+{
+ static enum built_in_function check[2][2][6]
+ = { { { BUILT_IN_ASAN_LOAD1, BUILT_IN_ASAN_LOAD2,
+ BUILT_IN_ASAN_LOAD4, BUILT_IN_ASAN_LOAD8,
+ BUILT_IN_ASAN_LOAD16, BUILT_IN_ASAN_LOADN },
+ { BUILT_IN_ASAN_STORE1, BUILT_IN_ASAN_STORE2,
+ BUILT_IN_ASAN_STORE4, BUILT_IN_ASAN_STORE8,
+ BUILT_IN_ASAN_STORE16, BUILT_IN_ASAN_STOREN } },
+ { { BUILT_IN_ASAN_LOAD1_NOABORT,
+ BUILT_IN_ASAN_LOAD2_NOABORT,
+ BUILT_IN_ASAN_LOAD4_NOABORT,
+ BUILT_IN_ASAN_LOAD8_NOABORT,
+ BUILT_IN_ASAN_LOAD16_NOABORT,
+ BUILT_IN_ASAN_LOADN_NOABORT },
+ { BUILT_IN_ASAN_STORE1_NOABORT,
+ BUILT_IN_ASAN_STORE2_NOABORT,
+ BUILT_IN_ASAN_STORE4_NOABORT,
+ BUILT_IN_ASAN_STORE8_NOABORT,
+ BUILT_IN_ASAN_STORE16_NOABORT,
+ BUILT_IN_ASAN_STOREN_NOABORT } } };
if (size_in_bytes == -1)
{
*nargs = 2;
- return builtin_decl_implicit (check[is_store][5]);
+ return builtin_decl_implicit (check[recover_p][is_store][5]);
}
*nargs = 1;
- return builtin_decl_implicit (check[is_store][exact_log2 (size_in_bytes)]);
+ int size_log2 = exact_log2 (size_in_bytes);
+ return builtin_decl_implicit (check[recover_p][is_store][size_log2]);
}
/* Split the current basic block and create a condition statement
@@ -2550,6 +2578,9 @@ asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
gimple g = gsi_stmt (*iter);
location_t loc = gimple_location (g);
+ bool recover_p
+ = (flag_sanitize & flag_sanitize_recover & SANITIZE_KERNEL_ADDRESS) != 0;
+
HOST_WIDE_INT flags = tree_to_shwi (gimple_call_arg (g, 0));
gcc_assert (flags < ASAN_CHECK_LAST);
bool is_scalar_access = (flags & ASAN_CHECK_SCALAR_ACCESS) != 0;
@@ -2578,7 +2609,7 @@ asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
tree base_addr = gimple_assign_lhs (g);
int nargs;
- tree fun = check_func (is_store, size_in_bytes, &nargs);
+ tree fun = check_func (is_store, recover_p, size_in_bytes, &nargs);
if (nargs == 1)
g = gimple_build_call (fun, 1, base_addr);
else
@@ -2639,7 +2670,7 @@ asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
basic_block then_bb, else_bb;
gsi = create_cond_insert_point (&gsi, /*before_p*/false,
/*then_more_likely_p=*/false,
- /*create_then_fallthru_edge=*/false,
+ /*create_then_fallthru_edge*/recover_p,
&then_bb,
&else_bb);
@@ -2748,7 +2779,7 @@ asan_expand_check_ifn (gimple_stmt_iterator *iter, bool use_calls)
/* Generate call to the run-time library (e.g. __asan_report_load8). */
gsi = gsi_start_bb (then_bb);
int nargs;
- tree fun = report_error_func (is_store, size_in_bytes, &nargs);
+ tree fun = report_error_func (is_store, recover_p, size_in_bytes, &nargs);
g = gimple_build_call (fun, nargs, base_addr, len);
gimple_set_location (g, loc);
gsi_insert_after (&gsi, g, GSI_NEW_STMT);