Add support for ASan odr_indicator.

config/

        * bootstrap-asan.mk: Replace LSAN_OPTIONS=detect_leaks=0 with
        ASAN_OPTIONS=detect_leaks=0:use_odr_indicator=1.

gcc/

        * asan.c (asan_global_struct): Refactor.
        (create_odr_indicator): New function.
        (asan_needs_odr_indicator_p): Likewise.
        (is_odr_indicator): Likewise.
        (asan_add_global): Introduce odr_indicator_ptr. Pass it into global's
        constructor.
        (asan_protect_global): Do not protect odr indicators.

gcc/c-family/

	* c-attribs.c (asan odr indicator): New attribute.
	(handle_asan_odr_indicator_attribute): New function.

gcc/testsuite/

        * c-c++-common/asan/no-redundant-odr-indicators-1.c: New test.

From-SVN: r243153
This commit is contained in:
Maxim Ostapenko 2016-12-02 07:39:27 +00:00 committed by Maxim Ostapenko
parent b06496b161
commit 84b0769e33
8 changed files with 135 additions and 9 deletions

View File

@ -1,3 +1,8 @@
2016-12-02 Maxim Ostapenko <m.ostapenko@samsung.com>
* bootstrap-asan.mk: Replace LSAN_OPTIONS=detect_leaks=0 with
ASAN_OPTIONS=detect_leaks=0:use_odr_indicator=1.
2016-12-01 Matthias Klose <doko@ubuntu.com> 2016-12-01 Matthias Klose <doko@ubuntu.com>
* pkg.m4: Remove. * pkg.m4: Remove.

View File

@ -1,7 +1,7 @@
# This option enables -fsanitize=address for stage2 and stage3. # This option enables -fsanitize=address for stage2 and stage3.
# Suppress LeakSanitizer in bootstrap. # Suppress LeakSanitizer in bootstrap.
export LSAN_OPTIONS="detect_leaks=0" export ASAN_OPTIONS=detect_leaks=0:use_odr_indicator=1
STAGE2_CFLAGS += -fsanitize=address STAGE2_CFLAGS += -fsanitize=address
STAGE3_CFLAGS += -fsanitize=address STAGE3_CFLAGS += -fsanitize=address

View File

@ -1,3 +1,13 @@
2016-12-02 Maxim Ostapenko <m.ostapenko@samsung.com>
* asan.c (asan_global_struct): Refactor.
(create_odr_indicator): New function.
(asan_needs_odr_indicator_p): Likewise.
(is_odr_indicator): Likewise.
(asan_add_global): Introduce odr_indicator_ptr. Pass it into global's
constructor.
(asan_protect_global): Do not protect odr indicators.
2016-12-01 Jeff Law <law@redhat.com> 2016-12-01 Jeff Law <law@redhat.com>
* tree-ssa-threadedge.c * tree-ssa-threadedge.c

View File

