Commit 0e668eaf by Jakub Jelinek Committed by Jakub Jelinek

sanitizer.def: Add Address Sanitizer builtins.

	* sanitizer.def: Add Address Sanitizer builtins.
	Rename BUILT_IN_TSAN_READ_* to BUILT_IN_TSAN_READ* and
	BUILT_IN_TSAN_WRITE_* to BUILT_IN_TSAN_WRITE*.
	* Makefile.in (asan.o): Depend on langhooks.h.
	(tsan.o): Depend on asan.h.
	* asan.h (initialize_sanitizer_builtins): New prototype.
	* asan.c: Include langhooks.h.
	(report_error_func): Use builtin_decl_implicit of corresponding
	BUILT_IN_ASAN_REPORT_{LOAD,STORE}*.
	(asan_init_func): Removed.
	(initialize_sanitizer_builtins): New function.
	(asan_finish_file): Call it.  Use builtin_decl_implicit
	on BUILT_IN_ASAN_{INIT,{,UN}REGISTER_GLOBALS}.
	(asan_instrument): Call initialize_sanitizer_builtins.
	* builtins.def (DEF_SANITIZER_BUILTIN): Change condition to
	(flag_asan || flag_tsan).
	* tsan.c: Include asan.h and tsan.h.
	(get_memory_access_decl): Rename BUILT_IN_TSAN_{READ,WRITE}_*
	to BUILT_IN_TSAN_{READ,WRITE}*.
	(tsan_pass): Call initialize_sanitizer_builtins.
	(tsan_gate, tsan_gate_O0): Don't check if
	builtin_decl_implicit_p (BUILT_IN_TSAN_INIT) is true.
	(tsan_finish_file): Call initialize_sanitizer_builtins.
	* builtin-types.def (BT_FN_VOID_PTR_PTRMODE): New fn type.

