diff options
-rw-r--r-- | gcc/params.opt | 4 | ||||
-rw-r--r-- | gcc/sanitizer.def | 21 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/tsan/volatile.c | 67 | ||||
-rw-r--r-- | gcc/tsan.c | 29 |
4 files changed, 109 insertions, 12 deletions
diff --git a/gcc/params.opt b/gcc/params.opt index 4aec480..9b564bb 100644 --- a/gcc/params.opt +++ b/gcc/params.opt @@ -908,6 +908,10 @@ Stop reverse growth if the reverse probability of best edge is less than this th Common Joined UInteger Var(param_tree_reassoc_width) Param Optimization Set the maximum number of instructions executed in parallel in reassociated tree. If 0, use the target dependent heuristic. +-param=tsan-distinguish-volatile= +Common Joined UInteger Var(param_tsan_distinguish_volatile) IntegerRange(0, 1) Param +Emit special instrumentation for accesses to volatiles. + -param=uninit-control-dep-attempts= Common Joined UInteger Var(param_uninit_control_dep_attempts) Init(1000) IntegerRange(1, 65536) Param Optimization Maximum number of nested calls to search for control dependencies during uninitialized variable analysis. diff --git a/gcc/sanitizer.def b/gcc/sanitizer.def index 11eb646..a32715d 100644 --- a/gcc/sanitizer.def +++ b/gcc/sanitizer.def @@ -214,6 +214,27 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ_RANGE, "__tsan_read_range", DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE_RANGE, "__tsan_write_range", BT_FN_VOID_PTR_PTRMODE, ATTR_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_VOLATILE_READ1, "__tsan_volatile_read1", + BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_VOLATILE_READ2, "__tsan_volatile_read2", + BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_VOLATILE_READ4, "__tsan_volatile_read4", + BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_VOLATILE_READ8, "__tsan_volatile_read8", + BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_VOLATILE_READ16, "__tsan_volatile_read16", + BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_VOLATILE_WRITE1, "__tsan_volatile_write1", + BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_VOLATILE_WRITE2, "__tsan_volatile_write2", + BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_VOLATILE_WRITE4, "__tsan_volatile_write4", + BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_VOLATILE_WRITE8, "__tsan_volatile_write8", + BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) +DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_VOLATILE_WRITE16, "__tsan_volatile_write16", + BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) + DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_ATOMIC8_LOAD, "__tsan_atomic8_load", BT_FN_I1_CONST_VPTR_INT, ATTR_NOTHROW_LEAF_LIST) diff --git a/gcc/testsuite/c-c++-common/tsan/volatile.c b/gcc/testsuite/c-c++-common/tsan/volatile.c new file mode 100644 index 0000000..6837992 --- /dev/null +++ b/gcc/testsuite/c-c++-common/tsan/volatile.c @@ -0,0 +1,67 @@ +/* { dg-options "--param=tsan-distinguish-volatile=1 -fdump-tree-optimized" } */ + +#include <assert.h> +#include <stdint.h> +#include <stdio.h> + +int32_t Global4; +volatile int32_t VolatileGlobal4; +volatile int64_t VolatileGlobal8; + +static int nvolatile_reads; +static int nvolatile_writes; + +#ifdef __cplusplus +extern "C" { +#endif + +__attribute__((no_sanitize_thread)) +void __tsan_volatile_read4(void *addr) { + assert(addr == &VolatileGlobal4); + nvolatile_reads++; +} +__attribute__((no_sanitize_thread)) +void __tsan_volatile_write4(void *addr) { + assert(addr == &VolatileGlobal4); + nvolatile_writes++; +} +__attribute__((no_sanitize_thread)) +void __tsan_volatile_read8(void *addr) { + assert(addr == &VolatileGlobal8); + nvolatile_reads++; +} +__attribute__((no_sanitize_thread)) +void __tsan_volatile_write8(void *addr) { + assert(addr == &VolatileGlobal8); + nvolatile_writes++; +} + +#ifdef __cplusplus +} +#endif + +__attribute__((no_sanitize_thread)) +static void check() { + assert(nvolatile_reads == 4); + assert(nvolatile_writes == 4); +} + +int main() { + Global4 = 1; + + VolatileGlobal4 = 1; + Global4 = VolatileGlobal4; + VolatileGlobal4 = 1 + VolatileGlobal4; + + VolatileGlobal8 = 1; + Global4 = (int32_t)VolatileGlobal8; + VolatileGlobal8 = 1 + VolatileGlobal8; + + check(); + return 0; +} + +// { dg-final { scan-tree-dump-times "__tsan_volatile_read4 \\(&VolatileGlobal4" 2 "optimized" } } +// { dg-final { scan-tree-dump-times "__tsan_volatile_read8 \\(&VolatileGlobal8" 2 "optimized" } } +// { dg-final { scan-tree-dump-times "__tsan_volatile_write4 \\(&VolatileGlobal4" 2 "optimized" } } +// { dg-final { scan-tree-dump-times "__tsan_volatile_write8 \\(&VolatileGlobal8" 2 "optimized" } } @@ -52,25 +52,29 @@ along with GCC; see the file COPYING3. If not see void __tsan_read/writeX (void *addr); */ static tree -get_memory_access_decl (bool is_write, unsigned size) +get_memory_access_decl (bool is_write, unsigned size, bool volatilep) { enum built_in_function fcode; + int pos; if (size <= 1) - fcode = is_write ? BUILT_IN_TSAN_WRITE1 - : BUILT_IN_TSAN_READ1; + pos = 0; else if (size <= 3) - fcode = is_write ? BUILT_IN_TSAN_WRITE2 - : BUILT_IN_TSAN_READ2; + pos = 1; else if (size <= 7) - fcode = is_write ? BUILT_IN_TSAN_WRITE4 - : BUILT_IN_TSAN_READ4; + pos = 2; else if (size <= 15) - fcode = is_write ? BUILT_IN_TSAN_WRITE8 - : BUILT_IN_TSAN_READ8; + pos = 3; + else + pos = 4; + + if (param_tsan_distinguish_volatile && volatilep) + fcode = is_write ? BUILT_IN_TSAN_VOLATILE_WRITE1 + : BUILT_IN_TSAN_VOLATILE_READ1; else - fcode = is_write ? BUILT_IN_TSAN_WRITE16 - : BUILT_IN_TSAN_READ16; + fcode = is_write ? BUILT_IN_TSAN_WRITE1 + : BUILT_IN_TSAN_READ1; + fcode = (built_in_function)(fcode + pos); return builtin_decl_implicit (fcode); } @@ -204,7 +208,8 @@ instrument_expr (gimple_stmt_iterator gsi, tree expr, bool is_write) g = gimple_build_call (builtin_decl, 2, expr_ptr, size_int (size)); } else if (rhs == NULL) - g = gimple_build_call (get_memory_access_decl (is_write, size), + g = gimple_build_call (get_memory_access_decl (is_write, size, + TREE_THIS_VOLATILE (expr)), 1, expr_ptr); else { |