@ -1388,6 +1388,16 @@ asan_needs_local_alias (tree decl)
return DECL_WEAK (decl) || !targetm.binds_local_p (decl); return DECL_WEAK (decl) || !targetm.binds_local_p (decl);
} }
/* Return true if DECL, a global var, is an artificial ODR indicator symbol
therefore doesn't need protection. */
static bool
is_odr_indicator (tree decl)
{
return (DECL_ARTIFICIAL (decl)
&& lookup_attribute ("asan odr indicator", DECL_ATTRIBUTES (decl)));
}
/* Return true if DECL is a VAR_DECL that should be protected /* Return true if DECL is a VAR_DECL that should be protected
by Address Sanitizer, by appending a red zone with protected by Address Sanitizer, by appending a red zone with protected
shadow memory after it and aligning it to at least shadow memory after it and aligning it to at least
@ -1436,7 +1446,8 @@ asan_protect_global (tree decl)
|| ASAN_RED_ZONE_SIZE * BITS_PER_UNIT > MAX_OFILE_ALIGNMENT || ASAN_RED_ZONE_SIZE * BITS_PER_UNIT > MAX_OFILE_ALIGNMENT
|| !valid_constant_size_p (DECL_SIZE_UNIT (decl)) || !valid_constant_size_p (DECL_SIZE_UNIT (decl))
|| DECL_ALIGN_UNIT (decl) > 2 * ASAN_RED_ZONE_SIZE || DECL_ALIGN_UNIT (decl) > 2 * ASAN_RED_ZONE_SIZE
|| TREE_TYPE (decl) == ubsan_get_source_location_type ()) || TREE_TYPE (decl) == ubsan_get_source_location_type ()
|| is_odr_indicator (decl))
return false; return false;
rtl = DECL_RTL (decl); rtl = DECL_RTL (decl);
@ -2266,14 +2277,15 @@ asan_dynamic_init_call (bool after_p)
static tree static tree
asan_global_struct (void) asan_global_struct (void)
{ {
static const char *field_names[8] static const char *field_names[]
= { "__beg", "__size", "__size_with_redzone", = { "__beg", "__size", "__size_with_redzone",
"__name", "__module_name", "__has_dynamic_init", "__location", "__odr_indicator"}; "__name", "__module_name", "__has_dynamic_init", "__location",
tree fields[8], ret; "__odr_indicator" };
int i; tree fields[ARRAY_SIZE (field_names)], ret;
unsigned i;
ret = make_node (RECORD_TYPE); ret = make_node (RECORD_TYPE);
for (i = 0; i < 8; i++) for (i = 0; i < ARRAY_SIZE (field_names); i++)
{ {
fields[i] fields[i]
= build_decl (UNKNOWN_LOCATION, FIELD_DECL, = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
@ -2295,6 +2307,63 @@ asan_global_struct (void)
return ret; return ret;
} }
/* Create and return odr indicator symbol for DECL.
TYPE is __asan_global struct type as returned by asan_global_struct. */
static tree
create_odr_indicator (tree decl, tree type)
{
char *name;
tree uptr = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (type)));
tree decl_name
= (HAS_DECL_ASSEMBLER_NAME_P (decl) ? DECL_ASSEMBLER_NAME (decl)
: DECL_NAME (decl));
/* DECL_NAME theoretically might be NULL. Bail out with 0 in this case. */
if (decl_name == NULL_TREE)
return build_int_cst (uptr, 0);
size_t len = strlen (IDENTIFIER_POINTER (decl_name)) + sizeof ("__odr_asan_");
name = XALLOCAVEC (char, len);
snprintf (name, len, "__odr_asan_%s", IDENTIFIER_POINTER (decl_name));
#ifndef NO_DOT_IN_LABEL
name[sizeof ("__odr_asan") - 1] = '.';
#elif !defined(NO_DOLLAR_IN_LABEL)
name[sizeof ("__odr_asan") - 1] = '$';
#endif
tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (name),
char_type_node);
TREE_ADDRESSABLE (var) = 1;
TREE_READONLY (var) = 0;
TREE_THIS_VOLATILE (var) = 1;
DECL_GIMPLE_REG_P (var) = 0;
DECL_ARTIFICIAL (var) = 1;
DECL_IGNORED_P (var) = 1;
TREE_STATIC (var) = 1;
TREE_PUBLIC (var) = 1;
DECL_VISIBILITY (var) = DECL_VISIBILITY (decl);
DECL_VISIBILITY_SPECIFIED (var) = DECL_VISIBILITY_SPECIFIED (decl);
TREE_USED (var) = 1;
tree ctor = build_constructor_va (TREE_TYPE (var), 1, NULL_TREE,
build_int_cst (unsigned_type_node, 0));
TREE_CONSTANT (ctor) = 1;
TREE_STATIC (ctor) = 1;
DECL_INITIAL (var) = ctor;
DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("asan odr indicator"),
NULL, DECL_ATTRIBUTES (var));
make_decl_rtl (var);
varpool_node::finalize_decl (var);
return fold_convert (uptr, build_fold_addr_expr (var));
}
/* Return true if DECL, a global var, might be overridden and needs
an additional odr indicator symbol. */
static bool
asan_needs_odr_indicator_p (tree decl)
{
return !DECL_ARTIFICIAL (decl) && !DECL_WEAK (decl) && TREE_PUBLIC (decl);
}
/* Append description of a single global DECL into vector V. /* Append description of a single global DECL into vector V.
TYPE is __asan_global struct type as returned by asan_global_struct. */ TYPE is __asan_global struct type as returned by asan_global_struct. */
@ -2335,6 +2404,9 @@ asan_add_global (tree decl, tree type, vec<constructor_elt, va_gc> *v)
assemble_alias (refdecl, DECL_ASSEMBLER_NAME (decl)); assemble_alias (refdecl, DECL_ASSEMBLER_NAME (decl));
} }
tree odr_indicator_ptr
= (asan_needs_odr_indicator_p (decl) ? create_odr_indicator (decl, type)
: build_int_cst (uptr, 0));
CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE,
fold_convert (const_ptr_type_node, fold_convert (const_ptr_type_node,
build_fold_addr_expr (refdecl))); build_fold_addr_expr (refdecl)));
@ -2382,8 +2454,7 @@ asan_add_global (tree decl, tree type, vec<constructor_elt, va_gc> *v)
else else
locptr = build_int_cst (uptr, 0); locptr = build_int_cst (uptr, 0);
CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, locptr); CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, locptr);
/* TODO: support ODR indicators. */ CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, odr_indicator_ptr);
CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, 0));
init = build_constructor (type, vinner); init = build_constructor (type, vinner);
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init); CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
} }

