From patchwork Fri Jun 15 12:59:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 929932 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-479799-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="LyFyorSS"; dkim-atps=neutral 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 416gZD2DCQz9s3C for ; Fri, 15 Jun 2018 23:00:03 +1000 (AEST) 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:cc:subject:message-id:reply-to:mime-version :content-type; q=dns; s=default; b=K7zYJ0yo2p9qyzBnCfg8nkh23KQRz kCiqM+p62GDVPI49y5RUb3KiSgcnanzJ4fysO4Dd2MLIpu1y+b2dBgl9U3p21ISu p3mxX1Q68MDHSY/md1uagpisesUWtmnIKK2e1MvTyMbJzE56VM3AQxH8Jynrhh/R HJ44BoXTSdTJpM= 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:cc:subject:message-id:reply-to:mime-version :content-type; s=default; bh=7zZVb9lykTjtN7xio+7qp29K9y4=; b=LyF yorSS3inH5kBukX98f4qzUfbLlcswkGvCMAf7vSz+Ppqa5kmuGB062f0Goz4l32O MBBliVbs247jPUHwAIpuVjc4L3OmKTFz1zk7WltDG8crtRB3QZlN9QRQclqPdohy bXeRKJeOhu7hZShFn0Ai0NOdyu4NTVwkAe09qz7o= Received: (qmail 34100 invoked by alias); 15 Jun 2018 12:59:55 -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 34083 invoked by uid 89); 15 Jun 2018 12:59:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, NO_DNS_FOR_FROM autolearn=ham version=3.3.2 spammy=mshstk, gol, UD:i386.opt, i386.opt X-HELO: mga09.intel.com Received: from mga09.intel.com (HELO mga09.intel.com) (134.134.136.24) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 15 Jun 2018 12:59:51 +0000 X-Amp-Result: UNSCANNABLE X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Jun 2018 05:59:49 -0700 X-ExtLoop1: 1 Received: from gnu-skx-1.sc.intel.com ([172.25.70.206]) by orsmga007.jf.intel.com with ESMTP; 15 Jun 2018 05:59:49 -0700 Received: by gnu-skx-1.sc.intel.com (Postfix, from userid 1000) id 637562C012F; Fri, 15 Jun 2018 05:59:49 -0700 (PDT) Date: Fri, 15 Jun 2018 05:59:49 -0700 From: "H.J. Lu" To: gcc-patches@gcc.gnu.org Cc: Uros Bizjak , Igor Tsimbalist Subject: [PATCH] i386; Add -mmanual-endbr and cf_check function attribute Message-ID: <20180615125949.GA114203@intel.com> Reply-To: "H.J. Lu" MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.10.0 (2018-05-17) Currently GCC inserts ENDBR instruction at entries of all non-static functions, unless LTO compilation is used. Marking all functions, which are not called indirectly with nocf_check attribute, is not ideal since 99% of functions in a program may be of this kind. This patch adds -mmanual-endbr and cf_check function attribute. They can be used together with -fcf-protection such that ENDBR instruction is inserted only at entries of functions with cf_check attribute. It can limit number of ENDBR instructions to reduce program size. OK for trubk? H.J. ----- gcc/ * config/i386/i386.c (rest_of_insert_endbranch): Insert ENDBR at the function entry only when -mmanual-endbr isn't used or there is cf_check function attribute. (ix86_attribute_table): Add cf_check. * config/i386/i386.opt: Add -mmanual-endbr. * doc/extend.texi: Document cf_check attribute. * doc/invoke.texi: Document -mmanual-endbr. gcc/testsuite/ * gcc.target/i386/cf_check-1.c: New test. * gcc.target/i386/cf_check-2.c: Likewise. * gcc.target/i386/cf_check-3.c: Likewise. * gcc.target/i386/cf_check-4.c: Likewise. * gcc.target/i386/cf_check-5.c: Likewise. --- gcc/config/i386/i386.c | 5 +++++ gcc/config/i386/i386.opt | 5 +++++ gcc/doc/extend.texi | 7 +++++++ gcc/doc/invoke.texi | 9 ++++++++- gcc/testsuite/gcc.target/i386/cf_check-1.c | 11 +++++++++++ gcc/testsuite/gcc.target/i386/cf_check-2.c | 11 +++++++++++ gcc/testsuite/gcc.target/i386/cf_check-3.c | 11 +++++++++++ gcc/testsuite/gcc.target/i386/cf_check-4.c | 10 ++++++++++ gcc/testsuite/gcc.target/i386/cf_check-5.c | 9 +++++++++ 9 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/i386/cf_check-1.c create mode 100644 gcc/testsuite/gcc.target/i386/cf_check-2.c create mode 100644 gcc/testsuite/gcc.target/i386/cf_check-3.c create mode 100644 gcc/testsuite/gcc.target/i386/cf_check-4.c create mode 100644 gcc/testsuite/gcc.target/i386/cf_check-5.c diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 95cfa05ce61..d356e0e7acd 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -2604,6 +2604,9 @@ rest_of_insert_endbranch (void) if (!lookup_attribute ("nocf_check", TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl))) + && (!flag_manual_endbr + || lookup_attribute ("cf_check", + DECL_ATTRIBUTES (cfun->decl))) && !cgraph_node::get (cfun->decl)->only_called_directly_p ()) { cet_eb = gen_nop_endbr (); @@ -45896,6 +45899,8 @@ static const struct attribute_spec ix86_attribute_table[] = ix86_handle_fndecl_attribute, NULL }, { "function_return", 1, 1, true, false, false, false, ix86_handle_fndecl_attribute, NULL }, + { "cf_check", 0, 0, true, false, false, false, + ix86_handle_fndecl_attribute, NULL }, /* End element. */ { NULL, 0, 0, false, false, false, false, NULL, NULL } diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index a34d4acf1a2..aebc023420b 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -1016,6 +1016,11 @@ Target Report Undocumented Var(flag_cet_switch) Init(0) Turn on CET instrumentation for switch statements that use a jump table and an indirect jump. +mmanual-endbr +Target Report Var(flag_manual_endbr) Init(0) +Insert ENDBR instruction at function entry only via cf_check attribute +for CET instrumentation. + mforce-indirect-call Target Report Var(flag_force_indirect_call) Init(0) Make all function calls indirect. diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index e0a84b8b3c5..5fd4a1b22b0 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -5864,6 +5864,13 @@ foo (void) @} @end smallexample +@item cf_check +@cindex @code{cf_check} function attribute, x86 + +The @code{cf_check} attribute on a function is used to inform the +compiler that ENDBR instruction should be placed at the function +entry when @option{-fcf-protection=branch} is enabled. + @end table On the x86, the inliner does not inline a diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 940b84697fa..7ec4267b7b1 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1250,7 +1250,7 @@ See RS/6000 and PowerPC Options. -msse4a -m3dnow -m3dnowa -mpopcnt -mabm -mbmi -mtbm -mfma4 -mxop @gol -mlzcnt -mbmi2 -mfxsr -mxsave -mxsaveopt -mrtm -mlwp @gol -mmwaitx -mclzero -mpku -mthreads -mgfni -mvaes -mwaitpkg @gol --mshstk -mforce-indirect-call -mavx512vbmi2 @gol +-mshstk -mforce-indirect-call -mmanual-endbr -mavx512vbmi2 @gol -mvpclmulqdq -mavx512bitalg -mmovdiri -mmovdir64b -mavx512vpopcntdq -mcldemote @gol -mms-bitfields -mno-align-stringops -minline-all-stringops @gol @@ -27476,6 +27476,13 @@ Force all calls to functions to be indirect. This is useful when using Intel Processor Trace where it generates more precise timing information for function calls. +@item -mmanual-endbr +@opindex mmanual-endbr +Insert ENDBR instruction at function entry only via the @code{cf_check} +function attribute. This is useful when used with the option +@option{-fcf-protection=branch} to control ENDBR insertion at the +function entry. + @item -mcall-ms2sysv-xlogues @opindex mcall-ms2sysv-xlogues @opindex mno-call-ms2sysv-xlogues diff --git a/gcc/testsuite/gcc.target/i386/cf_check-1.c b/gcc/testsuite/gcc.target/i386/cf_check-1.c new file mode 100644 index 00000000000..c433eab854a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cf_check-1.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fcf-protection -mmanual-endbr" } */ +/* { dg-final { scan-assembler-not {\mendbr} } } */ + +extern void bar (void) __attribute__((__cf_check__)); + +void +foo (void) +{ + bar (); +} diff --git a/gcc/testsuite/gcc.target/i386/cf_check-2.c b/gcc/testsuite/gcc.target/i386/cf_check-2.c new file mode 100644 index 00000000000..e2b9c4dbcb2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cf_check-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fcf-protection -mno-manual-endbr" } */ +/* { dg-final { scan-assembler-times {\mendbr} 1 } } */ + +extern void bar (void) __attribute__((__cf_check__)); + +void +foo (void) +{ + bar (); +} diff --git a/gcc/testsuite/gcc.target/i386/cf_check-3.c b/gcc/testsuite/gcc.target/i386/cf_check-3.c new file mode 100644 index 00000000000..d835cc3a21b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cf_check-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fcf-protection=none" } */ +/* { dg-final { scan-assembler-not {\mendbr} } } */ + +extern void bar (void) __attribute__((__cf_check__)); + +void +foo (void) +{ + bar (); +} diff --git a/gcc/testsuite/gcc.target/i386/cf_check-4.c b/gcc/testsuite/gcc.target/i386/cf_check-4.c new file mode 100644 index 00000000000..d6cb27cf20b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cf_check-4.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fcf-protection -mmanual-endbr" } */ +/* { dg-final { scan-assembler-times {\mendbr} 1 } } */ + +extern void foo (void) __attribute__((__cf_check__)); + +void +foo (void) +{ +} diff --git a/gcc/testsuite/gcc.target/i386/cf_check-5.c b/gcc/testsuite/gcc.target/i386/cf_check-5.c new file mode 100644 index 00000000000..f2c0c5c2c09 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cf_check-5.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fcf-protection -mmanual-endbr" } */ +/* { dg-final { scan-assembler-times {\mendbr} 1 } } */ + +__attribute__((__cf_check__)) +void +foo (void) +{ +}