From patchwork Mon Nov 7 08:31:18 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Ostapenko X-Patchwork-Id: 81007 Delivered-To: patch@linaro.org Received: by 10.140.97.165 with SMTP id m34csp897803qge; Mon, 7 Nov 2016 00:31:48 -0800 (PST) X-Received: by 10.98.108.4 with SMTP id h4mr11393294pfc.11.1478507508048; Mon, 07 Nov 2016 00:31:48 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id f10si30074121pgn.62.2016.11.07.00.31.47 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 07 Nov 2016 00:31:48 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-440571-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-440571-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-440571-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=JU41rLkbPROY0mRTol lQVMnUjjeeaVmQxCb9FO5qIpMroOyQf6IQW5eHRiuawgHriUztN7o+T74yx7SFJ4 kITK7cLG8ykxt00k2xv+2QnSN9N2Ce0S2dSg6wnxf2yVmgPWbZSPiG82OCkUjGoG RcfabSUYLuk+OAlY56rmhXzWI= 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=ckYcMYRtrJxl7ZMVXWS6v6/n dHQ=; b=k+6wpkgXvnux/HRXszaDoUApGdvBhTDjaqhyWgYOVGohdkdAzLVwZR9P MoOGWuUxt3jkzBs0HIHFsFi1Ow14WsI6eNXbyl1MnyQaRPrr0nNWIgNPnmqZw60u p6mP7Mi1+XEcoH3iAgF9u4sRGvRhf7NVGgl6ZVIcMrAV7oDYRZA= Received: (qmail 100121 invoked by alias); 7 Nov 2016 08:31:36 -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 100058 invoked by uid 89); 7 Nov 2016 08:31:35 -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=postpone, sk:!target, fold_convert, sk:create_ X-HELO: mailout4.w1.samsung.com Received: from mailout4.w1.samsung.com (HELO mailout4.w1.samsung.com) (210.118.77.14) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 07 Nov 2016 08:31:25 +0000 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout4.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OG900LW2JO8RW40@mailout4.w1.samsung.com> for gcc-patches@gcc.gnu.org; Mon, 07 Nov 2016 08:31:20 +0000 (GMT) Received: from eusmges5.samsung.com (unknown [203.254.199.245]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20161107083120eucas1p29d31f432b60fd5eab3a15cd25b4ef594~EtrhB_S0k1309613096eucas1p2E; Mon, 7 Nov 2016 08:31:20 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges5.samsung.com (EUCPMTA) with SMTP id 73.2B.19540.7DB30285; Mon, 7 Nov 2016 08:31:19 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20161107083119eucas1p25c96348950eded7dd68ae9813db3c2cb~EtrgYcoiY0611206112eucas1p2v; Mon, 7 Nov 2016 08:31:19 +0000 (GMT) Received: from eusync2.samsung.com ( [203.254.199.212]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id E6.1F.07726.5DB30285; Mon, 7 Nov 2016 08:31:17 +0000 (GMT) Received: from [106.109.129.18] by eusync2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OG90056LJO6NK30@eusync2.samsung.com>; Mon, 07 Nov 2016 08:31:19 +0000 (GMT) Subject: [PATCH 7/7] Libsanitizer merge from upstream r285547. To: GCC Patches Cc: Jakub Jelinek , Kostya Serebryany , Yuri Gribov From: Maxim Ostapenko Message-id: <58203BD6.7060800@samsung.com> Date: Mon, 07 Nov 2016 11:31:18 +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: <582039C4.4040606@samsung.com> Content-type: multipart/mixed; boundary=------------070807020807030900020204 X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20161107083119eucas1p25c96348950eded7dd68ae9813db3c2cb 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> X-IsSubscribed: yes This patch tries to implement odr indicators functionality at compiler side. We emit new __odr_asan_XXX symbol for each instrumented global that indicates whether this global was already registered and the library checks this indicator symbol at runtime. For some globals (e.g. static or hidden) the odr indicator is not needed, thus we can skip the indicator for them and pass zero to runtime. If this patch is undesirable at this stage, we can probably postpone it until GCC 8 though. >From 137f139972a89259b9d8521e13ecb76fd2cef433 Mon Sep 17 00:00:00 2001 From: Maxim Ostapenko Date: Fri, 28 Oct 2016 10:22:03 +0300 Subject: [PATCH 7/7] 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/testsuite/ * c-c++-common/asan/no-redundant-odr-indicators-1.c: New test. --- config/ChangeLog | 5 ++ config/bootstrap-asan.mk | 2 +- gcc/ChangeLog | 10 +++ gcc/asan.c | 76 +++++++++++++++++++--- gcc/testsuite/ChangeLog | 4 ++ .../asan/no-redundant-odr-indicators-1.c | 17 +++++ 6 files changed, 105 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/asan/no-redundant-odr-indicators-1.c diff --git a/config/ChangeLog b/config/ChangeLog index 3b0092b..0c75185 100644 --- a/config/ChangeLog +++ b/config/ChangeLog @@ -1,3 +1,8 @@ +2016-11-07 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 1da0ef9..527cafa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,15 @@ 2016-11-07 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-07 Maxim Ostapenko + * asan.h (asan_intercepted_p): Handle BUILT_IN_STRCSPN, BUILT_IN_STRPBRK, BUILT_IN_STRSPN and BUILT_IN_STRSTR. diff --git a/gcc/asan.c b/gcc/asan.c index fdc84bd..b54110a 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -1329,6 +1329,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) +{ + const char *sym_name = IDENTIFIER_POINTER (DECL_NAME (decl)); + return strstr(sym_name, "_.__odr_asan_") == sym_name; +} + /* 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 @@ -1377,7 +1387,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); @@ -2197,14 +2208,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, @@ -2226,6 +2238,52 @@ 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) = TREE_ADDRESSABLE (decl); + TREE_READONLY (var) = 0; + TREE_THIS_VOLATILE (var) = 1; + DECL_GIMPLE_REG_P (var) = DECL_GIMPLE_REG_P (decl); + DECL_ARTIFICIAL (var) = 1; + DECL_IGNORED_P (var) = DECL_IGNORED_P (decl); + TREE_STATIC (var) = 1; + TREE_PUBLIC (var) = 1; + DECL_VISIBILITY (var) = DECL_VISIBILITY (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; + 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. */ @@ -2266,6 +2324,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))); @@ -2313,8 +2374,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/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index afa77a8..7d11a7c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,9 @@ 2016-11-07 Maxim Ostapenko + * c-c++-common/asan/no-redundant-odr-indicators-1.c: New test. + +2016-11-07 Maxim Ostapenko + * c-c++-common/asan/default_options.h: New file. * c-c++-common/asan/strcasestr-1.c: New test. * c-c++-common/asan/strcasestr-2.c: Likewise. 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.*" } } */ -- 1.9.1