From patchwork Thu Nov 6 11:48:18 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Enkovich X-Patchwork-Id: 407416 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 977B1140098 for ; Thu, 6 Nov 2014 22:48:36 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=vm7BC5d3BvLhsG8mz7lScd5ha+9Q4lLAMt1jsut6x8gmFphD1YAoI G/JwIoeJkrF8BLE8f5w2kHmIFDp8aIHVXSEtR9Y9X9mb8iZaZk+pTIx4cznZzokC LBILUFGV6omrjbBgUaDmbtfgEk2ulb8HcMGRSIzVf2leReA+ZXqvHc= 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:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=vvEN67VTd47UBHis6Enmd9U3FZk=; b=vn/DJ5rboaLm2500xWMg ANvxbskx9zdJJp25gt/bqUrD77R0PTqozhBM7SqzffPH9QFXppNTYJpmu8tGPrvB 33hUYb2OK51I0ghJYPYGRJJ2A+FTsIgfoMQ7c2/pIn4NvMw6CfbkVukQ0AtszFSC AIHzPcF5+ODt8rwMWkUf9GE= Received: (qmail 30483 invoked by alias); 6 Nov 2014 11:48:29 -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 30471 invoked by uid 89); 6 Nov 2014 11:48:28 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f44.google.com Received: from mail-pa0-f44.google.com (HELO mail-pa0-f44.google.com) (209.85.220.44) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Thu, 06 Nov 2014 11:48:26 +0000 Received: by mail-pa0-f44.google.com with SMTP id bj1so1131204pad.3 for ; Thu, 06 Nov 2014 03:48:25 -0800 (PST) X-Received: by 10.66.252.8 with SMTP id zo8mr3993681pac.12.1415274504978; Thu, 06 Nov 2014 03:48:24 -0800 (PST) Received: from msticlxl57.ims.intel.com ([192.55.54.42]) by mx.google.com with ESMTPSA id s7sm5715594pdi.72.2014.11.06.03.48.22 for (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 06 Nov 2014 03:48:24 -0800 (PST) Date: Thu, 6 Nov 2014 14:48:18 +0300 From: Ilya Enkovich To: gcc-patches@gcc.gnu.org Subject: [PATCH, Pointer Bounds Checker, Builtins instrumentation 1/5] Builtin codes and decls Message-ID: <20141106114818.GB53257@msticlxl57.ims.intel.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Hi, This is the first patch in a series to enable builtin function calls instrumentation by Poitner Bounds Checker. Previously builtins instrumentation was disabled in checker because it allowed two function calls with the same function code have different set of arguments. Here I try another approach where function codes are not reused by instrumented calls. Basic idea is to provide each function code with a pair to be used for instrumented call. It's achieved by additional include of builtins.def into built_in_class enum. Instrumented builtins shouldn't be visible for users. Also when checker is disabled we don't need decls for them at all. Therefore function decls for instrumented function are not created at compiler initialization, but lazily created on demand. These decls are mainly requested by checker itslef and by LTO streamer to read instrumented code. This patch introduces new builtin codes, functions for builtin clones creation and modifies LTO streamer. Thanks, Ilya --- 2014-11-06 Ilya Enkovich * tree-core.h (built_in_class): Add builtin codes to be used by Pointer Bounds Checker for instrumented builtin functions. * tree-streamer-in.c: Include ipa-chkp.h. (streamer_get_builtin_tree): Create instrumented decl if required. * ipa-chkp.h (chkp_maybe_clone_builtin_fndecl): New. * ipa-chkp.c (chkp_build_instrumented_fndecl): Support builtin function decls. (chkp_maybe_clone_builtin_fndecl): New. (chkp_maybe_create_clone): Support builtin function decls. diff --git a/gcc/ipa-chkp.c b/gcc/ipa-chkp.c index f910583..691adfd 100644 --- a/gcc/ipa-chkp.c +++ b/gcc/ipa-chkp.c @@ -130,6 +130,16 @@ chkp_build_instrumented_fndecl (tree fndecl) make own copy. */ DECL_ATTRIBUTES (new_decl) = copy_list (DECL_ATTRIBUTES (fndecl)); + /* Change builtin function code. */ + if (DECL_BUILT_IN (new_decl)) + { + gcc_assert (DECL_BUILT_IN_CLASS (new_decl) == BUILT_IN_NORMAL); + gcc_assert (DECL_FUNCTION_CODE (new_decl) < BEGIN_CHKP_BUILTINS); + DECL_FUNCTION_CODE (new_decl) + = (enum built_in_function)(DECL_FUNCTION_CODE (new_decl) + + BEGIN_CHKP_BUILTINS + 1); + } + return new_decl; } @@ -355,6 +365,30 @@ chkp_add_bounds_params_to_function (tree fndecl) chkp_copy_function_type_adding_bounds (TREE_TYPE (fndecl)); } +tree +chkp_maybe_clone_builtin_fndecl (tree fndecl) +{ + tree clone; + enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); + + gcc_assert (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL + && fcode < BEGIN_CHKP_BUILTINS); + + fcode = (enum built_in_function) (fcode + BEGIN_CHKP_BUILTINS + 1); + clone = builtin_decl_explicit (fcode); + if (clone) + return clone; + + clone = chkp_build_instrumented_fndecl (fndecl); + chkp_add_bounds_params_to_function (clone); + + gcc_assert (DECL_FUNCTION_CODE (clone) == fcode); + + set_builtin_decl (fcode, clone, false); + + return clone; +} + /* Return clone created for instrumentation of NODE or NULL. */ cgraph_node * @@ -365,6 +399,52 @@ chkp_maybe_create_clone (tree fndecl) gcc_assert (!node->instrumentation_clone); + if (DECL_BUILT_IN (fndecl) + && (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL + || DECL_FUNCTION_CODE (fndecl) >= BEGIN_CHKP_BUILTINS)) + return NULL; + + clone = node->instrumented_version; + + /* For builtin functions we may loose and recreate + cgraph node. We should check if we already have + instrumented version. */ + if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL + && fndecl == builtin_decl_explicit (DECL_FUNCTION_CODE (fndecl)) + && !clone) + { + enum built_in_function fncode = DECL_FUNCTION_CODE (fndecl); + tree new_decl; + + fncode = (enum built_in_function) (fncode + BEGIN_CHKP_BUILTINS + 1); + new_decl = builtin_decl_explicit (fncode); + + /* We've actually already created an instrumented clone once. + Restore it. */ + if (new_decl) + { + clone = cgraph_node::get (new_decl); + + if (!clone) + { + gcc_assert (!gimple_has_body_p (fndecl)); + clone = cgraph_node::get_create (new_decl); + clone->externally_visible = node->externally_visible; + clone->local = node->local; + clone->address_taken = node->address_taken; + clone->thunk = node->thunk; + clone->alias = node->alias; + clone->weakref = node->weakref; + clone->cpp_implicit_alias = node->cpp_implicit_alias; + clone->orig_decl = fndecl; + clone->instrumentation_clone = true; + } + + clone->instrumented_version = node; + node->instrumented_version = clone; + } + } + if (!clone) { tree new_decl = chkp_build_instrumented_fndecl (fndecl); @@ -409,6 +489,15 @@ chkp_maybe_create_clone (tree fndecl) actually copies args list from the original decl. */ chkp_add_bounds_params_to_function (new_decl); + /* Remember builtin fndecl. */ + if (DECL_BUILT_IN_CLASS (clone->decl) == BUILT_IN_NORMAL + && fndecl == builtin_decl_explicit (DECL_FUNCTION_CODE (fndecl))) + { + gcc_assert (!builtin_decl_explicit (DECL_FUNCTION_CODE (clone->decl))); + set_builtin_decl (DECL_FUNCTION_CODE (clone->decl), + clone->decl, false); + } + /* Clones have the same comdat group as originals. */ if (node->same_comdat_group || DECL_ONE_ONLY (node->decl)) diff --git a/gcc/ipa-chkp.h b/gcc/ipa-chkp.h index d4ad113..b2d03ad 100644 --- a/gcc/ipa-chkp.h +++ b/gcc/ipa-chkp.h @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see #define GCC_IPA_CHKP_H extern tree chkp_copy_function_type_adding_bounds (tree orig_type); +extern tree chkp_maybe_clone_builtin_fndecl (tree fndecl); extern cgraph_node *chkp_maybe_create_clone (tree fndecl); #endif /* GCC_IPA_CHKP_H */ diff --git a/gcc/tree-core.h b/gcc/tree-core.h index f8ee8cc..2027bd53 100644 --- a/gcc/tree-core.h +++ b/gcc/tree-core.h @@ -168,6 +168,14 @@ enum built_in_class { enum built_in_function { #include "builtins.def" + BEGIN_CHKP_BUILTINS, + +#undef DEF_BUILTIN +#define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) ENUM##_CHKP, +#include "builtins.def" + + END_CHKP_BUILTINS, + /* Complex division routines in libgcc. These are done via builtins because emit_library_call_value can't handle complex values. */ BUILT_IN_COMPLEX_MUL_MIN, diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c index 371e316..1137029 100644 --- a/gcc/tree-streamer-in.c +++ b/gcc/tree-streamer-in.c @@ -49,6 +49,7 @@ along with GCC; see the file COPYING3. If not see #include "streamer-hooks.h" #include "lto-streamer.h" #include "builtins.h" +#include "ipa-chkp.h" /* Read a STRING_CST from the string table in DATA_IN using input block IB. */ @@ -1128,6 +1129,14 @@ streamer_get_builtin_tree (struct lto_input_block *ib, struct data_in *data_in) if (fcode >= END_BUILTINS) fatal_error ("machine independent builtin code out of range"); result = builtin_decl_explicit (fcode); + if (!result + && fcode > BEGIN_CHKP_BUILTINS + && fcode < END_CHKP_BUILTINS) + { + fcode = (enum built_in_function) (fcode - BEGIN_CHKP_BUILTINS - 1); + result = builtin_decl_explicit (fcode); + result = chkp_maybe_clone_builtin_fndecl (result); + } gcc_assert (result); } else if (fclass == BUILT_IN_MD)