View File

@ -1,3 +1,8 @@
2016-12-02 Maxim Ostapenko <m.ostapenko@samsung.com>
* c-attribs.c (asan odr indicator): New attribute.
(handle_asan_odr_indicator_attribute): New function.
2016-11-26 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> 2016-11-26 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
* c-common.c (c_common_nodes_and_builtins): Remove initialization of * c-common.c (c_common_nodes_and_builtins): Remove initialization of

View File

@ -57,6 +57,8 @@ static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree,
int, bool *); int, bool *);
static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int, static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int,
bool *); bool *);
static tree handle_asan_odr_indicator_attribute (tree *, tree, tree, int,
bool *);
static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *); static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *);
static tree handle_noinline_attribute (tree *, tree, tree, int, bool *); static tree handle_noinline_attribute (tree *, tree, tree, int, bool *);
static tree handle_noclone_attribute (tree *, tree, tree, int, bool *); static tree handle_noclone_attribute (tree *, tree, tree, int, bool *);
@ -292,6 +294,9 @@ const struct attribute_spec c_common_attribute_table[] =
{ "no_sanitize_undefined", 0, 0, true, false, false, { "no_sanitize_undefined", 0, 0, true, false, false,
handle_no_sanitize_undefined_attribute, handle_no_sanitize_undefined_attribute,
false }, false },
{ "asan odr indicator", 0, 0, true, false, false,
handle_asan_odr_indicator_attribute,
false },
{ "warning", 1, 1, true, false, false, { "warning", 1, 1, true, false, false,
handle_error_attribute, false }, handle_error_attribute, false },
{ "error", 1, 1, true, false, false, { "error", 1, 1, true, false, false,
@ -591,6 +596,15 @@ handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int,
return NULL_TREE; return NULL_TREE;
} }
/* Handle an "asan odr indicator" attribute; arguments as in
struct attribute_spec.handler. */
static tree
handle_asan_odr_indicator_attribute (tree *, tree, tree, int, bool *)
{
return NULL_TREE;
}
/* Handle a "stack_protect" attribute; arguments as in /* Handle a "stack_protect" attribute; arguments as in
struct attribute_spec.handler. */ struct attribute_spec.handler. */

View File

@ -1,3 +1,7 @@
2016-12-02 Maxim Ostapenko <m.ostapenko@samsung.com>
* c-c++-common/asan/no-redundant-odr-indicators-1.c: New test.
2016-12-01 Elizebeth Punnoose <elizebeth.punnoose@hpe.com> 2016-12-01 Elizebeth Punnoose <elizebeth.punnoose@hpe.com>
PR fortran/77505 PR fortran/77505

View File

@ -0,0 +1,17 @@
/* { dg-do compile } */
/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
/* Local variables should not have odr indicators. */
static int a = 2;
/* Thread local variables should not have odr indicators. */
__thread int b = 3;
/* Externally visible variables should have odr indicators. */
int c = 1;
int main () {
return 0;
}
/* { dg-final { scan-assembler-not "odr_asan\[\.\$\]a" } } */
/* { dg-final { scan-assembler-not "odr_asan\[\.\$\]b" } } */
/* { dg-final { scan-assembler "odr_asan\[\.\$\]c" } } */