From patchwork Wed Nov 2 09:51:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Martin_Li=C5=A1ka?= X-Patchwork-Id: 80458 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp44804qge; Wed, 2 Nov 2016 02:52:20 -0700 (PDT) X-Received: by 10.99.172.26 with SMTP id v26mr4403404pge.164.1478080340666; Wed, 02 Nov 2016 02:52:20 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id p75si2009027pfa.165.2016.11.02.02.52.20 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 02 Nov 2016 02:52:20 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-440147-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-440147-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-440147-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:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; q=dns; s=default; b=WbNzi1k4k61TiNnGl yidafkZ3ANyVWqhUzC6EWYj4PoG9BF8kaWD/AML4hjoYJguElxP8zyzUFsIEBvoz VPzqeO7kUECbIGktMBwivuZn6iLSijAiMt9//56+YPs40HkFBL1yGjYUjbuJVFb7 jRxpjh8kAW3APx5+Dg/BTi9yXY= 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:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; s=default; bh=eOedmPIqWZvIqkdSL1jyWdb Snn4=; b=L0Sck+tQuhf1WYkNlT6jINe2qr58129jeUNxwCwB17IpXoLTTsvMV4I BL7hiq+Y2NmOeDTA4NIEr4IEqSHxrHfRDEYEXtibupxnSrzQFuS2FFiZSggAjDmZ q3GYTLZ+SYBWsiLCA2pDfkZXIZFngnRw+GmoFTWCRpAKrXWMtoTk= Received: (qmail 95493 invoked by alias); 2 Nov 2016 09:52:04 -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 95467 invoked by uid 89); 2 Nov 2016 09:52:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, SPF_PASS autolearn=ham version=3.3.2 spammy=2227, 2897 X-HELO: mx2.suse.de Received: from mx2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 02 Nov 2016 09:51:53 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 0FFF5ABFB; Wed, 2 Nov 2016 09:51:51 +0000 (UTC) Subject: Re: [PATCH, RFC] Introduce -fsanitize=use-after-scope (v2) To: Jakub Jelinek References: <20160512104156.GY28550@tucnak.redhat.com> <57348F45.5020700@suse.cz> <20160818133609.GN14857@tucnak.redhat.com> <98f408c5-7e1e-6fd8-e589-34f8de2f4455@suse.cz> <20161007111347.GF7282@tucnak.redhat.com> <20161021142617.GG7282@tucnak.redhat.com> <3a109250-0440-7438-8e1f-7e5c6d8b6580@suse.cz> <20161027172358.GN3541@tucnak.redhat.com> <606cd948-6cba-02a4-f114-35900ab53203@suse.cz> <20161101151219.GT3541@tucnak.redhat.com> Cc: GCC Patches From: =?UTF-8?Q?Martin_Li=c5=a1ka?= Message-ID: <268c6807-f5d3-926d-2571-72817d57fb5f@suse.cz> Date: Wed, 2 Nov 2016 10:51:50 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 MIME-Version: 1.0 In-Reply-To: <20161101151219.GT3541@tucnak.redhat.com> X-IsSubscribed: yes On 11/01/2016 04:12 PM, Jakub Jelinek wrote: > On Tue, Nov 01, 2016 at 03:53:46PM +0100, Martin Liška wrote: >> @@ -1504,7 +1505,7 @@ non_rewritable_lvalue_p (tree lhs) >> >> static void >> maybe_optimize_var (tree var, bitmap addresses_taken, bitmap not_reg_needs, >> - bitmap suitable_for_renaming) >> + bitmap suitable_for_renaming, bitmap marked_nonaddressable) >> { >> /* Global Variables, result decls cannot be changed. */ >> if (is_global_var (var) >> @@ -1522,6 +1523,7 @@ maybe_optimize_var (tree var, bitmap addresses_taken, bitmap not_reg_needs, >> || !bitmap_bit_p (not_reg_needs, DECL_UID (var)))) >> { >> TREE_ADDRESSABLE (var) = 0; >> + bitmap_set_bit (marked_nonaddressable, DECL_UID (var)); > > Why do you need the marked_nonaddressable bitmap? Because the later loop (which visits every gimple statement) iterates only if there's an entry in suitable_for_renaming. > >> if (is_gimple_reg (var)) >> bitmap_set_bit (suitable_for_renaming, DECL_UID (var)); >> if (dump_file) >> @@ -1550,20 +1552,43 @@ maybe_optimize_var (tree var, bitmap addresses_taken, bitmap not_reg_needs, >> } >> } >> >> -/* Compute TREE_ADDRESSABLE and DECL_GIMPLE_REG_P for local variables. */ >> +/* Return true when STMT is ASAN mark where second argument is an address >> + of a local variable. */ >> >> -void >> -execute_update_addresses_taken (void) >> +static bool >> +is_asan_mark_p (gimple *stmt) >> +{ >> + if (!gimple_call_internal_p (stmt, IFN_ASAN_MARK)) >> + return false; >> + >> + tree addr = get_base_address (gimple_call_arg (stmt, 1)); >> + if (TREE_CODE (addr) == ADDR_EXPR >> + && TREE_CODE (TREE_OPERAND (addr, 0)) == VAR_DECL) > > Just check here if dropping TREE_ADDRESSABLE from the VAR (use VAR_P btw) > would turn it into is_gimple_reg), and don't return true if not. Well, the predicate is called once before maybe_optimize_var, thus I need to have it conservative and not consider TREE_ADDRESSABLE flag. Having argument would work for that? > >> + return true; >> + >> + return false; >> +} >> + >> +/* Compute TREE_ADDRESSABLE and DECL_GIMPLE_REG_P for local variables. >> + If SANITIZE_ASAN_MARK is set to true, sanitize also ASAN_MARK built-ins. */ >> + >> + >> +static void >> +execute_update_addresses_taken (bool sanitize_asan_mark = false) > > I wonder if the sanitize_asan_mark wouldn't better be some PROP_* property > set during the asan pass and kept on until end of compilation of that > function. That means even if a var only addressable because of ASAN_MARK is > discovered after this pass we'd still be able to rewrite it into SSA. It's doable (please see attached patch) and also nicer. However, one would need to extend curr_properties to long type as we already use 16 existing values. Martin > > Jakub > >From ad5f68a010674118fac7ca8b6953f7b99fd3c2a8 Mon Sep 17 00:00:00 2001 From: marxin Date: Tue, 1 Nov 2016 11:21:20 +0100 Subject: [PATCH] Use-after-scope: do not mark variables that are no longer addressable gcc/ChangeLog: 2016-11-02 Martin Liska * asan.c: Update properties_provided and todo_flags_finish. * function.h (struct GTY): Change int to long as there's not enough space for a new value. * tree-pass.h: Define PROP_asan_check_done. * tree-ssa.c (maybe_optimize_var): Add new argument. (is_asan_mark_p): New function. (execute_update_addresses_taken): Handle ASAN_MARK internal fns. --- gcc/asan.c | 5 +++-- gcc/function.h | 2 +- gcc/tree-pass.h | 1 + gcc/tree-ssa.c | 69 +++++++++++++++++++++++++++++++++++++++++++++------------ 4 files changed, 60 insertions(+), 17 deletions(-) diff --git a/gcc/asan.c b/gcc/asan.c index 95495d2..94ee877 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -59,6 +59,7 @@ along with GCC; see the file COPYING3. If not see #include "params.h" #include "builtins.h" #include "fnmatch.h" +#include "tree-ssa.h" /* AddressSanitizer finds out-of-bounds and use-after-free bugs with <2x slowdown on average. @@ -2993,10 +2994,10 @@ const pass_data pass_data_asan = OPTGROUP_NONE, /* optinfo_flags */ TV_NONE, /* tv_id */ ( PROP_ssa | PROP_cfg | PROP_gimple_leh ), /* properties_required */ - 0, /* properties_provided */ + PROP_asan_check_done, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_update_ssa, /* todo_flags_finish */ + TODO_update_ssa | TODO_update_address_taken, /* todo_flags_finish */ }; class pass_asan : public gimple_opt_pass diff --git a/gcc/function.h b/gcc/function.h index e854c7f..5600488 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -289,7 +289,7 @@ struct GTY(()) function { location_t function_end_locus; /* Properties used by the pass manager. */ - unsigned int curr_properties; + unsigned long curr_properties; unsigned int last_verified; /* Non-null if the function does something that would prevent it from diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index da9ba13..ea43593 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -222,6 +222,7 @@ protected: of math functions; the current choices have been optimized. */ +#define PROP_asan_check_done (1 << 16) /* ASAN check is emitted */ #define PROP_trees \ (PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh | PROP_gimple_lomp) diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 135952b..1492f47 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -41,6 +41,7 @@ along with GCC; see the file COPYING3. If not see #include "cfgexpand.h" #include "tree-cfg.h" #include "tree-dfa.h" +#include "asan.h" /* Pointer map of variable mappings, keyed by edge. */ static hash_map > *edge_var_maps; @@ -1504,7 +1505,7 @@ non_rewritable_lvalue_p (tree lhs) static void maybe_optimize_var (tree var, bitmap addresses_taken, bitmap not_reg_needs, - bitmap suitable_for_renaming) + bitmap suitable_for_renaming, bitmap marked_nonaddressable) { /* Global Variables, result decls cannot be changed. */ if (is_global_var (var) @@ -1522,6 +1523,7 @@ maybe_optimize_var (tree var, bitmap addresses_taken, bitmap not_reg_needs, || !bitmap_bit_p (not_reg_needs, DECL_UID (var)))) { TREE_ADDRESSABLE (var) = 0; + bitmap_set_bit (marked_nonaddressable, DECL_UID (var)); if (is_gimple_reg (var)) bitmap_set_bit (suitable_for_renaming, DECL_UID (var)); if (dump_file) @@ -1550,6 +1552,22 @@ maybe_optimize_var (tree var, bitmap addresses_taken, bitmap not_reg_needs, } } +/* Return true when STMT is ASAN mark where second argument is an address + of a local variable. */ + +static bool +is_asan_mark_p (gimple *stmt) +{ + if (!gimple_call_internal_p (stmt, IFN_ASAN_MARK)) + return false; + + tree addr = get_base_address (gimple_call_arg (stmt, 1)); + if (TREE_CODE (addr) == ADDR_EXPR && VAR_P (TREE_OPERAND (addr, 0))) + return true; + + return false; +} + /* Compute TREE_ADDRESSABLE and DECL_GIMPLE_REG_P for local variables. */ void @@ -1559,9 +1577,12 @@ execute_update_addresses_taken (void) bitmap addresses_taken = BITMAP_ALLOC (NULL); bitmap not_reg_needs = BITMAP_ALLOC (NULL); bitmap suitable_for_renaming = BITMAP_ALLOC (NULL); + bitmap marked_nonaddressable = BITMAP_ALLOC (NULL); tree var; unsigned i; + bool sanitize_asan_mark = cfun->curr_properties & PROP_asan_check_done; + timevar_push (TV_ADDRESS_TAKEN); /* Collect into ADDRESSES_TAKEN all variables whose address is taken within @@ -1575,17 +1596,23 @@ execute_update_addresses_taken (void) enum gimple_code code = gimple_code (stmt); tree decl; - if (code == GIMPLE_CALL - && optimize_atomic_compare_exchange_p (stmt)) + if (code == GIMPLE_CALL) { - /* For __atomic_compare_exchange_N if the second argument - is &var, don't mark var addressable; - if it becomes non-addressable, we'll rewrite it into - ATOMIC_COMPARE_EXCHANGE call. */ - tree arg = gimple_call_arg (stmt, 1); - gimple_call_set_arg (stmt, 1, null_pointer_node); - gimple_ior_addresses_taken (addresses_taken, stmt); - gimple_call_set_arg (stmt, 1, arg); + if (optimize_atomic_compare_exchange_p (stmt)) + { + /* For __atomic_compare_exchange_N if the second argument + is &var, don't mark var addressable; + if it becomes non-addressable, we'll rewrite it into + ATOMIC_COMPARE_EXCHANGE call. */ + tree arg = gimple_call_arg (stmt, 1); + gimple_call_set_arg (stmt, 1, null_pointer_node); + gimple_ior_addresses_taken (addresses_taken, stmt); + gimple_call_set_arg (stmt, 1, arg); + } + else if (sanitize_asan_mark && is_asan_mark_p (stmt)) + ; + else + gimple_ior_addresses_taken (addresses_taken, stmt); } else /* Note all addresses taken by the stmt. */ @@ -1675,15 +1702,17 @@ execute_update_addresses_taken (void) for -g vs. -g0. */ for (var = DECL_ARGUMENTS (cfun->decl); var; var = DECL_CHAIN (var)) maybe_optimize_var (var, addresses_taken, not_reg_needs, - suitable_for_renaming); + suitable_for_renaming, marked_nonaddressable); FOR_EACH_VEC_SAFE_ELT (cfun->local_decls, i, var) maybe_optimize_var (var, addresses_taken, not_reg_needs, - suitable_for_renaming); + suitable_for_renaming, marked_nonaddressable); /* Operand caches need to be recomputed for operands referencing the updated variables and operands need to be rewritten to expose bare symbols. */ - if (!bitmap_empty_p (suitable_for_renaming)) + if (!bitmap_empty_p (suitable_for_renaming) + || (asan_sanitize_use_after_scope () + && !bitmap_empty_p (marked_nonaddressable))) { FOR_EACH_BB_FN (bb, cfun) for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);) @@ -1841,6 +1870,17 @@ execute_update_addresses_taken (void) continue; } } + else if (sanitize_asan_mark && is_asan_mark_p (stmt)) + { + tree var = TREE_OPERAND (gimple_call_arg (stmt, 1), 0); + if (bitmap_bit_p (suitable_for_renaming, DECL_UID (var)) + || bitmap_bit_p (marked_nonaddressable, DECL_UID (var))) + { + unlink_stmt_vdef (stmt); + gsi_remove (&gsi, true); + continue; + } + } for (i = 0; i < gimple_call_num_args (stmt); ++i) { tree *argp = gimple_call_arg_ptr (stmt, i); @@ -1896,6 +1936,7 @@ execute_update_addresses_taken (void) BITMAP_FREE (not_reg_needs); BITMAP_FREE (addresses_taken); BITMAP_FREE (suitable_for_renaming); + BITMAP_FREE (marked_nonaddressable); timevar_pop (TV_ADDRESS_TAKEN); } -- 2.10.1