diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-10 12:14:36 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-10 12:14:36 +0000 |
commit | 55b58027644caba54158d5ee8fa9ddf43fbf7acb (patch) | |
tree | 3bd1c13134ce9fb42d46d64f6d4cfee4d5b21d3f /gcc/asan.c | |
parent | 614aede0da661b3519e751fe6ab234e45c40fe37 (diff) | |
download | ppe42-gcc-55b58027644caba54158d5ee8fa9ddf43fbf7acb.tar.gz ppe42-gcc-55b58027644caba54158d5ee8fa9ddf43fbf7acb.zip |
* asan.c (asan_init_shadow_ptr_types): Move earlier in the file.
Call initialize_sanitizer_builtins at the end.
(asan_pp_string): Use TREE_TYPE (shadow_ptr_types[0])
as character type instead of char_type_node.
(asan_emit_stack_protection): Call asan_init_shadow_ptr_types
if shadow_ptr_types isn't initialized.
(asan_protect_global): Return true for STRING_CSTs except those
created by asan_pp_string.
(count_string_csts, add_string_csts): New functions.
(struct asan_add_string_csts_data): New type.
(asan_finish_file): Clear flag_asan at the beginning, restore at the
end. Traverse constant_pool_htab () to look for protected
STRING_CSTs. Don't call initialize_sanitizer_builtins,
instead call asan_init_shadow_ptr_types if shadow_ptr_types isn't
initialized yet.
(asan_instrument): Don't call initialize_sanitizer_builtins.
* varasm.c (output_constant_def_contents): If STRING_CST should be
asan protected, align it sufficiently and emit padding after it.
(categorize_decl_for_section): If flag_asan, don't put STRING_CSTs
that should be asan protected into mergeable sections. For
-fmerge-all-constants, ignore it for -fmudflap or if decl is
asan protected.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194355 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/asan.c')
-rw-r--r-- | gcc/asan.c | 110 |
1 files changed, 89 insertions, 21 deletions
diff --git a/gcc/asan.c b/gcc/asan.c index b8f36cb5851..6c8ef187189 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -212,6 +212,21 @@ alias_set_type asan_shadow_set = -1; alias set is used for all shadow memory accesses. */ static GTY(()) tree shadow_ptr_types[2]; +/* Initialize shadow_ptr_types array. */ + +static void +asan_init_shadow_ptr_types (void) +{ + asan_shadow_set = new_alias_set (); + shadow_ptr_types[0] = build_distinct_type_copy (signed_char_type_node); + TYPE_ALIAS_SET (shadow_ptr_types[0]) = asan_shadow_set; + shadow_ptr_types[0] = build_pointer_type (shadow_ptr_types[0]); + shadow_ptr_types[1] = build_distinct_type_copy (short_integer_type_node); + TYPE_ALIAS_SET (shadow_ptr_types[1]) = asan_shadow_set; + shadow_ptr_types[1] = build_pointer_type (shadow_ptr_types[1]); + initialize_sanitizer_builtins (); +} + /* Asan pretty-printer, used for buidling of the description STRING_CSTs. */ static pretty_printer asan_pp; static bool asan_pp_initialized; @@ -234,10 +249,11 @@ asan_pp_string (void) size_t len = strlen (buf); tree ret = build_string (len + 1, buf); TREE_TYPE (ret) - = build_array_type (char_type_node, build_index_type (size_int (len))); + = build_array_type (TREE_TYPE (shadow_ptr_types[0]), + build_index_type (size_int (len))); TREE_READONLY (ret) = 1; TREE_STATIC (ret) = 1; - return build1 (ADDR_EXPR, build_pointer_type (char_type_node), ret); + return build1 (ADDR_EXPR, shadow_ptr_types[0], ret); } /* Return a CONST_INT representing 4 subsequent shadow memory bytes. */ @@ -276,6 +292,9 @@ asan_emit_stack_protection (rtx base, HOST_WIDE_INT *offsets, tree *decls, unsigned char cur_shadow_byte = ASAN_STACK_MAGIC_LEFT; tree str_cst; + if (shadow_ptr_types[0] == NULL_TREE) + asan_init_shadow_ptr_types (); + /* First of all, prepare the description string. */ if (!asan_pp_initialized) asan_pp_initialize (); @@ -430,6 +449,16 @@ asan_protect_global (tree decl) rtx rtl, symbol; section *sect; + if (TREE_CODE (decl) == STRING_CST) + { + /* Instrument all STRING_CSTs except those created + by asan_pp_string here. */ + if (shadow_ptr_types[0] != NULL_TREE + && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE + && TREE_TYPE (TREE_TYPE (decl)) == TREE_TYPE (shadow_ptr_types[0])) + return false; + return true; + } if (TREE_CODE (decl) != VAR_DECL /* TLS vars aren't statically protectable. */ || DECL_THREAD_LOCAL_P (decl) @@ -1580,6 +1609,50 @@ initialize_sanitizer_builtins (void) #undef DEF_SANITIZER_BUILTIN } +/* Called via htab_traverse. Count number of emitted + STRING_CSTs in the constant hash table. */ + +static int +count_string_csts (void **slot, void *data) +{ + struct constant_descriptor_tree *desc + = (struct constant_descriptor_tree *) *slot; + if (TREE_CODE (desc->value) == STRING_CST + && TREE_ASM_WRITTEN (desc->value) + && asan_protect_global (desc->value)) + ++*((unsigned HOST_WIDE_INT *) data); + return 1; +} + +/* Helper structure to pass two parameters to + add_string_csts. */ + +struct asan_add_string_csts_data +{ + tree type; + vec<constructor_elt, va_gc> *v; +}; + +/* Called via htab_traverse. Call asan_add_global + on emitted STRING_CSTs from the constant hash table. */ + +static int +add_string_csts (void **slot, void *data) +{ + struct constant_descriptor_tree *desc + = (struct constant_descriptor_tree *) *slot; + if (TREE_CODE (desc->value) == STRING_CST + && TREE_ASM_WRITTEN (desc->value) + && asan_protect_global (desc->value)) + { + struct asan_add_string_csts_data *aascd + = (struct asan_add_string_csts_data *) data; + asan_add_global (SYMBOL_REF_DECL (XEXP (desc->rtl, 0)), + aascd->type, aascd->v); + } + return 1; +} + /* Needs to be GTY(()), because cgraph_build_static_cdtor may invoke ggc_collect. */ static GTY(()) tree asan_ctor_statements; @@ -1595,13 +1668,20 @@ asan_finish_file (void) struct varpool_node *vnode; unsigned HOST_WIDE_INT gcount = 0; - initialize_sanitizer_builtins (); + if (shadow_ptr_types[0] == NULL_TREE) + asan_init_shadow_ptr_types (); + /* Avoid instrumenting code in the asan ctors/dtors. + We don't need to insert padding after the description strings, + nor after .LASAN* array. */ + flag_asan = 0; 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) if (asan_protect_global (vnode->symbol.decl)) ++gcount; + htab_t const_desc_htab = constant_pool_htab (); + htab_traverse (const_desc_htab, count_string_csts, &gcount); if (gcount) { tree type = asan_global_struct (), var, ctor; @@ -1622,6 +1702,10 @@ asan_finish_file (void) FOR_EACH_DEFINED_VARIABLE (vnode) if (asan_protect_global (vnode->symbol.decl)) asan_add_global (vnode->symbol.decl, TREE_TYPE (type), v); + struct asan_add_string_csts_data aascd; + aascd.type = TREE_TYPE (type); + aascd.v = v; + htab_traverse (const_desc_htab, add_string_csts, &aascd); ctor = build_constructor (type, v); TREE_CONSTANT (ctor) = 1; TREE_STATIC (ctor) = 1; @@ -1644,20 +1728,7 @@ asan_finish_file (void) } cgraph_build_static_cdtor ('I', asan_ctor_statements, MAX_RESERVED_INIT_PRIORITY - 1); -} - -/* Initialize shadow_ptr_types array. */ - -static void -asan_init_shadow_ptr_types (void) -{ - asan_shadow_set = new_alias_set (); - shadow_ptr_types[0] = build_distinct_type_copy (signed_char_type_node); - TYPE_ALIAS_SET (shadow_ptr_types[0]) = asan_shadow_set; - shadow_ptr_types[0] = build_pointer_type (shadow_ptr_types[0]); - shadow_ptr_types[1] = build_distinct_type_copy (short_integer_type_node); - TYPE_ALIAS_SET (shadow_ptr_types[1]) = asan_shadow_set; - shadow_ptr_types[1] = build_pointer_type (shadow_ptr_types[1]); + flag_asan = 1; } /* Instrument the current function. */ @@ -1666,10 +1737,7 @@ static unsigned int asan_instrument (void) { if (shadow_ptr_types[0] == NULL_TREE) - { - asan_init_shadow_ptr_types (); - initialize_sanitizer_builtins (); - } + asan_init_shadow_ptr_types (); transform_statements (); return 0; } |