From patchwork Mon Nov 14 08:44:26 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Ostapenko X-Patchwork-Id: 82025 Delivered-To: patch@linaro.org Received: by 10.140.97.165 with SMTP id m34csp905908qge; Mon, 14 Nov 2016 00:44:59 -0800 (PST) X-Received: by 10.99.242.5 with SMTP id v5mr66470497pgh.181.1479113099632; Mon, 14 Nov 2016 00:44:59 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id 2si10286768pfd.204.2016.11.14.00.44.59 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 14 Nov 2016 00:44:59 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-441314-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-441314-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-441314-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:cc:from:message-id:date:mime-version:in-reply-to :content-type:references; q=dns; s=default; b=mlDZ/E8hQcTZV0E7mH lIYwATZ0ZJTbcboy1yJMCIu2OvtsEBzIF7ra+vIvVGocRnmNK7Ku7+KbmmVGOMuc V1iqD+9+JUEw0ZK0EIzyWuSgoOAW8/OV4DqpbUsY02GHq0kKfhxQjVJMiqB307+W lICuHUidetoTCzxgiAexD/slE= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:cc:from:message-id:date:mime-version:in-reply-to :content-type:references; s=default; bh=TYBJO9UtTForIsKuULX41wwg mN4=; b=s17HOSF8nsICR2heNLjsf4CuotJpAMXtHMXl1iPNsECgmb4ep+eFTvUR Fh/PwR0c5Wv1FLZ9fghWJPD3Y0qpUHtLOPLLs9obpI50ueTHxqZiDbeFBjE7v4SS R/oJQppA/XOEPClJ/k1q8C8cv0P7Ot3+aErCwdlXd2yddwvqDkw= Received: (qmail 31285 invoked by alias); 14 Nov 2016 08:44:45 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 31197 invoked by uid 89); 14 Nov 2016 08:44:43 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.7 required=5.0 tests=BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=array_size, 2295, 6, sk:asm_gen, TREE_PUBLIC X-HELO: mailout3.w1.samsung.com Received: from mailout3.w1.samsung.com (HELO mailout3.w1.samsung.com) (210.118.77.13) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 14 Nov 2016 08:44:33 +0000 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout3.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OGM008THIY4RE70@mailout3.w1.samsung.com> for gcc-patches@gcc.gnu.org; Mon, 14 Nov 2016 08:44:28 +0000 (GMT) Received: from eusmges2.samsung.com (unknown [203.254.199.241]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20161114084427eucas1p2bd91ef5cb2b4b7afccb5b908eaa5931e~G3X_itWW62853828538eucas1p26; Mon, 14 Nov 2016 08:44:27 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges2.samsung.com (EUCPMTA) with SMTP id E6.76.02283.B6979285; Mon, 14 Nov 2016 08:44:27 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20161114084427eucas1p2ca7ef732d015742b843d0ca8a2312803~G3X94UaFi2724327243eucas1p29; Mon, 14 Nov 2016 08:44:27 +0000 (GMT) Received: from eusync3.samsung.com ( [203.254.199.213]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id EB.84.07726.F6979285; Mon, 14 Nov 2016 08:44:31 +0000 (GMT) Received: from [106.109.129.18] by eusync3.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OGM002OJIY2UG00@eusync3.samsung.com>; Mon, 14 Nov 2016 08:44:27 +0000 (GMT) Subject: [PATCH v2] Support ASan ODR indicators at compiler side. To: Jakub Jelinek Cc: GCC Patches , Yuri Gribov From: Maxim Ostapenko Message-id: <5829796A.4080602@samsung.com> Date: Mon, 14 Nov 2016 11:44:26 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.5.1 MIME-version: 1.0 In-reply-to: <20161107085233.GD3541@tucnak.redhat.com> Content-type: multipart/mixed; boundary=------------050400060009010701050906 X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20161114084427eucas1p2ca7ef732d015742b843d0ca8a2312803 X-Msg-Generator: CA X-Sender-IP: 182.198.249.179 X-Local-Sender: =?UTF-8?B?TWFrc2ltIE9zdGFwZW5rbxtTUlItU1cgVG9vbHMgTGFiGw==?= =?UTF-8?B?7IK87ISx7KCE7J6QG0VuZ2luZWVy?= X-Global-Sender: =?UTF-8?B?TWF4aW0gT3N0YXBlbmtvG1NSUi1TVyBUb29scyBMYWIbU2Ft?= =?UTF-8?B?c3VuZ8KgRWxlY3Ryb25pY3MbRW5naW5lZXI=?= X-Sender-Code: =?UTF-8?B?QzEwG0NJU0hRG0MxMEdEMDFHRDAxMDE1Nw==?= CMS-TYPE: 201P X-HopCount: 7 X-CMS-RootMailID: 20161107083119eucas1p25c96348950eded7dd68ae9813db3c2cb X-RootMTR: 20161107083119eucas1p25c96348950eded7dd68ae9813db3c2cb References: <582039C4.4040606@samsung.com> <58203BD6.7060800@samsung.com> <20161107085233.GD3541@tucnak.redhat.com> X-IsSubscribed: yes Hi, this is the second attempt to support ASan odr indicators in GCC. I've fixed issues with several flags (e.g.TREE_ADDRESSABLE) and introduced new "asan odr indicator" attribute to distinguish indicators from other symbols. Looks better now? Tested and ASan bootstrapped on x86_64-unknown-linux-gnu. -Maxim 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. diff --git a/config/ChangeLog b/config/ChangeLog index 3b0092b..0c75185 100644 --- a/config/ChangeLog +++ b/config/ChangeLog @@ -1,3 +1,8 @@ +2016-11-14 Maxim Ostapenko + + * bootstrap-asan.mk: Replace LSAN_OPTIONS=detect_leaks=0 with + ASAN_OPTIONS=detect_leaks=0:use_odr_indicator=1. + 2016-06-21 Trevor Saunders * elf.m4: Remove interix support. diff --git a/config/bootstrap-asan.mk b/config/bootstrap-asan.mk index 70baaf9..e73d4c2 100644 --- a/config/bootstrap-asan.mk +++ b/config/bootstrap-asan.mk @@ -1,7 +1,7 @@ # This option enables -fsanitize=address for stage2 and stage3. # Suppress LeakSanitizer in bootstrap. -export LSAN_OPTIONS="detect_leaks=0" +export ASAN_OPTIONS=detect_leaks=0:use_odr_indicator=1 STAGE2_CFLAGS += -fsanitize=address STAGE3_CFLAGS += -fsanitize=address diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a76e3e8..64744b9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-11-14 Maxim Ostapenko + + * 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-11-09 Kugan Vivekanandarajah * ipa-cp.c (ipa_get_jf_pass_through_result): Handle unary expressions. diff --git a/gcc/asan.c b/gcc/asan.c index 6e93ea3..1191ebe 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -1388,6 +1388,16 @@ asan_needs_local_alias (tree 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 by Address Sanitizer, by appending a red zone with protected 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 || !valid_constant_size_p (DECL_SIZE_UNIT (decl)) || 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; rtl = DECL_RTL (decl); @@ -2266,14 +2277,15 @@ asan_dynamic_init_call (bool after_p) static tree asan_global_struct (void) { - static const char *field_names[8] + static const char *field_names[] = { "__beg", "__size", "__size_with_redzone", - "__name", "__module_name", "__has_dynamic_init", "__location", "__odr_indicator"}; - tree fields[8], ret; - int i; + "__name", "__module_name", "__has_dynamic_init", "__location", + "__odr_indicator"}; + tree fields[ARRAY_SIZE (field_names)], ret; + unsigned i; ret = make_node (RECORD_TYPE); - for (i = 0; i < 8; i++) + for (i = 0; i < ARRAY_SIZE (field_names); i++) { fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, @@ -2295,6 +2307,56 @@ asan_global_struct (void) 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 sym_name[100], tmp_name[100]; + static int lasan_odr_ind_cnt = 0; + tree uptr = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (type))); + + snprintf (tmp_name, sizeof (tmp_name), "__odr_asan_%s_", + IDENTIFIER_POINTER (DECL_NAME (decl))); + ASM_GENERATE_INTERNAL_LABEL (sym_name, tmp_name, ++lasan_odr_ind_cnt); + char *asterisk = sym_name; + while ((asterisk = strchr (asterisk, '*'))) + *asterisk = '_'; + tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (sym_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) = VISIBILITY_DEFAULT; + DECL_VISIBILITY_SPECIFIED (var) = 1; + + 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)); + 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. TYPE is __asan_global struct type as returned by asan_global_struct. */ @@ -2335,6 +2397,9 @@ asan_add_global (tree decl, tree type, vec *v) 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, fold_convert (const_ptr_type_node, build_fold_addr_expr (refdecl))); @@ -2382,8 +2447,7 @@ asan_add_global (tree decl, tree type, vec *v) else locptr = build_int_cst (uptr, 0); CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, locptr); - /* TODO: support ODR indicators. */ - CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, 0)); + CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, odr_indicator_ptr); init = build_constructor (type, vinner); CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init); } diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index 925f1b2..44b1f51 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -57,6 +57,8 @@ static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree, int, bool *); static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int, 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_noinline_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, handle_no_sanitize_undefined_attribute, false }, + { "asan odr indicator", 0, 0, true, false, false, + handle_asan_odr_indicator_attribute, + false }, { "warning", 1, 1, true, false, false, handle_error_attribute, false }, { "error", 1, 1, true, false, false, @@ -591,6 +596,22 @@ handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int, return NULL_TREE; } +/* Handle an "asan odr indicator" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_asan_odr_indicator_attribute (tree *node, tree name, tree, int, + bool *no_add_attrs) +{ + if (!VAR_P (*node)) + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + + return NULL_TREE; +} + /* Handle a "stack_protect" attribute; arguments as in struct attribute_spec.handler. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e822e6f..67361a3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-11-14 Maxim Ostapenko + + * c-c++-common/asan/no-redundant-odr-indicators-1.c: New test. + 2016-11-09 Kugan Vivekanandarajah * gcc.dg/ipa/vrp7.c: New test. diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-odr-indicators-1.c b/gcc/testsuite/c-c++-common/asan/no-redundant-odr-indicators-1.c new file mode 100644 index 0000000..ff1f272 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/no-redundant-odr-indicators-1.c @@ -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.*" } } */