From-SVN: r194103
parent f41e5bd1
2012-12-03 Jakub Jelinek <jakub@redhat.com>
* sanitizer.def: Add Address Sanitizer builtins.
Rename BUILT_IN_TSAN_READ_* to BUILT_IN_TSAN_READ* and
BUILT_IN_TSAN_WRITE_* to BUILT_IN_TSAN_WRITE*.
* Makefile.in (asan.o): Depend on langhooks.h.
(tsan.o): Depend on asan.h.
* asan.h (initialize_sanitizer_builtins): New prototype.
* asan.c: Include langhooks.h.
(report_error_func): Use builtin_decl_implicit of corresponding
BUILT_IN_ASAN_REPORT_{LOAD,STORE}*.
(asan_init_func): Removed.
(initialize_sanitizer_builtins): New function.
(asan_finish_file): Call it. Use builtin_decl_implicit
on BUILT_IN_ASAN_{INIT,{,UN}REGISTER_GLOBALS}.
(asan_instrument): Call initialize_sanitizer_builtins.
* builtins.def (DEF_SANITIZER_BUILTIN): Change condition to
(flag_asan || flag_tsan).
* tsan.c: Include asan.h and tsan.h.
(get_memory_access_decl): Rename BUILT_IN_TSAN_{READ,WRITE}_*
to BUILT_IN_TSAN_{READ,WRITE}*.
(tsan_pass): Call initialize_sanitizer_builtins.
(tsan_gate, tsan_gate_O0): Don't check if
builtin_decl_implicit_p (BUILT_IN_TSAN_INIT) is true.
(tsan_finish_file): Call initialize_sanitizer_builtins.
* builtin-types.def (BT_FN_VOID_PTR_PTRMODE): New fn type.
2012-12-03 Aldy Hernandez <aldyh@redhat.com> 2012-12-03 Aldy Hernandez <aldyh@redhat.com>
PR middle-end/55401 PR middle-end/55401
...@@ -2228,13 +2228,13 @@ stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ ...@@ -2228,13 +2228,13 @@ stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
asan.o : asan.c asan.h $(CONFIG_H) $(SYSTEM_H) $(GIMPLE_H) \ asan.o : asan.c asan.h $(CONFIG_H) $(SYSTEM_H) $(GIMPLE_H) \
output.h coretypes.h $(GIMPLE_PRETTY_PRINT_H) \ output.h coretypes.h $(GIMPLE_PRETTY_PRINT_H) \
tree-iterator.h $(TREE_FLOW_H) $(TREE_PASS_H) \ tree-iterator.h $(TREE_FLOW_H) $(TREE_PASS_H) \
$(TARGET_H) $(EXPR_H) $(OPTABS_H) $(TM_P_H) $(TARGET_H) $(EXPR_H) $(OPTABS_H) $(TM_P_H) langhooks.h
tsan.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TREE_INLINE_H) \ tsan.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TREE_INLINE_H) \
$(GIMPLE_H) $(DIAGNOSTIC_H) langhooks.h \ $(GIMPLE_H) $(DIAGNOSTIC_H) langhooks.h \
$(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(CGRAPH_H) $(GGC_H) \ $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(CGRAPH_H) $(GGC_H) \
$(BASIC_BLOCK_H) $(FLAGS_H) $(FUNCTION_H) \ $(BASIC_BLOCK_H) $(FLAGS_H) $(FUNCTION_H) \
$(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_CORE_H) $(GIMPLE_H) tree-iterator.h \ $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_CORE_H) $(GIMPLE_H) tree-iterator.h \
intl.h cfghooks.h output.h options.h c-family/c-common.h tsan.h intl.h cfghooks.h output.h options.h c-family/c-common.h tsan.h asan.h
tree-ssa-tail-merge.o: tree-ssa-tail-merge.c \ tree-ssa-tail-merge.o: tree-ssa-tail-merge.c \
$(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(BITMAP_H) \ $(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(BITMAP_H) \
$(FLAGS_H) $(TM_P_H) $(BASIC_BLOCK_H) \ $(FLAGS_H) $(TM_P_H) $(BASIC_BLOCK_H) \
......
...@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "optabs.h" #include "optabs.h"
#include "output.h" #include "output.h"
#include "tm_p.h" #include "tm_p.h"
#include "langhooks.h"
/* AddressSanitizer finds out-of-bounds and use-after-free bugs /* AddressSanitizer finds out-of-bounds and use-after-free bugs
with <2x slowdown on average. with <2x slowdown on average.
...@@ -485,38 +486,16 @@ asan_protect_global (tree decl) ...@@ -485,38 +486,16 @@ asan_protect_global (tree decl)
static tree static tree
report_error_func (bool is_store, int size_in_bytes) report_error_func (bool is_store, int size_in_bytes)
{ {
tree fn_type; static enum built_in_function report[2][5]
tree def; = { { BUILT_IN_ASAN_REPORT_LOAD1, BUILT_IN_ASAN_REPORT_LOAD2,
char name[100]; BUILT_IN_ASAN_REPORT_LOAD4, BUILT_IN_ASAN_REPORT_LOAD8,
BUILT_IN_ASAN_REPORT_LOAD16 },
sprintf (name, "__asan_report_%s%d", { BUILT_IN_ASAN_REPORT_STORE1, BUILT_IN_ASAN_REPORT_STORE2,
is_store ? "store" : "load", size_in_bytes); BUILT_IN_ASAN_REPORT_STORE4, BUILT_IN_ASAN_REPORT_STORE8,
fn_type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE); BUILT_IN_ASAN_REPORT_STORE16 } };
def = build_fn_decl (name, fn_type); return builtin_decl_implicit (report[is_store][exact_log2 (size_in_bytes)]);
TREE_NOTHROW (def) = 1;
DECL_IGNORED_P (def) = 1;
TREE_THIS_VOLATILE (def) = 1; /* Attribute noreturn. Surprise! */
DECL_ATTRIBUTES (def) = tree_cons (get_identifier ("leaf"),
NULL, DECL_ATTRIBUTES (def));
return def;
} }
/* Construct a function tree for __asan_init(). */
static tree
asan_init_func (void)
{
tree fn_type;
tree def;
fn_type = build_function_type_list (void_type_node, NULL_TREE);
def = build_fn_decl ("__asan_init", fn_type);
TREE_NOTHROW (def) = 1;
DECL_IGNORED_P (def) = 1;
return def;
}
#define PROB_VERY_UNLIKELY (REG_BR_PROB_BASE / 2000 - 1) #define PROB_VERY_UNLIKELY (REG_BR_PROB_BASE / 2000 - 1)
#define PROB_ALWAYS (REG_BR_PROB_BASE) #define PROB_ALWAYS (REG_BR_PROB_BASE)
...@@ -1510,6 +1489,38 @@ asan_add_global (tree decl, tree type, vec<constructor_elt, va_gc> *v) ...@@ -1510,6 +1489,38 @@ asan_add_global (tree decl, tree type, vec<constructor_elt, va_gc> *v)
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init); CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
} }
/* Initialize sanitizer.def builtins if the FE hasn't initialized them. */
void
initialize_sanitizer_builtins (void)
{
tree decl;
if (builtin_decl_implicit_p (BUILT_IN_ASAN_INIT))
return;
tree BT_FN_VOID = build_function_type_list (void_type_node, NULL_TREE);
tree BT_FN_VOID_PTR
= build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
tree BT_FN_VOID_PTR_PTRMODE
= build_function_type_list (void_type_node, ptr_type_node,
build_nonstandard_integer_type (POINTER_SIZE,
1), NULL_TREE);
#undef ATTR_NOTHROW_LEAF_LIST
#define ATTR_NOTHROW_LEAF_LIST ECF_NOTHROW | ECF_LEAF
#undef ATTR_NORETURN_NOTHROW_LEAF_LIST
#define ATTR_NORETURN_NOTHROW_LEAF_LIST ECF_NORETURN | ATTR_NOTHROW_LEAF_LIST
#undef DEF_SANITIZER_BUILTIN
#define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
decl = add_builtin_function ("__builtin_" NAME, TYPE, ENUM, \
BUILT_IN_NORMAL, NAME, NULL_TREE); \
set_call_expr_flags (decl, ATTRS); \
set_builtin_decl (ENUM, decl, true);
#include "sanitizer.def"
#undef DEF_SANITIZER_BUILTIN
}
/* Needs to be GTY(()), because cgraph_build_static_cdtor may /* Needs to be GTY(()), because cgraph_build_static_cdtor may
invoke ggc_collect. */ invoke ggc_collect. */
static GTY(()) tree asan_ctor_statements; static GTY(()) tree asan_ctor_statements;
...@@ -1525,14 +1536,16 @@ asan_finish_file (void) ...@@ -1525,14 +1536,16 @@ asan_finish_file (void)
struct varpool_node *vnode; struct varpool_node *vnode;
unsigned HOST_WIDE_INT gcount = 0; unsigned HOST_WIDE_INT gcount = 0;
append_to_statement_list (build_call_expr (asan_init_func (), 0), initialize_sanitizer_builtins ();
&asan_ctor_statements);
tree fn = builtin_decl_implicit (BUILT_IN_ASAN_INIT);
append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
FOR_EACH_DEFINED_VARIABLE (vnode) FOR_EACH_DEFINED_VARIABLE (vnode)
if (asan_protect_global (vnode->symbol.decl)) if (asan_protect_global (vnode->symbol.decl))
++gcount; ++gcount;
if (gcount) if (gcount)
{ {
tree type = asan_global_struct (), var, ctor, decl; tree type = asan_global_struct (), var, ctor;
tree uptr = build_nonstandard_integer_type (POINTER_SIZE, 1); tree uptr = build_nonstandard_integer_type (POINTER_SIZE, 1);
tree dtor_statements = NULL_TREE; tree dtor_statements = NULL_TREE;
vec<constructor_elt, va_gc> *v; vec<constructor_elt, va_gc> *v;
...@@ -1556,20 +1569,14 @@ asan_finish_file (void) ...@@ -1556,20 +1569,14 @@ asan_finish_file (void)
DECL_INITIAL (var) = ctor; DECL_INITIAL (var) = ctor;
varpool_assemble_decl (varpool_node_for_decl (var)); varpool_assemble_decl (varpool_node_for_decl (var));
type = build_function_type_list (void_type_node, ptr_type_node, fn = builtin_decl_implicit (BUILT_IN_ASAN_REGISTER_GLOBALS);
uptr, NULL_TREE); append_to_statement_list (build_call_expr (fn, 2,
decl = build_fn_decl ("__asan_register_globals", type);
TREE_NOTHROW (decl) = 1;
DECL_IGNORED_P (decl) = 1;
append_to_statement_list (build_call_expr (decl, 2,
build_fold_addr_expr (var), build_fold_addr_expr (var),
build_int_cst (uptr, gcount)), build_int_cst (uptr, gcount)),
&asan_ctor_statements); &asan_ctor_statements);
decl = build_fn_decl ("__asan_unregister_globals", type); fn = builtin_decl_implicit (BUILT_IN_ASAN_UNREGISTER_GLOBALS);
TREE_NOTHROW (decl) = 1; append_to_statement_list (build_call_expr (fn, 2,
DECL_IGNORED_P (decl) = 1;
append_to_statement_list (build_call_expr (decl, 2,
build_fold_addr_expr (var), build_fold_addr_expr (var),
build_int_cst (uptr, gcount)), build_int_cst (uptr, gcount)),
&dtor_statements); &dtor_statements);
...@@ -1600,7 +1607,10 @@ static unsigned int ...@@ -1600,7 +1607,10 @@ static unsigned int
asan_instrument (void) asan_instrument (void)
{ {
if (shadow_ptr_types[0] == NULL_TREE) if (shadow_ptr_types[0] == NULL_TREE)
asan_init_shadow_ptr_types (); {
asan_init_shadow_ptr_types ();
initialize_sanitizer_builtins ();
}
transform_statements (); transform_statements ();
return 0; return 0;
} }
......
...@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see
extern void asan_finish_file (void); extern void asan_finish_file (void);
extern rtx asan_emit_stack_protection (rtx, HOST_WIDE_INT *, tree *, int); extern rtx asan_emit_stack_protection (rtx, HOST_WIDE_INT *, tree *, int);
extern bool asan_protect_global (tree); extern bool asan_protect_global (tree);
extern void initialize_sanitizer_builtins (void);
/* Alias set for accessing the shadow memory. */ /* Alias set for accessing the shadow memory. */
extern alias_set_type asan_shadow_set; extern alias_set_type asan_shadow_set;
......
...@@ -253,6 +253,8 @@ DEF_FUNCTION_TYPE_2 (BT_FN_INT_INT_FILEPTR, ...@@ -253,6 +253,8 @@ DEF_FUNCTION_TYPE_2 (BT_FN_INT_INT_FILEPTR,
BT_INT, BT_INT, BT_FILEPTR) BT_INT, BT_INT, BT_FILEPTR)
DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTRMODE_PTR, DEF_FUNCTION_TYPE_2 (BT_FN_VOID_PTRMODE_PTR,
BT_VOID, BT_PTRMODE, BT_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_VALIST_REF_VALIST_ARG, DEF_FUNCTION_TYPE_2 (BT_FN_VOID_VALIST_REF_VALIST_ARG,
BT_VOID, BT_VALIST_REF, BT_VALIST_ARG) BT_VOID, BT_VALIST_REF, BT_VALIST_ARG)
DEF_FUNCTION_TYPE_2 (BT_FN_LONG_LONG_LONG, DEF_FUNCTION_TYPE_2 (BT_FN_LONG_LONG_LONG,
......
...@@ -156,7 +156,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -156,7 +156,7 @@ along with GCC; see the file COPYING3. If not see
#define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ #define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
true, true, true, ATTRS, true, \ true, true, true, ATTRS, true, \
flag_tsan) (flag_asan || flag_tsan))
/* Define an attribute list for math functions that are normally /* Define an attribute list for math functions that are normally
"impure" because some of them may write into global memory for "impure" because some of them may write into global memory for
......
/* This file contains the definitions and documentation for the
Address Sanitizer and Thread Sanitizer builtins used in the GNU compiler.
Copyright (C) 2012 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* Before including this file, you should define a macro:
DEF_SANITIZER_BUILTIN (ENUM, NAME, TYPE, ATTRS)
See builtins.def for details.
The builtins are created by the C-family of FEs in c-family/c-common.c,
for other FEs by asan.c. */
/* Address Sanitizer */
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_INIT, "__asan_init",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD1, "__asan_report_load1",
BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD2, "__asan_report_load2",
BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD4, "__asan_report_load4",
BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD8, "__asan_report_load8",
BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_LOAD16, "__asan_report_load16",
BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE1, "__asan_report_store1",
BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE2, "__asan_report_store2",
BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE4, "__asan_report_store4",
BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE8, "__asan_report_store8",
BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REPORT_STORE16, "__asan_report_store16",
BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_REGISTER_GLOBALS,
"__asan_register_globals",
BT_FN_VOID_PTR_PTRMODE, ATTR_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_ASAN_UNREGISTER_GLOBALS,
"__asan_unregister_globals",
BT_FN_VOID_PTR_PTRMODE, ATTR_NOTHROW_LEAF_LIST)
/* Thread Sanitizer */
DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_INIT, "__tsan_init", DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_INIT, "__tsan_init",
BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST) BT_FN_VOID, ATTR_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_FUNC_ENTRY, "__tsan_func_entry", DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_FUNC_ENTRY, "__tsan_func_entry",
...@@ -6,23 +65,23 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_FUNC_EXIT, "__tsan_func_exit", ...@@ -6,23 +65,23 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_FUNC_EXIT, "__tsan_func_exit",
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_VPTR_UPDATE, "__tsan_vptr_update", DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_VPTR_UPDATE, "__tsan_vptr_update",
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ_1, "__tsan_read1", DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ1, "__tsan_read1",
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ_2, "__tsan_read2", DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ2, "__tsan_read2",
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ_4, "__tsan_read4", DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ4, "__tsan_read4",
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ_8, "__tsan_read8", DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ8, "__tsan_read8",
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ_16, "__tsan_read16", DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_READ16, "__tsan_read16",
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE_1, "__tsan_write1", DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE1, "__tsan_write1",
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE_2, "__tsan_write2", DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE2, "__tsan_write2",
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE_4, "__tsan_write4", DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE4, "__tsan_write4",
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE_8, "__tsan_write8", DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE8, "__tsan_write8",
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE_16, "__tsan_write16", DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_WRITE16, "__tsan_write16",
BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST) BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
...@@ -37,6 +37,8 @@ along with GCC; see the file COPYING3. If not see ...@@ -37,6 +37,8 @@ along with GCC; see the file COPYING3. If not see
#include "target.h" #include "target.h"
#include "cgraph.h" #include "cgraph.h"
#include "diagnostic.h" #include "diagnostic.h"
#include "tsan.h"
#include "asan.h"
/* Number of instrumented memory accesses in the current function. */ /* Number of instrumented memory accesses in the current function. */
...@@ -49,20 +51,20 @@ get_memory_access_decl (bool is_write, unsigned size) ...@@ -49,20 +51,20 @@ get_memory_access_decl (bool is_write, unsigned size)
enum built_in_function fcode; enum built_in_function fcode;
if (size <= 1) if (size <= 1)
fcode = is_write ? BUILT_IN_TSAN_WRITE_1 fcode = is_write ? BUILT_IN_TSAN_WRITE1
: BUILT_IN_TSAN_READ_1; : BUILT_IN_TSAN_READ1;
else if (size <= 3) else if (size <= 3)
fcode = is_write ? BUILT_IN_TSAN_WRITE_2 fcode = is_write ? BUILT_IN_TSAN_WRITE2
: BUILT_IN_TSAN_READ_2; : BUILT_IN_TSAN_READ2;
else if (size <= 7) else if (size <= 7)
fcode = is_write ? BUILT_IN_TSAN_WRITE_4 fcode = is_write ? BUILT_IN_TSAN_WRITE4
: BUILT_IN_TSAN_READ_4; : BUILT_IN_TSAN_READ4;
else if (size <= 15) else if (size <= 15)
fcode = is_write ? BUILT_IN_TSAN_WRITE_8 fcode = is_write ? BUILT_IN_TSAN_WRITE8
: BUILT_IN_TSAN_READ_8; : BUILT_IN_TSAN_READ8;
else else
fcode = is_write ? BUILT_IN_TSAN_WRITE_16 fcode = is_write ? BUILT_IN_TSAN_WRITE16
: BUILT_IN_TSAN_READ_16; : BUILT_IN_TSAN_READ16;
return builtin_decl_implicit (fcode); return builtin_decl_implicit (fcode);
} }
...@@ -285,6 +287,7 @@ instrument_func_exit (void) ...@@ -285,6 +287,7 @@ instrument_func_exit (void)
static unsigned static unsigned
tsan_pass (void) tsan_pass (void)
{ {
initialize_sanitizer_builtins ();
if (instrument_memory_accesses ()) if (instrument_memory_accesses ())
{ {
instrument_func_entry (); instrument_func_entry ();
...@@ -298,8 +301,7 @@ tsan_pass (void) ...@@ -298,8 +301,7 @@ tsan_pass (void)
static bool static bool
tsan_gate (void) tsan_gate (void)
{ {
return flag_tsan != 0 return flag_tsan != 0;
&& builtin_decl_implicit_p (BUILT_IN_TSAN_INIT);
} }
/* Inserts __tsan_init () into the list of CTORs. */ /* Inserts __tsan_init () into the list of CTORs. */
...@@ -307,11 +309,10 @@ tsan_gate (void) ...@@ -307,11 +309,10 @@ tsan_gate (void)
void void
tsan_finish_file (void) tsan_finish_file (void)
{ {
tree ctor_statements; tree ctor_statements = NULL_TREE;
tree init_decl;
ctor_statements = NULL_TREE; initialize_sanitizer_builtins ();
init_decl = builtin_decl_implicit (BUILT_IN_TSAN_INIT); tree init_decl = builtin_decl_implicit (BUILT_IN_TSAN_INIT);
append_to_statement_list (build_call_expr (init_decl, 0), append_to_statement_list (build_call_expr (init_decl, 0),
&ctor_statements); &ctor_statements);
cgraph_build_static_cdtor ('I', ctor_statements, cgraph_build_static_cdtor ('I', ctor_statements,
...@@ -343,8 +344,7 @@ struct gimple_opt_pass pass_tsan = ...@@ -343,8 +344,7 @@ struct gimple_opt_pass pass_tsan =
static bool static bool
tsan_gate_O0 (void) tsan_gate_O0 (void)
{ {
return flag_tsan != 0 && !optimize return flag_tsan != 0 && !optimize;
&& builtin_decl_implicit_p (BUILT_IN_TSAN_INIT);
} }
struct gimple_opt_pass pass_tsan_O0 = struct gimple_opt_pass pass_tsan_O0 =
......
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