Commit 94fce891 by Jakub Jelinek Committed by Jakub Jelinek

asan.c (asan_init_shadow_ptr_types): Move earlier in the file.

	* 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.

From-SVN: r194355
parent 8d28afb4
2012-12-10 Jakub Jelinek <jakub@redhat.com>
* 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.
2012-12-10 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/neon.ml (opcode): Add Vrintn, Vrinta, Vrintp, Vrintm,
......@@ -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;
}
......
......@@ -3249,11 +3249,23 @@ output_constant_def_contents (rtx symbol)
place_block_symbol (symbol);
else
{
bool asan_protected = false;
align = DECL_ALIGN (decl);
switch_to_section (get_constant_section (exp, align));
if (flag_asan && TREE_CODE (exp) == STRING_CST
&& asan_protect_global (exp))
{
asan_protected = true;
align = MAX (align, ASAN_RED_ZONE_SIZE * BITS_PER_UNIT);
}
if (align > BITS_PER_UNIT)
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
assemble_constant_contents (exp, XSTR (symbol, 0), align);
if (asan_protected)
{
HOST_WIDE_INT size = get_constant_size (exp);
assemble_zeros (asan_red_zone_size (size));
}
}
if (flag_mudflap)
mudflap_enqueue_constant (exp);
......@@ -6157,7 +6169,9 @@ categorize_decl_for_section (const_tree decl, int reloc)
return SECCAT_TEXT;
else if (TREE_CODE (decl) == STRING_CST)
{
if (flag_mudflap) /* or !flag_merge_constants */
if (flag_mudflap
|| (flag_asan && asan_protect_global (CONST_CAST_TREE (decl))))
/* or !flag_merge_constants */
return SECCAT_RODATA;
else
return SECCAT_RODATA_MERGE_STR;
......@@ -6181,7 +6195,8 @@ categorize_decl_for_section (const_tree decl, int reloc)
}
else if (reloc & targetm.asm_out.reloc_rw_mask ())
ret = reloc == 1 ? SECCAT_DATA_REL_RO_LOCAL : SECCAT_DATA_REL_RO;
else if (reloc || flag_merge_constants < 2)
else if (reloc || flag_merge_constants < 2 || flag_mudflap
|| (flag_asan && asan_protect_global (CONST_CAST_TREE (decl))))
/* C and C++ don't allow different variables to share the same
location. -fmerge-all-constants allows even that (at the
expense of not conforming). */
......
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