x86: Allow -fcf-protection with multi-byte NOPs

Message ID 20180417184224.GA22831@intel.com
State New
Headers show
Series
  • x86: Allow -fcf-protection with multi-byte NOPs
Related show

Commit Message

H.J. Lu April 17, 2018, 6:42 p.m.
-fcf-protection -mcet can't be used with IFUNC features, like symbol
multiversioning or target clone, since IBT/SHSTK are applied to the whole
program and they may be disabled in some functions.  But -fcf-protection
is implemented with multi-byte NOPs on all 64-bit processors as well as
32-bit processors starting with Pentium Pro.  If -fcf-protection requires
-mcet, IFUNC features can't be used on Linux when -fcf-protection is
enabled by default.

This patch changes -fcf-protection to to enable the NOP portion of CET
ISAs unless IBT and/or SHSTK are disabled explicitly.  The rest of CET
ISAs, including intrinsics, still requires -mcet, -mibt or -mshstk.

OK for trunk?

H.J.
---
gcc/

	PR target/85417
	* config/i386/cet.c (file_end_indicate_exec_stack_and_cet):
	Check flag_cf_protection instead of TARGET_IBT and TARGET_SHSTK.
	* config/i386/i386.c (pass_insert_endbranch::gate): Don't check
	TARGET_IBT.
	(ix86_option_override_internal): For -fcf-protection, set
	x_flag_cet to 1 if not set and also check x_flag_cet.
	(ix86_trampoline_init): Don't check TARGET_IBT.
	(x86_output_mi_thunk): Likewise.
	(ix86_notrack_prefixed_insn_p): Likewise.
	* config/i386/i386.md (rdssp<mode>): Also enable for flag_cet.
	(incssp<mode>): Likewise.
	(nop_endbr): Also enable for flag_cet.
	* config/i386/i386.opt (flag_cet): Initialized to -1.

gcc/testsuite/

	PR target/85417
	* c-c++-common/attr-nocf-check-1.c: Compile with
	-fcf-protection=none.
	* c-c++-common/attr-nocf-check-3.c: Likewise.
	* gcc.dg/march-generic.c: Likewise.
	* gcc.target/i386/align-limit.c: Likewise.
	* c-c++-common/fcf-protection-1.c: Remove dg-error for x86
	targets.
	* c-c++-common/fcf-protection-2.c: Likewise.
	* c-c++-common/fcf-protection-3.c: Likewise.
	* c-c++-common/fcf-protection-5.c: Likewise.
	* c-c++-common/fcf-protection-6.c: Remove dg-additional-options
	and dg-error for x86 targets.
	* c-c++-common/fcf-protection-7.c: Likewise.
	* gcc.target/i386/cet-notrack-icf-1.c: Compile with
	-fcf-protection=none -mno-cet.
	* gcc.target/i386/cet-notrack-icf-3.c: Likewise.
	* gcc.target/i386/cet-property-2.c: Compile with
	-fcf-protection=none.
	* gcc.target/i386/indirect-thunk-attr-7.c: Likewise.
	* gcc.target/i386/indirect-thunk-extern-7.c: Likewise.
	* gcc.target/i386/ret-thunk-26.c: Likewise.
	* gcc.target/i386/cet-label-3.c: New test.
	* gcc.target/i386/cet-property-3.c: Likewise.
	* gcc.target/i386/cet-sjlj-7.c: Likewise.
	* gcc.target/i386/pr85417-1.c: Likewise.
	* gcc.target/i386/pr85417-2.c: Likewise.
---
 gcc/config/i386/cet.c                              |  4 +-
 gcc/config/i386/i386.c                             | 23 +++++++----
 gcc/config/i386/i386.md                            |  6 +--
 gcc/config/i386/i386.opt                           |  2 +-
 gcc/testsuite/c-c++-common/attr-nocf-check-1.c     |  1 +
 gcc/testsuite/c-c++-common/attr-nocf-check-3.c     |  1 +
 gcc/testsuite/c-c++-common/fcf-protection-1.c      |  1 -
 gcc/testsuite/c-c++-common/fcf-protection-2.c      |  1 -
 gcc/testsuite/c-c++-common/fcf-protection-3.c      |  1 -
 gcc/testsuite/c-c++-common/fcf-protection-5.c      |  1 -
 gcc/testsuite/c-c++-common/fcf-protection-6.c      |  3 +-
 gcc/testsuite/c-c++-common/fcf-protection-7.c      |  3 +-
 gcc/testsuite/gcc.dg/march-generic.c               |  2 +-
 gcc/testsuite/gcc.target/i386/align-limit.c        |  2 +-
 gcc/testsuite/gcc.target/i386/cet-label-3.c        | 16 ++++++++
 gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c  |  2 +-
 gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c  |  2 +-
 gcc/testsuite/gcc.target/i386/cet-property-2.c     |  2 +-
 gcc/testsuite/gcc.target/i386/cet-property-3.c     | 11 +++++
 gcc/testsuite/gcc.target/i386/cet-sjlj-7.c         | 48 ++++++++++++++++++++++
 .../gcc.target/i386/indirect-thunk-attr-7.c        |  2 +-
 .../gcc.target/i386/indirect-thunk-extern-7.c      |  2 +-
 gcc/testsuite/gcc.target/i386/pr85417-1.c          |  4 ++
 gcc/testsuite/gcc.target/i386/pr85417-2.c          | 17 ++++++++
 gcc/testsuite/gcc.target/i386/ret-thunk-26.c       |  2 +-
 25 files changed, 129 insertions(+), 30 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/cet-label-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/cet-property-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/cet-sjlj-7.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr85417-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr85417-2.c

-- 
2.14.3

Comments

Uros Bizjak April 17, 2018, 6:55 p.m. | #1
On Tue, Apr 17, 2018 at 8:42 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:
> -fcf-protection -mcet can't be used with IFUNC features, like symbol

> multiversioning or target clone, since IBT/SHSTK are applied to the whole

> program and they may be disabled in some functions.  But -fcf-protection

> is implemented with multi-byte NOPs on all 64-bit processors as well as

> 32-bit processors starting with Pentium Pro.  If -fcf-protection requires

> -mcet, IFUNC features can't be used on Linux when -fcf-protection is

> enabled by default.

>

> This patch changes -fcf-protection to to enable the NOP portion of CET

> ISAs unless IBT and/or SHSTK are disabled explicitly.  The rest of CET

> ISAs, including intrinsics, still requires -mcet, -mibt or -mshstk.

>

> OK for trunk?


As said in the PR, NOP sequences have non-zero cost in the executable
(they enlarge the executable), so I don't think this feature should be
enabled by default.

There is always a configure option if someone wants their compiler to
always emit relevant multi-byte nops.

Uros.
H.J. Lu April 17, 2018, 7:03 p.m. | #2
On Tue, Apr 17, 2018 at 11:55 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Tue, Apr 17, 2018 at 8:42 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:

>> -fcf-protection -mcet can't be used with IFUNC features, like symbol

>> multiversioning or target clone, since IBT/SHSTK are applied to the whole

>> program and they may be disabled in some functions.  But -fcf-protection

>> is implemented with multi-byte NOPs on all 64-bit processors as well as

>> 32-bit processors starting with Pentium Pro.  If -fcf-protection requires

>> -mcet, IFUNC features can't be used on Linux when -fcf-protection is

>> enabled by default.

>>

>> This patch changes -fcf-protection to to enable the NOP portion of CET

>> ISAs unless IBT and/or SHSTK are disabled explicitly.  The rest of CET

>> ISAs, including intrinsics, still requires -mcet, -mibt or -mshstk.

>>

>> OK for trunk?

>

> As said in the PR, NOP sequences have non-zero cost in the executable

> (they enlarge the executable), so I don't think this feature should be

> enabled by default.

>

> There is always a configure option if someone wants their compiler to

> always emit relevant multi-byte nops.


What we need is an option to enable -fcf-function with multi-byte NOPs
without -mcet which enables the full CET ISAs.  A configure option
without the corresponding the command-line option makes test and
debug difficult.   I can add

--enable-cf-function-nop or --with-cf-function-nop

with

-fct-function-nop

-- 
H.J.
H.J. Lu April 17, 2018, 7:25 p.m. | #3
On Tue, Apr 17, 2018 at 12:03 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Tue, Apr 17, 2018 at 11:55 AM, Uros Bizjak <ubizjak@gmail.com> wrote:

>> On Tue, Apr 17, 2018 at 8:42 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:

>>> -fcf-protection -mcet can't be used with IFUNC features, like symbol

>>> multiversioning or target clone, since IBT/SHSTK are applied to the whole

>>> program and they may be disabled in some functions.  But -fcf-protection

>>> is implemented with multi-byte NOPs on all 64-bit processors as well as

>>> 32-bit processors starting with Pentium Pro.  If -fcf-protection requires

>>> -mcet, IFUNC features can't be used on Linux when -fcf-protection is

>>> enabled by default.

>>>

>>> This patch changes -fcf-protection to to enable the NOP portion of CET

>>> ISAs unless IBT and/or SHSTK are disabled explicitly.  The rest of CET

>>> ISAs, including intrinsics, still requires -mcet, -mibt or -mshstk.

>>>

>>> OK for trunk?

>>

>> As said in the PR, NOP sequences have non-zero cost in the executable

>> (they enlarge the executable), so I don't think this feature should be

>> enabled by default.

>>

>> There is always a configure option if someone wants their compiler to

>> always emit relevant multi-byte nops.

>

> What we need is an option to enable -fcf-function with multi-byte NOPs

> without -mcet which enables the full CET ISAs.  A configure option

> without the corresponding the command-line option makes test and

> debug difficult.   I can add

>

> --enable-cf-function-nop or --with-cf-function-nop

>

> with

>

> -fct-function-nop

>


How about adding -mno-cet, which enables the NOP portion of CET
ISAs?

-- 
H.J.
H.J. Lu April 17, 2018, 7:25 p.m. | #4
On Tue, Apr 17, 2018 at 12:25 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Tue, Apr 17, 2018 at 12:03 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>> On Tue, Apr 17, 2018 at 11:55 AM, Uros Bizjak <ubizjak@gmail.com> wrote:

>>> On Tue, Apr 17, 2018 at 8:42 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:

>>>> -fcf-protection -mcet can't be used with IFUNC features, like symbol

>>>> multiversioning or target clone, since IBT/SHSTK are applied to the whole

>>>> program and they may be disabled in some functions.  But -fcf-protection

>>>> is implemented with multi-byte NOPs on all 64-bit processors as well as

>>>> 32-bit processors starting with Pentium Pro.  If -fcf-protection requires

>>>> -mcet, IFUNC features can't be used on Linux when -fcf-protection is

>>>> enabled by default.

>>>>

>>>> This patch changes -fcf-protection to to enable the NOP portion of CET

>>>> ISAs unless IBT and/or SHSTK are disabled explicitly.  The rest of CET

>>>> ISAs, including intrinsics, still requires -mcet, -mibt or -mshstk.

>>>>

>>>> OK for trunk?

>>>

>>> As said in the PR, NOP sequences have non-zero cost in the executable

>>> (they enlarge the executable), so I don't think this feature should be

>>> enabled by default.

>>>

>>> There is always a configure option if someone wants their compiler to

>>> always emit relevant multi-byte nops.

>>

>> What we need is an option to enable -fcf-function with multi-byte NOPs

>> without -mcet which enables the full CET ISAs.  A configure option

>> without the corresponding the command-line option makes test and

>> debug difficult.   I can add

>>

>> --enable-cf-function-nop or --with-cf-function-nop

>>

>> with

>>

>> -fct-function-nop

>>

>

> How about adding -mno-cet, which enables the NOP portion of CET


I meant -mnop-cet, not -mno-cet.

> ISAs?

>

> --

> H.J.




-- 
H.J.
H.J. Lu April 18, 2018, 11:24 a.m. | #5
On Tue, Apr 17, 2018 at 12:25 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Tue, Apr 17, 2018 at 12:25 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>> On Tue, Apr 17, 2018 at 12:03 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>>> On Tue, Apr 17, 2018 at 11:55 AM, Uros Bizjak <ubizjak@gmail.com> wrote:

>>>> On Tue, Apr 17, 2018 at 8:42 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:

>>>>> -fcf-protection -mcet can't be used with IFUNC features, like symbol

>>>>> multiversioning or target clone, since IBT/SHSTK are applied to the whole

>>>>> program and they may be disabled in some functions.  But -fcf-protection

>>>>> is implemented with multi-byte NOPs on all 64-bit processors as well as

>>>>> 32-bit processors starting with Pentium Pro.  If -fcf-protection requires

>>>>> -mcet, IFUNC features can't be used on Linux when -fcf-protection is

>>>>> enabled by default.

>>>>>

>>>>> This patch changes -fcf-protection to to enable the NOP portion of CET

>>>>> ISAs unless IBT and/or SHSTK are disabled explicitly.  The rest of CET

>>>>> ISAs, including intrinsics, still requires -mcet, -mibt or -mshstk.

>>>>>

>>>>> OK for trunk?

>>>>

>>>> As said in the PR, NOP sequences have non-zero cost in the executable

>>>> (they enlarge the executable), so I don't think this feature should be

>>>> enabled by default.

>>>>

>>>> There is always a configure option if someone wants their compiler to

>>>> always emit relevant multi-byte nops.

>>>

>>> What we need is an option to enable -fcf-function with multi-byte NOPs

>>> without -mcet which enables the full CET ISAs.  A configure option

>>> without the corresponding the command-line option makes test and

>>> debug difficult.   I can add

>>>

>>> --enable-cf-function-nop or --with-cf-function-nop

>>>

>>> with

>>>

>>> -fct-function-nop

>>>

>>

>> How about adding -mno-cet, which enables the NOP portion of CET

>

> I meant -mnop-cet, not -mno-cet.

>


Here is a patch to add -mnop and use it with -fcf-protection.


-- 
H.J.
From cb4446aa122dfb7711240612c013e4cdbd73971f Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 16 Apr 2018 14:13:10 -0700
Subject: [PATCH] x86: Allow -fcf-protection with multi-byte NOPs

-fcf-protection -mcet can't be used with IFUNC features, like symbol
multiversioning or target clone, since IBT/SHSTK are applied to the whole
program and they may be disabled in some functions.  But -fcf-protection
is implemented with multi-byte NOPs on all 64-bit processors as well as
32-bit processors starting with Pentium Pro.  If -fcf-protection requires
-mcet, IFUNC features can't be used on Linux when -fcf-protection is
enabled by default.

This patch adds -mnop to enable multi-byte NOP code generation which
can be used with -fcf-protection to implement indirect branch and return
address tracking without -mcet.

gcc/

	PR target/85417
	* config/i386/cet.c (file_end_indicate_exec_stack_and_cet):
	Check flag_cf_protection instead of TARGET_IBT and TARGET_SHSTK.
	* config/i386/i386.c (pass_insert_endbranch::gate): Don't check
	TARGET_IBT.
	(ix86_option_override_internal): Allow  -fcf-protection with
	multi-byte NOPs unless CET is disabled explicitly.
	(ix86_trampoline_init): Don't check TARGET_IBT.
	(x86_output_mi_thunk): Likewise.
	(ix86_notrack_prefixed_insn_p): Likewise.
	* config/i386/i386.md (rdssp<mode>): Also enable for flag_nop.
	(incssp<mode>): Likewise.
	(nop_endbr): Likewise.
	* config/i386/i386.opt: Add -mnop.
	* doc/invoke.texi: Document -mnop.

gcc/testsuite/

	PR target/85417
	* c-c++-common/attr-nocf-check-1.c: Compile with
	-fcf-protection=none.
	* c-c++-common/attr-nocf-check-3.c: Likewise.
	* gcc.dg/march-generic.c: Likewise.
	* gcc.target/i386/align-limit.c: Likewise.
	* c-c++-common/fcf-protection-1.c: Compile with -mno-nop for
	x86 targets.
	* c-c++-common/fcf-protection-2.c: Likewise.
	* c-c++-common/fcf-protection-3.c: Likewise.
	* c-c++-common/fcf-protection-5.c: Likewise.
	* c-c++-common/fcf-protection-6.c: Likewise.
	* c-c++-common/fcf-protection-7.c: Likewise.
	* gcc.target/i386/cet-notrack-icf-1.c: Compile with
	-fcf-protection=none.
	* gcc.target/i386/cet-notrack-icf-3.c: Likewise.
	* gcc.target/i386/cet-property-2.c: Likewise.
	* gcc.target/i386/indirect-thunk-attr-7.c: Likewise.
	* gcc.target/i386/indirect-thunk-extern-7.c: Likewise.
	* gcc.target/i386/ret-thunk-26.c: Likewise.
	* gcc.target/i386/cet-label-3.c: New test.
	* gcc.target/i386/cet-property-3.c: Likewise.
	* gcc.target/i386/cet-sjlj-7.c: Likewise.
	* gcc.target/i386/pr85417-1.c: Likewise.
	* gcc.target/i386/pr85417-2.c: Likewise.
	* gcc.target/i386/pr85403.c: Compile with -mno-nop.
---
 gcc/config/i386/cet.c                              |  4 +-
 gcc/config/i386/i386.c                             | 23 +++++++----
 gcc/config/i386/i386.md                            |  6 +--
 gcc/config/i386/i386.opt                           |  4 ++
 gcc/doc/invoke.texi                                | 14 ++++++-
 gcc/testsuite/c-c++-common/attr-nocf-check-1.c     |  1 +
 gcc/testsuite/c-c++-common/attr-nocf-check-3.c     |  1 +
 gcc/testsuite/c-c++-common/fcf-protection-1.c      |  1 +
 gcc/testsuite/c-c++-common/fcf-protection-2.c      |  1 +
 gcc/testsuite/c-c++-common/fcf-protection-3.c      |  1 +
 gcc/testsuite/c-c++-common/fcf-protection-5.c      |  1 +
 gcc/testsuite/c-c++-common/fcf-protection-6.c      |  2 +-
 gcc/testsuite/c-c++-common/fcf-protection-7.c      |  2 +-
 gcc/testsuite/gcc.dg/march-generic.c               |  2 +-
 gcc/testsuite/gcc.target/i386/align-limit.c        |  2 +-
 gcc/testsuite/gcc.target/i386/cet-label-3.c        | 16 ++++++++
 gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c  |  2 +-
 gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c  |  2 +-
 gcc/testsuite/gcc.target/i386/cet-property-2.c     |  2 +-
 gcc/testsuite/gcc.target/i386/cet-property-3.c     | 11 +++++
 gcc/testsuite/gcc.target/i386/cet-sjlj-7.c         | 48 ++++++++++++++++++++++
 .../gcc.target/i386/indirect-thunk-attr-7.c        |  2 +-
 .../gcc.target/i386/indirect-thunk-extern-7.c      |  2 +-
 gcc/testsuite/gcc.target/i386/pr85403.c            |  2 +-
 gcc/testsuite/gcc.target/i386/pr85417-1.c          |  4 ++
 gcc/testsuite/gcc.target/i386/pr85417-2.c          | 17 ++++++++
 gcc/testsuite/gcc.target/i386/ret-thunk-26.c       |  2 +-
 27 files changed, 150 insertions(+), 25 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/cet-label-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/cet-property-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/cet-sjlj-7.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr85417-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr85417-2.c

diff --git a/gcc/config/i386/cet.c b/gcc/config/i386/cet.c
index 4a1e013fdde..eb3be171471 100644
--- a/gcc/config/i386/cet.c
+++ b/gcc/config/i386/cet.c
@@ -34,11 +34,11 @@ file_end_indicate_exec_stack_and_cet (void)
 
   unsigned int feature_1 = 0;
 
-  if (TARGET_IBT)
+  if (flag_cf_protection & CF_BRANCH)
     /* GNU_PROPERTY_X86_FEATURE_1_IBT.  */
     feature_1 |= 0x1;
 
-  if (TARGET_SHSTK)
+  if (flag_cf_protection & CF_RETURN)
     /* GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */
     feature_1 |= 0x2;
 
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 9074526b8a1..b74b3afccf1 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2701,7 +2701,7 @@ public:
   /* opt_pass methods: */
   virtual bool gate (function *)
     {
-      return ((flag_cf_protection & CF_BRANCH) && TARGET_IBT);
+      return ((flag_cf_protection & CF_BRANCH));
     }
 
   virtual unsigned int execute (function *)
@@ -4936,10 +4936,15 @@ ix86_option_override_internal (bool main_args_p,
     = (cf_protection_level) (opts->x_flag_cf_protection & ~CF_SET);
   if (cf_protection != CF_NONE)
     {
+      /* Since -fcf-protection is implemented with multi-byte NOPs on
+	 all 64-bit processors as well as 32-bit processors starting
+	 with Pentium Pro, allow -fcf-protection with multi-byte NOPs
+	 unless CET is disabled explicitly.  */
       switch (cf_protection)
 	{
 	case CF_BRANCH:
-	  if (! TARGET_IBT_P (opts->x_ix86_isa_flags2))
+	  if (!TARGET_IBT_P (opts->x_ix86_isa_flags2)
+	      && !opts->x_flag_nop)
 	    {
 	      error ("%<-fcf-protection=branch%> requires Intel CET "
 		     "support. Use -mcet or -mibt option to enable CET");
@@ -4948,7 +4953,8 @@ ix86_option_override_internal (bool main_args_p,
 	    }
 	  break;
 	case CF_RETURN:
-	  if (! TARGET_SHSTK_P (opts->x_ix86_isa_flags))
+	  if (!TARGET_SHSTK_P (opts->x_ix86_isa_flags)
+	      && !opts->x_flag_nop)
 	    {
 	      error ("%<-fcf-protection=return%> requires Intel CET "
 		     "support. Use -mcet or -mshstk option to enable CET");
@@ -4957,8 +4963,9 @@ ix86_option_override_internal (bool main_args_p,
 	    }
 	  break;
 	case CF_FULL:
-	  if (   ! TARGET_IBT_P (opts->x_ix86_isa_flags2)
-		 || ! TARGET_SHSTK_P (opts->x_ix86_isa_flags))
+	  if ((!TARGET_IBT_P (opts->x_ix86_isa_flags2)
+	       || !TARGET_SHSTK_P (opts->x_ix86_isa_flags))
+	      && !opts->x_flag_nop)
 	    {
 	      error ("%<-fcf-protection=full%> requires Intel CET "
 		     "support. Use -mcet or both of -mibt and "
@@ -30399,7 +30406,7 @@ ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
   rtx mem, fnaddr;
   int opcode;
   int offset = 0;
-  bool need_endbr = (flag_cf_protection & CF_BRANCH) && TARGET_IBT;
+  bool need_endbr = (flag_cf_protection & CF_BRANCH);
 
   fnaddr = XEXP (DECL_RTL (fndecl), 0);
 
@@ -41757,7 +41764,7 @@ x86_output_mi_thunk (FILE *file, tree, HOST_WIDE_INT delta,
   emit_note (NOTE_INSN_PROLOGUE_END);
 
   /* CET is enabled, insert EB instruction.  */
-  if ((flag_cf_protection & CF_BRANCH) && TARGET_IBT)
+  if ((flag_cf_protection & CF_BRANCH))
     emit_insn (gen_nop_endbr ());
 
   /* If VCALL_OFFSET, we'll need THIS in a register.  Might as well
@@ -49757,7 +49764,7 @@ ix86_bnd_prefixed_insn_p (rtx insn)
 static bool
 ix86_notrack_prefixed_insn_p (rtx insn)
 {
-  if (!insn || !((flag_cf_protection & CF_BRANCH) && TARGET_IBT))
+  if (!insn || !((flag_cf_protection & CF_BRANCH)))
     return false;
 
   if (CALL_P (insn))
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 352212094ec..5eef09ef66b 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -20278,7 +20278,7 @@
 (define_insn "rdssp<mode>"
   [(set (match_operand:SWI48x 0 "register_operand" "=r")
 	(unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
-  "TARGET_SHSTK"
+  "TARGET_SHSTK || flag_nop"
   "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
   [(set_attr "length" "6")
    (set_attr "type" "other")])
@@ -20286,7 +20286,7 @@
 (define_insn "incssp<mode>"
   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
 		   UNSPECV_INCSSP)]
-  "TARGET_SHSTK"
+  "TARGET_SHSTK || flag_nop"
   "incssp<mskmodesuffix>\t%0"
   [(set_attr "length" "4")
    (set_attr "type" "other")])
@@ -20341,7 +20341,7 @@
 
 (define_insn "nop_endbr"
   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
-  "TARGET_IBT"
+  "TARGET_IBT || flag_nop"
   "*
 { return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }"
   [(set_attr "length" "4")
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index c063ae8b1ae..8f6d002cd4d 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -1026,6 +1026,10 @@ 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.
 
+mnop
+Target Report Var(flag_nop) Init(0)
+Support multi-byte NOP code generation.
+
 mforce-indirect-call
 Target Report Var(flag_force_indirect_call) Init(0)
 Make all function calls indirect.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 8c0d275626f..46f225817c7 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1261,7 +1261,7 @@ See RS/6000 and PowerPC Options.
 -msse4a  -m3dnow  -m3dnowa  -mpopcnt  -mabm  -mbmi  -mtbm  -mfma4  -mxop @gol
 -mlzcnt  -mbmi2  -mfxsr  -mxsave  -mxsaveopt  -mrtm  -mlwp  -mmpx  @gol
 -mmwaitx  -mclzero  -mpku  -mthreads -mgfni  -mvaes  @gol
--mcet -mibt -mshstk -mforce-indirect-call -mavx512vbmi2 @gol
+-mcet -mibt -mshstk -mnop -mforce-indirect-call -mavx512vbmi2 @gol
 -mvpclmulqdq -mavx512bitalg -mavx512vpopcntdq @gol
 -mms-bitfields  -mno-align-stringops  -minline-all-stringops @gol
 -minline-stringops-dynamically  -mstringop-strategy=@var{alg} @gol
@@ -27461,6 +27461,18 @@ The option has effect only if the @option{-fcf-protection=full} or
 @option{-mshstk} is on by default when the @option{-mcet} option is
 specified.
 
+@item -mnop
+@itemx -mno-nop
+@opindex mnop
+Enable multi-byte NOP code generation.  When @option{-fcf-protection}
+is used to enable code instrumentation of control-flow transfers to
+increase program security, this can be used to generate multi-byte NOPs
+to implement indirect branch and return address tracking without
+@option{-mcet}, @option{-mibt} and @code{-mcet}, which also enable
+CET built-in functions and are incompatible with
+@xref{Function Multiversioning} or @code{target_clones} attribute. This
+is likely only useful together with @option{-fcf-protection}.
+
 @item -mcrc32
 @opindex mcrc32
 This option enables built-in functions @code{__builtin_ia32_crc32qi},
diff --git a/gcc/testsuite/c-c++-common/attr-nocf-check-1.c b/gcc/testsuite/c-c++-common/attr-nocf-check-1.c
index 15f69731b91..c5ac7cb9f86 100644
--- a/gcc/testsuite/c-c++-common/attr-nocf-check-1.c
+++ b/gcc/testsuite/c-c++-common/attr-nocf-check-1.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-additional-options "-fcf-protection=none" } */
 
 int func (int) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */
 int (*fptr) (int) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */
diff --git a/gcc/testsuite/c-c++-common/attr-nocf-check-3.c b/gcc/testsuite/c-c++-common/attr-nocf-check-3.c
index ad1ca7eec9b..02b56cb155e 100644
--- a/gcc/testsuite/c-c++-common/attr-nocf-check-3.c
+++ b/gcc/testsuite/c-c++-common/attr-nocf-check-3.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-additional-options "-fcf-protection=none" } */
 
 int  foo (void) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */
 void (*foo1) (void) __attribute__((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-1.c b/gcc/testsuite/c-c++-common/fcf-protection-1.c
index 8e71f47dde0..06dfb30cd8b 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-1.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-1.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection=full" } */
+/* { dg-additional-options "-mno-nop" { target { i?86-*-* x86_64-*-* } } } */
 /* { dg-error "'-fcf-protection=full' requires Intel CET.*-mcet.*-mibt and -mshstk option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
 /* { dg-error "'-fcf-protection=full' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-2.c b/gcc/testsuite/c-c++-common/fcf-protection-2.c
index d7d6db0e95d..5a15c9ad789 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-2.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-2.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection=branch" } */
+/* { dg-additional-options "-mno-nop" { target { i?86-*-* x86_64-*-* } } } */
 /* { dg-error "'-fcf-protection=branch' requires Intel CET.*-mcet or -mibt option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
 /* { dg-error "'-fcf-protection=branch' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-3.c b/gcc/testsuite/c-c++-common/fcf-protection-3.c
index 5b903c5fa51..5927bdb2752 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-3.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-3.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection=return" } */
+/* { dg-additional-options "-mno-nop" { target { i?86-*-* x86_64-*-* } } } */
 /* { dg-error "'-fcf-protection=return' requires Intel CET.*-mcet or -mshstk option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
 /* { dg-error "'-fcf-protection=return' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-5.c b/gcc/testsuite/c-c++-common/fcf-protection-5.c
index d7a67801e2e..c1e3f493e0b 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-5.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-5.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection" } */
+/* { dg-additional-options "-mno-nop" { target { i?86-*-* x86_64-*-* } } } */
 /* { dg-error "'-fcf-protection=full' requires Intel CET.*-mcet.*-mibt and -mshstk option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
 /* { dg-error "'-fcf-protection=full' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-6.c b/gcc/testsuite/c-c++-common/fcf-protection-6.c
index 532e76e6915..d07744adbeb 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-6.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-6.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection=branch" } */
-/* { dg-additional-options "-mshstk" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-additional-options "-mshstk -mno-nop" { target { i?86-*-* x86_64-*-* } } } */
 /* { dg-error "'-fcf-protection=branch' requires Intel CET.*-mcet or -mibt option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
 /* { dg-error "'-fcf-protection=branch' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-7.c b/gcc/testsuite/c-c++-common/fcf-protection-7.c
index 4c879692708..9eeee4aa146 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-7.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-7.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection=return" } */
-/* { dg-additional-options "-mibt" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-additional-options "-mibt -mno-nop" { target { i?86-*-* x86_64-*-* } } } */
 /* { dg-error "'-fcf-protection=return' requires Intel CET.*-mcet or -mshstk option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
 /* { dg-error "'-fcf-protection=return' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/gcc.dg/march-generic.c b/gcc/testsuite/gcc.dg/march-generic.c
index fb5b83c7d74..f9c00e4a1c1 100644
--- a/gcc/testsuite/gcc.dg/march-generic.c
+++ b/gcc/testsuite/gcc.dg/march-generic.c
@@ -1,6 +1,6 @@
 /* { dg-do compile { target i?86-*-* x86_64-*-* } } */
 /* { dg-skip-if "" { *-*-* } { "-march=*" } { "" } } */
-/* { dg-options "-march=generic" } */
+/* { dg-options "-march=generic -fcf-protection=none" } */
 /* { dg-error "'generic' CPU can be used only for '-mtune=' switch" "" { target *-*-* } 0 } */
 /* { dg-bogus "march" "" { target *-*-* } 0 } */
 int i;
diff --git a/gcc/testsuite/gcc.target/i386/align-limit.c b/gcc/testsuite/gcc.target/i386/align-limit.c
index d3d8dc5656e..849d741189c 100644
--- a/gcc/testsuite/gcc.target/i386/align-limit.c
+++ b/gcc/testsuite/gcc.target/i386/align-limit.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -falign-functions=64 -flimit-function-alignment -march=amdfam10" } */
+/* { dg-options "-O2 -falign-functions=64 -flimit-function-alignment -march=amdfam10 -fcf-protection=none" } */
 /* { dg-final { scan-assembler ".p2align 6,,1" } } */
 /* { dg-final { scan-assembler-not ".p2align 6,,63" } } */
 
diff --git a/gcc/testsuite/gcc.target/i386/cet-label-3.c b/gcc/testsuite/gcc.target/i386/cet-label-3.c
new file mode 100644
index 00000000000..06268cfba17
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cet-label-3.c
@@ -0,0 +1,16 @@
+/* Verify that CET works.  */
+/* { dg-do compile } */
+/* { dg-options "-O -fcf-protection -mnop" } */
+/* { dg-final { scan-assembler-times "endbr32" 3 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "endbr64" 3 { target { ! ia32 } } } } */
+
+int func (int arg)
+{
+  static void *array[] = { &&foo, &&bar };
+
+  goto *array[arg];
+foo:
+  return arg*111;
+bar:
+  return arg*777;
+}
diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c
index 7987d53d305..0bddf54862a 100644
--- a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c
+++ b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c
@@ -1,6 +1,6 @@
 /* Verify nocf_check functions are not ICF optimized.  */
 /* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -fcf-protection=none" } */
 /* { dg-final { scan-assembler-not "endbr" } } */
 /* { dg-final { scan-assembler-not "fn3:" } } */
 /* { dg-final { scan-assembler "set\[ \t]+fn2,fn1" } } */
diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c
index 07c4a6b61ef..ed2d53ac5ef 100644
--- a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c
+++ b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c
@@ -1,6 +1,6 @@
 /* Verify nocf_check function calls are not ICF optimized.  */
 /* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -fcf-protection=none" } */
 /* { dg-final { scan-assembler-not "endbr" } } */
 /* { dg-final { scan-assembler-not "fn2:" } } */
 /* { dg-final { scan-assembler "set\[ \t]+fn2,fn1" } } */
diff --git a/gcc/testsuite/gcc.target/i386/cet-property-2.c b/gcc/testsuite/gcc.target/i386/cet-property-2.c
index 5a87dab92f1..bca6f6cdeb7 100644
--- a/gcc/testsuite/gcc.target/i386/cet-property-2.c
+++ b/gcc/testsuite/gcc.target/i386/cet-property-2.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-mcet" } */
+/* { dg-options "-mcet -fcf-protection=none" } */
 /* { dg-final { scan-assembler-not ".note.gnu.property" } } */
 
 extern void foo (void);
diff --git a/gcc/testsuite/gcc.target/i386/cet-property-3.c b/gcc/testsuite/gcc.target/i386/cet-property-3.c
new file mode 100644
index 00000000000..a3302b12699
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cet-property-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-fcf-protection -mnop" } */
+/* { dg-final { scan-assembler ".note.gnu.property" } } */
+
+extern void foo (void);
+
+void
+bar (void)
+{
+  foo ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/cet-sjlj-7.c b/gcc/testsuite/gcc.target/i386/cet-sjlj-7.c
new file mode 100644
index 00000000000..c7765099536
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cet-sjlj-7.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fcf-protection -mnop" } */
+/* { dg-final { scan-assembler-times "endbr32" 2 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "endbr64" 2 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "call	_?setjmp" 1 } } */
+/* { dg-final { scan-assembler-times "call	longjmp" 1 } } */
+
+#include <stdio.h>
+#include <setjmp.h>
+
+jmp_buf buf;
+static int bar (int);
+
+__attribute__ ((noinline, noclone))
+static int
+foo (int i)
+{
+  int j = i * 11;
+
+  if (!setjmp (buf))
+    {
+      j += 33;
+      printf ("After setjmp: j = %d\n", j);
+      bar (j);
+    }
+
+  return j + i;
+}
+
+__attribute__ ((noinline, noclone))
+static int
+bar (int i)
+{
+ int j = i;
+
+  j -= 111;
+  printf ("In longjmp: j = %d\n", j);
+  longjmp (buf, 1);
+
+  return j;
+}
+
+int
+main ()
+{
+  foo (10);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
index d53fc887dcc..5c120519ad9 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic -fcf-protection=none" } */
 
 void func0 (void);
 void func1 (void);
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
index 2b9a33e93dc..74af6198bf4 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic -fcf-protection=none" } */
 
 void func0 (void);
 void func1 (void);
diff --git a/gcc/testsuite/gcc.target/i386/pr85403.c b/gcc/testsuite/gcc.target/i386/pr85403.c
index f4fb12dd4e2..8a8ef99ae6d 100644
--- a/gcc/testsuite/gcc.target/i386/pr85403.c
+++ b/gcc/testsuite/gcc.target/i386/pr85403.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-fcf-protection -mcet" } */
+/* { dg-options "-fcf-protection -mcet -mno-nop" } */
 /* { dg-require-ifunc "" } */
 
 __attribute__((target_clones("avx","arch=slm","arch=core-avx2","default")))
diff --git a/gcc/testsuite/gcc.target/i386/pr85417-1.c b/gcc/testsuite/gcc.target/i386/pr85417-1.c
new file mode 100644
index 00000000000..6aac7552e9d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr85417-1.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-march=native -fcf-protection -mnop" } */
+
+int foo;
diff --git a/gcc/testsuite/gcc.target/i386/pr85417-2.c b/gcc/testsuite/gcc.target/i386/pr85417-2.c
new file mode 100644
index 00000000000..311054a379b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr85417-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O3 -fcf-protection -mnop" } */
+/* { dg-final { scan-assembler "vpshufb" } } */
+/* { dg-final { scan-assembler "punpcklbw" } } */
+
+__attribute__((target_clones("arch=core-avx2","arch=slm","default")))
+void
+foo(char *in, char *out, int size)
+{
+  int i;
+  for(i = 0; i < size; i++)
+    {
+	out[2 * i] = in[i];
+	out[2 * i + 1] = in[i];
+    }
+}
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-26.c b/gcc/testsuite/gcc.target/i386/ret-thunk-26.c
index 9144e988735..dc722c2f5f9 100644
--- a/gcc/testsuite/gcc.target/i386/ret-thunk-26.c
+++ b/gcc/testsuite/gcc.target/i386/ret-thunk-26.c
@@ -1,6 +1,6 @@
 /* PR target/r84530 */
 /* { dg-do run } */
-/* { dg-options "-Os -mfunction-return=thunk" } */
+/* { dg-options "-Os -mfunction-return=thunk -fcf-protection=none" } */
 
 struct S { int i; };
 __attribute__((const, noinline, noclone))
Richard Biener April 18, 2018, 11:35 a.m. | #6
On Wed, Apr 18, 2018 at 1:24 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Tue, Apr 17, 2018 at 12:25 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>> On Tue, Apr 17, 2018 at 12:25 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>>> On Tue, Apr 17, 2018 at 12:03 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>>>> On Tue, Apr 17, 2018 at 11:55 AM, Uros Bizjak <ubizjak@gmail.com> wrote:

>>>>> On Tue, Apr 17, 2018 at 8:42 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:

>>>>>> -fcf-protection -mcet can't be used with IFUNC features, like symbol

>>>>>> multiversioning or target clone, since IBT/SHSTK are applied to the whole

>>>>>> program and they may be disabled in some functions.  But -fcf-protection

>>>>>> is implemented with multi-byte NOPs on all 64-bit processors as well as

>>>>>> 32-bit processors starting with Pentium Pro.  If -fcf-protection requires

>>>>>> -mcet, IFUNC features can't be used on Linux when -fcf-protection is

>>>>>> enabled by default.

>>>>>>

>>>>>> This patch changes -fcf-protection to to enable the NOP portion of CET

>>>>>> ISAs unless IBT and/or SHSTK are disabled explicitly.  The rest of CET

>>>>>> ISAs, including intrinsics, still requires -mcet, -mibt or -mshstk.

>>>>>>

>>>>>> OK for trunk?

>>>>>

>>>>> As said in the PR, NOP sequences have non-zero cost in the executable

>>>>> (they enlarge the executable), so I don't think this feature should be

>>>>> enabled by default.

>>>>>

>>>>> There is always a configure option if someone wants their compiler to

>>>>> always emit relevant multi-byte nops.

>>>>

>>>> What we need is an option to enable -fcf-function with multi-byte NOPs

>>>> without -mcet which enables the full CET ISAs.  A configure option

>>>> without the corresponding the command-line option makes test and

>>>> debug difficult.   I can add

>>>>

>>>> --enable-cf-function-nop or --with-cf-function-nop

>>>>

>>>> with

>>>>

>>>> -fct-function-nop

>>>>

>>>

>>> How about adding -mno-cet, which enables the NOP portion of CET

>>

>> I meant -mnop-cet, not -mno-cet.

>>

>

> Here is a patch to add -mnop and use it with -fcf-protection.


+mnop
+Target Report Var(flag_nop) Init(0)
+Support multi-byte NOP code generation.

the option name is incredibly bad and the documentation doesn't make it
better either.  The invoke.texi docs refer to duplicate {-mcet}.

Isn't there a -fcf-protection sub-set that can be used to automatically
enable this?  Or simply do this mode by default when
-fcf-protection is used but neither -mcet nor -mibt is enabled?

>

> --

> H.J.
H.J. Lu April 18, 2018, 11:39 a.m. | #7
On Wed, Apr 18, 2018 at 4:35 AM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Wed, Apr 18, 2018 at 1:24 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>> On Tue, Apr 17, 2018 at 12:25 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>>> On Tue, Apr 17, 2018 at 12:25 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>>>> On Tue, Apr 17, 2018 at 12:03 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>>>>> On Tue, Apr 17, 2018 at 11:55 AM, Uros Bizjak <ubizjak@gmail.com> wrote:

>>>>>> On Tue, Apr 17, 2018 at 8:42 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:

>>>>>>> -fcf-protection -mcet can't be used with IFUNC features, like symbol

>>>>>>> multiversioning or target clone, since IBT/SHSTK are applied to the whole

>>>>>>> program and they may be disabled in some functions.  But -fcf-protection

>>>>>>> is implemented with multi-byte NOPs on all 64-bit processors as well as

>>>>>>> 32-bit processors starting with Pentium Pro.  If -fcf-protection requires

>>>>>>> -mcet, IFUNC features can't be used on Linux when -fcf-protection is

>>>>>>> enabled by default.

>>>>>>>

>>>>>>> This patch changes -fcf-protection to to enable the NOP portion of CET

>>>>>>> ISAs unless IBT and/or SHSTK are disabled explicitly.  The rest of CET

>>>>>>> ISAs, including intrinsics, still requires -mcet, -mibt or -mshstk.

>>>>>>>

>>>>>>> OK for trunk?

>>>>>>

>>>>>> As said in the PR, NOP sequences have non-zero cost in the executable

>>>>>> (they enlarge the executable), so I don't think this feature should be

>>>>>> enabled by default.

>>>>>>

>>>>>> There is always a configure option if someone wants their compiler to

>>>>>> always emit relevant multi-byte nops.

>>>>>

>>>>> What we need is an option to enable -fcf-function with multi-byte NOPs

>>>>> without -mcet which enables the full CET ISAs.  A configure option

>>>>> without the corresponding the command-line option makes test and

>>>>> debug difficult.   I can add

>>>>>

>>>>> --enable-cf-function-nop or --with-cf-function-nop

>>>>>

>>>>> with

>>>>>

>>>>> -fct-function-nop

>>>>>

>>>>

>>>> How about adding -mno-cet, which enables the NOP portion of CET

>>>

>>> I meant -mnop-cet, not -mno-cet.

>>>

>>

>> Here is a patch to add -mnop and use it with -fcf-protection.

>

> +mnop

> +Target Report Var(flag_nop) Init(0)

> +Support multi-byte NOP code generation.

>

> the option name is incredibly bad and the documentation doesn't make it

> better either.  The invoke.texi docs refer to duplicate {-mcet}.

>

> Isn't there a -fcf-protection sub-set that can be used to automatically

> enable this?  Or simply do this mode by default when

> -fcf-protection is used but neither -mcet nor -mibt is enabled?


Make -fcf-protection default to multi-byte NOPs works.  Uros,
should I prepare a patch?

-- 
H.J.
Uros Bizjak April 18, 2018, 11:55 a.m. | #8
On Wed, Apr 18, 2018 at 1:39 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>>> Here is a patch to add -mnop and use it with -fcf-protection.

>>

>> +mnop

>> +Target Report Var(flag_nop) Init(0)

>> +Support multi-byte NOP code generation.

>>

>> the option name is incredibly bad and the documentation doesn't make it

>> better either.  The invoke.texi docs refer to duplicate {-mcet}.

>>

>> Isn't there a -fcf-protection sub-set that can be used to automatically

>> enable this?  Or simply do this mode by default when

>> -fcf-protection is used but neither -mcet nor -mibt is enabled?

>

> Make -fcf-protection default to multi-byte NOPs works.  Uros,

> should I prepare a patch?


Please make it an opt-in feature, so the compiler won't litter the
executable with unnecessary nops without user consent.

Uros.
H.J. Lu April 18, 2018, 11:57 a.m. | #9
On Wed, Apr 18, 2018 at 4:55 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Wed, Apr 18, 2018 at 1:39 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>

>>>> Here is a patch to add -mnop and use it with -fcf-protection.

>>>

>>> +mnop

>>> +Target Report Var(flag_nop) Init(0)

>>> +Support multi-byte NOP code generation.

>>>

>>> the option name is incredibly bad and the documentation doesn't make it

>>> better either.  The invoke.texi docs refer to duplicate {-mcet}.

>>>

>>> Isn't there a -fcf-protection sub-set that can be used to automatically

>>> enable this?  Or simply do this mode by default when

>>> -fcf-protection is used but neither -mcet nor -mibt is enabled?

>>

>> Make -fcf-protection default to multi-byte NOPs works.  Uros,

>> should I prepare a patch?

>

> Please make it an opt-in feature, so the compiler won't litter the

> executable with unnecessary nops without user consent.

>


-fcf-protection is off by default.  Users need to pass -fcf-protection
to enable it.  I will work on such a patch.

Thanks.

-- 
H.J.
Jakub Jelinek April 18, 2018, 12:04 p.m. | #10
On Wed, Apr 18, 2018 at 04:57:41AM -0700, H.J. Lu wrote:
> On Wed, Apr 18, 2018 at 4:55 AM, Uros Bizjak <ubizjak@gmail.com> wrote:

> > On Wed, Apr 18, 2018 at 1:39 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

> >

> >>>> Here is a patch to add -mnop and use it with -fcf-protection.

> >>>

> >>> +mnop

> >>> +Target Report Var(flag_nop) Init(0)

> >>> +Support multi-byte NOP code generation.

> >>>

> >>> the option name is incredibly bad and the documentation doesn't make it

> >>> better either.  The invoke.texi docs refer to duplicate {-mcet}.

> >>>

> >>> Isn't there a -fcf-protection sub-set that can be used to automatically

> >>> enable this?  Or simply do this mode by default when

> >>> -fcf-protection is used but neither -mcet nor -mibt is enabled?

> >>

> >> Make -fcf-protection default to multi-byte NOPs works.  Uros,

> >> should I prepare a patch?

> >

> > Please make it an opt-in feature, so the compiler won't litter the

> > executable with unnecessary nops without user consent.

> >

> 

> -fcf-protection is off by default.  Users need to pass -fcf-protection

> to enable it.  I will work on such a patch.


That is not true.  When building gcc itself, config/cet.m4 makes
-fcf-protection -mcet the default if assembler supports it.
The request was to change --enable-cet configure option from having
yes,no,default arguments with default autodetection and being a default
if --enable-cet*/--disable-cet is not specified to say
yes,no,auto arguments where no would be the default and auto would be the
current default - enable it if as supports it, disable otherwise.

	Jakub
Uros Bizjak April 18, 2018, 12:08 p.m. | #11
On Wed, Apr 18, 2018 at 1:57 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Wed, Apr 18, 2018 at 4:55 AM, Uros Bizjak <ubizjak@gmail.com> wrote:

>> On Wed, Apr 18, 2018 at 1:39 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>>

>>>>> Here is a patch to add -mnop and use it with -fcf-protection.

>>>>

>>>> +mnop

>>>> +Target Report Var(flag_nop) Init(0)

>>>> +Support multi-byte NOP code generation.

>>>>

>>>> the option name is incredibly bad and the documentation doesn't make it

>>>> better either.  The invoke.texi docs refer to duplicate {-mcet}.

>>>>

>>>> Isn't there a -fcf-protection sub-set that can be used to automatically

>>>> enable this?  Or simply do this mode by default when

>>>> -fcf-protection is used but neither -mcet nor -mibt is enabled?

>>>

>>> Make -fcf-protection default to multi-byte NOPs works.  Uros,

>>> should I prepare a patch?

>>

>> Please make it an opt-in feature, so the compiler won't litter the

>> executable with unnecessary nops without user consent.

>>

>

> -fcf-protection is off by default.  Users need to pass -fcf-protection

> to enable it.  I will work on such a patch.


Please note that currently all libraries are compiled with
"-fcf-protection -mcet" by default, even without using --enable-cet
during configure. The CET instrumentation of libraries should be put
under strict user control, so please remove the "default" from
config/cet.m4.

Uros.
H.J. Lu April 18, 2018, 12:09 p.m. | #12
On Wed, Apr 18, 2018 at 5:08 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Wed, Apr 18, 2018 at 1:57 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>> On Wed, Apr 18, 2018 at 4:55 AM, Uros Bizjak <ubizjak@gmail.com> wrote:

>>> On Wed, Apr 18, 2018 at 1:39 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>>>

>>>>>> Here is a patch to add -mnop and use it with -fcf-protection.

>>>>>

>>>>> +mnop

>>>>> +Target Report Var(flag_nop) Init(0)

>>>>> +Support multi-byte NOP code generation.

>>>>>

>>>>> the option name is incredibly bad and the documentation doesn't make it

>>>>> better either.  The invoke.texi docs refer to duplicate {-mcet}.

>>>>>

>>>>> Isn't there a -fcf-protection sub-set that can be used to automatically

>>>>> enable this?  Or simply do this mode by default when

>>>>> -fcf-protection is used but neither -mcet nor -mibt is enabled?

>>>>

>>>> Make -fcf-protection default to multi-byte NOPs works.  Uros,

>>>> should I prepare a patch?

>>>

>>> Please make it an opt-in feature, so the compiler won't litter the

>>> executable with unnecessary nops without user consent.

>>>

>>

>> -fcf-protection is off by default.  Users need to pass -fcf-protection

>> to enable it.  I will work on such a patch.

>

> Please note that currently all libraries are compiled with

> "-fcf-protection -mcet" by default, even without using --enable-cet

> during configure. The CET instrumentation of libraries should be put

> under strict user control, so please remove the "default" from

> config/cet.m4.

>


Igor, please prepare such a patch to config/cet.m4.


-- 
H.J.
Jakub Jelinek April 18, 2018, 12:09 p.m. | #13
On Wed, Apr 18, 2018 at 02:04:50PM +0200, Jakub Jelinek wrote:
> On Wed, Apr 18, 2018 at 04:57:41AM -0700, H.J. Lu wrote:

> > On Wed, Apr 18, 2018 at 4:55 AM, Uros Bizjak <ubizjak@gmail.com> wrote:

> > > On Wed, Apr 18, 2018 at 1:39 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

> > >

> > >>>> Here is a patch to add -mnop and use it with -fcf-protection.

> > >>>

> > >>> +mnop

> > >>> +Target Report Var(flag_nop) Init(0)

> > >>> +Support multi-byte NOP code generation.

> > >>>

> > >>> the option name is incredibly bad and the documentation doesn't make it

> > >>> better either.  The invoke.texi docs refer to duplicate {-mcet}.

> > >>>

> > >>> Isn't there a -fcf-protection sub-set that can be used to automatically

> > >>> enable this?  Or simply do this mode by default when

> > >>> -fcf-protection is used but neither -mcet nor -mibt is enabled?

> > >>

> > >> Make -fcf-protection default to multi-byte NOPs works.  Uros,

> > >> should I prepare a patch?

> > >

> > > Please make it an opt-in feature, so the compiler won't litter the

> > > executable with unnecessary nops without user consent.

> > >

> > 

> > -fcf-protection is off by default.  Users need to pass -fcf-protection

> > to enable it.  I will work on such a patch.

> 

> That is not true.  When building gcc itself, config/cet.m4 makes

> -fcf-protection -mcet the default if assembler supports it.

> The request was to change --enable-cet configure option from having

> yes,no,default arguments with default autodetection and being a default

> if --enable-cet*/--disable-cet is not specified to say

> yes,no,auto arguments where no would be the default and auto would be the

> current default - enable it if as supports it, disable otherwise.


So untested patch would be something like:

2018-04-18  Jakub Jelinek  <jakub@redhat.com>

	* config/cet.m4 (GCC_CET_FLAGS): Default to --disable-cet, replace
	--enable-cet=default with --enable-cet=auto.

	* doc/install.texi: Document --disable-cet being the default and
	--enable-cet=auto.

--- gcc/config/cet.m4.jj	2018-02-19 19:57:05.221280084 +0100
+++ gcc/config/cet.m4	2018-04-18 14:05:31.514859185 +0200
@@ -3,14 +3,14 @@ dnl GCC_CET_FLAGS
 dnl    (SHELL-CODE_HANDLER)
 dnl
 AC_DEFUN([GCC_CET_FLAGS],[dnl
-GCC_ENABLE(cet, default, ,[enable Intel CET in target libraries],
-	   permit yes|no|default)
+GCC_ENABLE(cet, no, ,[enable Intel CET in target libraries],
+	   permit yes|no|auto)
 AC_MSG_CHECKING([for CET support])
 
 case "$host" in
   i[[34567]]86-*-linux* | x86_64-*-linux*)
     case "$enable_cet" in
-      default)
+      auto)
 	# Check if target supports multi-byte NOPs
 	# and if assembler supports CET insn.
 	AC_COMPILE_IFELSE(
--- gcc/doc/install.texi.jj	2018-02-08 12:21:20.791749480 +0100
+++ gcc/doc/install.texi	2018-04-18 14:07:19.637901528 +0200
@@ -2103,10 +2103,11 @@ instrumentation, see @option{-fcf-protec
 to add @option{-fcf-protection} and, if needed, other target
 specific options to a set of building options.
 
-The option is enabled by default on Linux/x86 if target binutils
-supports @code{Intel CET} instructions.  In this case the target
-libraries are configured to get additional @option{-fcf-protection}
-and @option{-mcet} options.
+The option is disabled by default on Linux/x86.  When
+@code{--enable-cet=auto} is used, it is enabled if target binutils
+supports @code{Intel CET} instructions and disabled otherwise.
+In this case the target libraries are configured to get additional
+@option{-fcf-protection} and @option{-mcet} options.
 @end table
 
 @subheading Cross-Compiler-Specific Options


	Jakub
Tsimbalist, Igor V April 18, 2018, 12:23 p.m. | #14
> -----Original Message-----

> From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-

> owner@gcc.gnu.org] On Behalf Of H.J. Lu

> Sent: Wednesday, April 18, 2018 1:39 PM

> To: Richard Biener <richard.guenther@gmail.com>

> Cc: Uros Bizjak <ubizjak@gmail.com>; gcc-patches@gcc.gnu.org; Tsimbalist,

> Igor V <igor.v.tsimbalist@intel.com>

> Subject: Re: [PATCH] x86: Allow -fcf-protection with multi-byte NOPs

> 

> On Wed, Apr 18, 2018 at 4:35 AM, Richard Biener

> <richard.guenther@gmail.com> wrote:

> > On Wed, Apr 18, 2018 at 1:24 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

> >> On Tue, Apr 17, 2018 at 12:25 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

> >>> On Tue, Apr 17, 2018 at 12:25 PM, H.J. Lu <hjl.tools@gmail.com>

> wrote:

> >>>> On Tue, Apr 17, 2018 at 12:03 PM, H.J. Lu <hjl.tools@gmail.com>

> wrote:

> >>>>> On Tue, Apr 17, 2018 at 11:55 AM, Uros Bizjak

> <ubizjak@gmail.com> wrote:

> >>>>>> On Tue, Apr 17, 2018 at 8:42 PM, H.J. Lu <hongjiu.lu@intel.com>

> wrote:

> >>>>>>> -fcf-protection -mcet can't be used with IFUNC features, like

> symbol

> >>>>>>> multiversioning or target clone, since IBT/SHSTK are applied to

> the whole

> >>>>>>> program and they may be disabled in some functions.  But -fcf-

> protection

> >>>>>>> is implemented with multi-byte NOPs on all 64-bit processors as

> well as

> >>>>>>> 32-bit processors starting with Pentium Pro.  If -fcf-protection

> requires

> >>>>>>> -mcet, IFUNC features can't be used on Linux when -fcf-

> protection is

> >>>>>>> enabled by default.

> >>>>>>>

> >>>>>>> This patch changes -fcf-protection to to enable the NOP portion

> of CET

> >>>>>>> ISAs unless IBT and/or SHSTK are disabled explicitly.  The rest of

> CET

> >>>>>>> ISAs, including intrinsics, still requires -mcet, -mibt or -mshstk.

> >>>>>>>

> >>>>>>> OK for trunk?

> >>>>>>

> >>>>>> As said in the PR, NOP sequences have non-zero cost in the

> executable

> >>>>>> (they enlarge the executable), so I don't think this feature should

> be

> >>>>>> enabled by default.

> >>>>>>

> >>>>>> There is always a configure option if someone wants their compiler

> to

> >>>>>> always emit relevant multi-byte nops.

> >>>>>

> >>>>> What we need is an option to enable -fcf-function with multi-byte

> NOPs

> >>>>> without -mcet which enables the full CET ISAs.  A configure option

> >>>>> without the corresponding the command-line option makes test and

> >>>>> debug difficult.   I can add

> >>>>>

> >>>>> --enable-cf-function-nop or --with-cf-function-nop

> >>>>>

> >>>>> with

> >>>>>

> >>>>> -fct-function-nop

> >>>>>

> >>>>

> >>>> How about adding -mno-cet, which enables the NOP portion of CET

> >>>

> >>> I meant -mnop-cet, not -mno-cet.

> >>>

> >>

> >> Here is a patch to add -mnop and use it with -fcf-protection.

> >

> > +mnop

> > +Target Report Var(flag_nop) Init(0)

> > +Support multi-byte NOP code generation.

> >

> > the option name is incredibly bad and the documentation doesn't make it

> > better either.  The invoke.texi docs refer to duplicate {-mcet}.

> >

> > Isn't there a -fcf-protection sub-set that can be used to automatically

> > enable this?  Or simply do this mode by default when

> > -fcf-protection is used but neither -mcet nor -mibt is enabled?

> 

> Make -fcf-protection default to multi-byte NOPs works.  Uros,

> should I prepare a patch?


This is going to change the designed approach and has to be communicated to/agreed
with other compilers. And I assume there will be no extra option introduced, like -mnop.

Igor

> --

> H.J.
Tsimbalist, Igor V April 18, 2018, 12:28 p.m. | #15
> -----Original Message-----

> From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-

> owner@gcc.gnu.org] On Behalf Of Jakub Jelinek

> Sent: Wednesday, April 18, 2018 2:10 PM

> To: H.J. Lu <hjl.tools@gmail.com>

> Cc: Uros Bizjak <ubizjak@gmail.com>; Richard Biener

> <richard.guenther@gmail.com>; gcc-patches@gcc.gnu.org; Tsimbalist, Igor

> V <igor.v.tsimbalist@intel.com>

> Subject: Re: [PATCH] x86: Allow -fcf-protection with multi-byte NOPs

> 

> On Wed, Apr 18, 2018 at 02:04:50PM +0200, Jakub Jelinek wrote:

> > On Wed, Apr 18, 2018 at 04:57:41AM -0700, H.J. Lu wrote:

> > > On Wed, Apr 18, 2018 at 4:55 AM, Uros Bizjak <ubizjak@gmail.com>

> wrote:

> > > > On Wed, Apr 18, 2018 at 1:39 PM, H.J. Lu <hjl.tools@gmail.com>

> wrote:

> > > >

> > > >>>> Here is a patch to add -mnop and use it with -fcf-protection.

> > > >>>

> > > >>> +mnop

> > > >>> +Target Report Var(flag_nop) Init(0)

> > > >>> +Support multi-byte NOP code generation.

> > > >>>

> > > >>> the option name is incredibly bad and the documentation doesn't

> make it

> > > >>> better either.  The invoke.texi docs refer to duplicate {-mcet}.

> > > >>>

> > > >>> Isn't there a -fcf-protection sub-set that can be used to

> automatically

> > > >>> enable this?  Or simply do this mode by default when

> > > >>> -fcf-protection is used but neither -mcet nor -mibt is enabled?

> > > >>

> > > >> Make -fcf-protection default to multi-byte NOPs works.  Uros,

> > > >> should I prepare a patch?

> > > >

> > > > Please make it an opt-in feature, so the compiler won't litter the

> > > > executable with unnecessary nops without user consent.

> > > >

> > >

> > > -fcf-protection is off by default.  Users need to pass -fcf-protection

> > > to enable it.  I will work on such a patch.

> >

> > That is not true.  When building gcc itself, config/cet.m4 makes

> > -fcf-protection -mcet the default if assembler supports it.

> > The request was to change --enable-cet configure option from having

> > yes,no,default arguments with default autodetection and being a default

> > if --enable-cet*/--disable-cet is not specified to say

> > yes,no,auto arguments where no would be the default and auto would be

> the

> > current default - enable it if as supports it, disable otherwise.

> 

> So untested patch would be something like:

> 

> 2018-04-18  Jakub Jelinek  <jakub@redhat.com>

> 

> 	* config/cet.m4 (GCC_CET_FLAGS): Default to --disable-cet, replace

> 	--enable-cet=default with --enable-cet=auto.

> 

> 	* doc/install.texi: Document --disable-cet being the default and

> 	--enable-cet=auto.

> 

> --- gcc/config/cet.m4.jj	2018-02-19 19:57:05.221280084 +0100

> +++ gcc/config/cet.m4	2018-04-18 14:05:31.514859185 +0200

> @@ -3,14 +3,14 @@ dnl GCC_CET_FLAGS

>  dnl    (SHELL-CODE_HANDLER)

>  dnl

>  AC_DEFUN([GCC_CET_FLAGS],[dnl

> -GCC_ENABLE(cet, default, ,[enable Intel CET in target libraries],

> -	   permit yes|no|default)

> +GCC_ENABLE(cet, no, ,[enable Intel CET in target libraries],

> +	   permit yes|no|auto)

>  AC_MSG_CHECKING([for CET support])

> 

>  case "$host" in

>    i[[34567]]86-*-linux* | x86_64-*-linux*)

>      case "$enable_cet" in

> -      default)

> +      auto)

>  	# Check if target supports multi-byte NOPs

>  	# and if assembler supports CET insn.

>  	AC_COMPILE_IFELSE(

> --- gcc/doc/install.texi.jj	2018-02-08 12:21:20.791749480 +0100

> +++ gcc/doc/install.texi	2018-04-18 14:07:19.637901528 +0200

> @@ -2103,10 +2103,11 @@ instrumentation, see @option{-fcf-protec

>  to add @option{-fcf-protection} and, if needed, other target

>  specific options to a set of building options.

> 

> -The option is enabled by default on Linux/x86 if target binutils

> -supports @code{Intel CET} instructions.  In this case the target

> -libraries are configured to get additional @option{-fcf-protection}

> -and @option{-mcet} options.

> +The option is disabled by default on Linux/x86.  When

> +@code{--enable-cet=auto} is used, it is enabled if target binutils

> +supports @code{Intel CET} instructions and disabled otherwise.

> +In this case the target libraries are configured to get additional

> +@option{-fcf-protection} and @option{-mcet} options.

>  @end table

> 

>  @subheading Cross-Compiler-Specific Options

> 


Thanks! I will work on this.

> 	Jakub
Uros Bizjak April 18, 2018, 12:32 p.m. | #16
On Wed, Apr 18, 2018 at 2:09 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Wed, Apr 18, 2018 at 02:04:50PM +0200, Jakub Jelinek wrote:

>> On Wed, Apr 18, 2018 at 04:57:41AM -0700, H.J. Lu wrote:

>> > On Wed, Apr 18, 2018 at 4:55 AM, Uros Bizjak <ubizjak@gmail.com> wrote:

>> > > On Wed, Apr 18, 2018 at 1:39 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>> > >

>> > >>>> Here is a patch to add -mnop and use it with -fcf-protection.

>> > >>>

>> > >>> +mnop

>> > >>> +Target Report Var(flag_nop) Init(0)

>> > >>> +Support multi-byte NOP code generation.

>> > >>>

>> > >>> the option name is incredibly bad and the documentation doesn't make it

>> > >>> better either.  The invoke.texi docs refer to duplicate {-mcet}.

>> > >>>

>> > >>> Isn't there a -fcf-protection sub-set that can be used to automatically

>> > >>> enable this?  Or simply do this mode by default when

>> > >>> -fcf-protection is used but neither -mcet nor -mibt is enabled?

>> > >>

>> > >> Make -fcf-protection default to multi-byte NOPs works.  Uros,

>> > >> should I prepare a patch?

>> > >

>> > > Please make it an opt-in feature, so the compiler won't litter the

>> > > executable with unnecessary nops without user consent.

>> > >

>> >

>> > -fcf-protection is off by default.  Users need to pass -fcf-protection

>> > to enable it.  I will work on such a patch.

>>

>> That is not true.  When building gcc itself, config/cet.m4 makes

>> -fcf-protection -mcet the default if assembler supports it.

>> The request was to change --enable-cet configure option from having

>> yes,no,default arguments with default autodetection and being a default

>> if --enable-cet*/--disable-cet is not specified to say

>> yes,no,auto arguments where no would be the default and auto would be the

>> current default - enable it if as supports it, disable otherwise.

>

> So untested patch would be something like:


Yes, this is what I think should be the most appropriate approach.

Uros.

> 2018-04-18  Jakub Jelinek  <jakub@redhat.com>

>

>         * config/cet.m4 (GCC_CET_FLAGS): Default to --disable-cet, replace

>         --enable-cet=default with --enable-cet=auto.

>

>         * doc/install.texi: Document --disable-cet being the default and

>         --enable-cet=auto.

>

> --- gcc/config/cet.m4.jj        2018-02-19 19:57:05.221280084 +0100

> +++ gcc/config/cet.m4   2018-04-18 14:05:31.514859185 +0200

> @@ -3,14 +3,14 @@ dnl GCC_CET_FLAGS

>  dnl    (SHELL-CODE_HANDLER)

>  dnl

>  AC_DEFUN([GCC_CET_FLAGS],[dnl

> -GCC_ENABLE(cet, default, ,[enable Intel CET in target libraries],

> -          permit yes|no|default)

> +GCC_ENABLE(cet, no, ,[enable Intel CET in target libraries],

> +          permit yes|no|auto)

>  AC_MSG_CHECKING([for CET support])

>

>  case "$host" in

>    i[[34567]]86-*-linux* | x86_64-*-linux*)

>      case "$enable_cet" in

> -      default)

> +      auto)

>         # Check if target supports multi-byte NOPs

>         # and if assembler supports CET insn.

>         AC_COMPILE_IFELSE(

> --- gcc/doc/install.texi.jj     2018-02-08 12:21:20.791749480 +0100

> +++ gcc/doc/install.texi        2018-04-18 14:07:19.637901528 +0200

> @@ -2103,10 +2103,11 @@ instrumentation, see @option{-fcf-protec

>  to add @option{-fcf-protection} and, if needed, other target

>  specific options to a set of building options.

>

> -The option is enabled by default on Linux/x86 if target binutils

> -supports @code{Intel CET} instructions.  In this case the target

> -libraries are configured to get additional @option{-fcf-protection}

> -and @option{-mcet} options.

> +The option is disabled by default on Linux/x86.  When

> +@code{--enable-cet=auto} is used, it is enabled if target binutils

> +supports @code{Intel CET} instructions and disabled otherwise.

> +In this case the target libraries are configured to get additional

> +@option{-fcf-protection} and @option{-mcet} options.

>  @end table

>

>  @subheading Cross-Compiler-Specific Options

>

>

>         Jakub
H.J. Lu April 18, 2018, 7:24 p.m. | #17
On Wed, Apr 18, 2018 at 5:32 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Wed, Apr 18, 2018 at 2:09 PM, Jakub Jelinek <jakub@redhat.com> wrote:

>> On Wed, Apr 18, 2018 at 02:04:50PM +0200, Jakub Jelinek wrote:

>>> On Wed, Apr 18, 2018 at 04:57:41AM -0700, H.J. Lu wrote:

>>> > On Wed, Apr 18, 2018 at 4:55 AM, Uros Bizjak <ubizjak@gmail.com> wrote:

>>> > > On Wed, Apr 18, 2018 at 1:39 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>>> > >

>>> > >>>> Here is a patch to add -mnop and use it with -fcf-protection.

>>> > >>>

>>> > >>> +mnop

>>> > >>> +Target Report Var(flag_nop) Init(0)

>>> > >>> +Support multi-byte NOP code generation.

>>> > >>>

>>> > >>> the option name is incredibly bad and the documentation doesn't make it

>>> > >>> better either.  The invoke.texi docs refer to duplicate {-mcet}.

>>> > >>>

>>> > >>> Isn't there a -fcf-protection sub-set that can be used to automatically

>>> > >>> enable this?  Or simply do this mode by default when

>>> > >>> -fcf-protection is used but neither -mcet nor -mibt is enabled?

>>> > >>

>>> > >> Make -fcf-protection default to multi-byte NOPs works.  Uros,

>>> > >> should I prepare a patch?

>>> > >

>>> > > Please make it an opt-in feature, so the compiler won't litter the

>>> > > executable with unnecessary nops without user consent.

>>> > >

>>> >

>>> > -fcf-protection is off by default.  Users need to pass -fcf-protection

>>> > to enable it.  I will work on such a patch.

>>>

>>> That is not true.  When building gcc itself, config/cet.m4 makes

>>> -fcf-protection -mcet the default if assembler supports it.

>>> The request was to change --enable-cet configure option from having

>>> yes,no,default arguments with default autodetection and being a default

>>> if --enable-cet*/--disable-cet is not specified to say

>>> yes,no,auto arguments where no would be the default and auto would be the

>>> current default - enable it if as supports it, disable otherwise.

>>

>> So untested patch would be something like:

>

> Yes, this is what I think should be the most appropriate approach.

>

> Uros.

>

>> 2018-04-18  Jakub Jelinek  <jakub@redhat.com>

>>

>>         * config/cet.m4 (GCC_CET_FLAGS): Default to --disable-cet, replace

>>         --enable-cet=default with --enable-cet=auto.

>>

>>         * doc/install.texi: Document --disable-cet being the default and

>>         --enable-cet=auto.

>>

>> --- gcc/config/cet.m4.jj        2018-02-19 19:57:05.221280084 +0100

>> +++ gcc/config/cet.m4   2018-04-18 14:05:31.514859185 +0200

>> @@ -3,14 +3,14 @@ dnl GCC_CET_FLAGS

>>  dnl    (SHELL-CODE_HANDLER)

>>  dnl

>>  AC_DEFUN([GCC_CET_FLAGS],[dnl

>> -GCC_ENABLE(cet, default, ,[enable Intel CET in target libraries],

>> -          permit yes|no|default)

>> +GCC_ENABLE(cet, no, ,[enable Intel CET in target libraries],

>> +          permit yes|no|auto)

>>  AC_MSG_CHECKING([for CET support])

>>

>>  case "$host" in

>>    i[[34567]]86-*-linux* | x86_64-*-linux*)

>>      case "$enable_cet" in

>> -      default)

>> +      auto)

>>         # Check if target supports multi-byte NOPs

>>         # and if assembler supports CET insn.

>>         AC_COMPILE_IFELSE(

>> --- gcc/doc/install.texi.jj     2018-02-08 12:21:20.791749480 +0100

>> +++ gcc/doc/install.texi        2018-04-18 14:07:19.637901528 +0200

>> @@ -2103,10 +2103,11 @@ instrumentation, see @option{-fcf-protec

>>  to add @option{-fcf-protection} and, if needed, other target

>>  specific options to a set of building options.

>>

>> -The option is enabled by default on Linux/x86 if target binutils

>> -supports @code{Intel CET} instructions.  In this case the target

>> -libraries are configured to get additional @option{-fcf-protection}

>> -and @option{-mcet} options.

>> +The option is disabled by default on Linux/x86.  When

>> +@code{--enable-cet=auto} is used, it is enabled if target binutils

>> +supports @code{Intel CET} instructions and disabled otherwise.

>> +In this case the target libraries are configured to get additional

>> +@option{-fcf-protection} and @option{-mcet} options.

>>  @end table

>>

>>  @subheading Cross-Compiler-Specific Options

>>

>>

>>         Jakub


Looks good to me.

Thanks.

-- 
H.J.
H.J. Lu April 19, 2018, 1:30 p.m. | #18
On Wed, Apr 18, 2018 at 01:35:33PM +0200, Richard Biener wrote:
> On Wed, Apr 18, 2018 at 1:24 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

> > On Tue, Apr 17, 2018 at 12:25 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

> >> On Tue, Apr 17, 2018 at 12:25 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

> >>> On Tue, Apr 17, 2018 at 12:03 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

> >>>> On Tue, Apr 17, 2018 at 11:55 AM, Uros Bizjak <ubizjak@gmail.com> wrote:

> >>>>> On Tue, Apr 17, 2018 at 8:42 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:

> >>>>>> -fcf-protection -mcet can't be used with IFUNC features, like symbol

> >>>>>> multiversioning or target clone, since IBT/SHSTK are applied to the whole

> >>>>>> program and they may be disabled in some functions.  But -fcf-protection

> >>>>>> is implemented with multi-byte NOPs on all 64-bit processors as well as

> >>>>>> 32-bit processors starting with Pentium Pro.  If -fcf-protection requires

> >>>>>> -mcet, IFUNC features can't be used on Linux when -fcf-protection is

> >>>>>> enabled by default.

> >>>>>>

> >>>>>> This patch changes -fcf-protection to to enable the NOP portion of CET

> >>>>>> ISAs unless IBT and/or SHSTK are disabled explicitly.  The rest of CET

> >>>>>> ISAs, including intrinsics, still requires -mcet, -mibt or -mshstk.

> >>>>>>

> >>>>>> OK for trunk?

> >>>>>

> >>>>> As said in the PR, NOP sequences have non-zero cost in the executable

> >>>>> (they enlarge the executable), so I don't think this feature should be

> >>>>> enabled by default.

> >>>>>

> >>>>> There is always a configure option if someone wants their compiler to

> >>>>> always emit relevant multi-byte nops.

> >>>>

> >>>> What we need is an option to enable -fcf-function with multi-byte NOPs

> >>>> without -mcet which enables the full CET ISAs.  A configure option

> >>>> without the corresponding the command-line option makes test and

> >>>> debug difficult.   I can add

> >>>>

> >>>> --enable-cf-function-nop or --with-cf-function-nop

> >>>>

> >>>> with

> >>>>

> >>>> -fct-function-nop

> >>>>

> >>>

> >>> How about adding -mno-cet, which enables the NOP portion of CET

> >>

> >> I meant -mnop-cet, not -mno-cet.

> >>

> >

> > Here is a patch to add -mnop and use it with -fcf-protection.

> 

> +mnop

> +Target Report Var(flag_nop) Init(0)

> +Support multi-byte NOP code generation.

> 

> the option name is incredibly bad and the documentation doesn't make it

> better either.  The invoke.texi docs refer to duplicate {-mcet}.

> 

> Isn't there a -fcf-protection sub-set that can be used to automatically

> enable this?  Or simply do this mode by default when

> -fcf-protection is used but neither -mcet nor -mibt is enabled?

> 


Since multi-byte NOPs are used to implement -fcf-protection on x86, we
propose a new design for -fcf-protection:

1. -fcf-protection option will report the unsupported error on non-x86
platform. On x86 platform it's supported and inserts endbr-nop
instructions and properties, depending on its value (full/branch/return)
2. -mcet/-mibt/-mshstk options control intrinsics only. 
3. These options are independent and do not influence each other so no
need for cross checking between them.

OK for trunk?


H.J.
----
----
-fcf-protection -mcet can't be used with IFUNC features, like symbol
multiversioning or target clone, since IBT/SHSTK are applied to the whole
program and they may be disabled in some functions.  But -fcf-protection
is implemented with multi-byte NOPs on all 64-bit processors as well as
32-bit processors starting with Pentium Pro.  If -fcf-protection requires
-mcet, IFUNC features can't be used on Linux when -fcf-protection is
enabled by default.

This patch changes -fcf-protection to implement indirect branch and
return address tracking with multi-byte NOPs.  -mibt and -mshstk are
changed to only CET built-in functions.  CET tests are updated to
allow -fcf-protection without -mibt, -mshstk and -mcet on x86.
-fcf-protection=none are also added to tests which fail with
-fcf-protection so that -fcf-protection can be added to RUNTESTFLAGS
to verify -fcf-protection implementation.

gcc/

	PR target/85417
	* config/i386/cet.c (file_end_indicate_exec_stack_and_cet):
	Check flag_cf_protection instead of TARGET_IBT and TARGET_SHSTK.
	* config/i386/i386-c.c (ix86_target_macros_internal): Also
	define __IBT__ and __SHSTK__ for -fcf-protection.
	* config/i386/i386.c (pass_insert_endbranch::gate): Don't check
	TARGET_IBT.
	(ix86_trampoline_init): Likewise.
	(x86_output_mi_thunk): Likewise.
	(ix86_notrack_prefixed_insn_p): Likewise.
	(ix86_option_override_internal): Don't disallow -fcf-protection.
	* config/i386/i386.md (rdssp<mode>): Also enable for
	-fcf-protection.
	(incssp<mode>): Likewise.
	(nop_endbr): Likewise.
	* config/i386/i386.opt (mcet): Change help message to built-in
	functions only.
	(mibt): Likewise.
	(mshstk): Likewise.
	* doc/invoke.texi: Remove -mcet, -mibt and -mshstk condition
	on -fcf-protection.  Change -mcet, -mibt and -mshstk to only
	enable CET built-in functions.

gcc/testsuite/

	PR target/85417
	* c-c++-common/attr-nocf-check-1.c: Compile with
	-fcf-protection=none.
	* c-c++-common/attr-nocf-check-3.c: Likewise.
	* gcc.dg/march-generic.c: Likewise.
	* gcc.target/i386/align-limit.c: Likewise.
	* gcc.target/i386/cet-notrack-icf-1.c: Likewise.
	* gcc.target/i386/cet-notrack-icf-3.c: Likewise.
	* gcc.target/i386/cet-property-2.c: Likewise.
	* gcc.target/i386/ret-thunk-26.c: Likewise.
	* c-c++-common/fcf-protection-1.c: Remove dg-error for x86
	targets.
	* c-c++-common/fcf-protection-2.c: Likewise.
	* c-c++-common/fcf-protection-3.c: Likewise.
	* c-c++-common/fcf-protection-5.c: Likewise.
	* c-c++-common/fcf-protection-6.c: Likewise.
	* c-c++-common/fcf-protection-7.c: Likewise.
	* gcc.target/i386/cet-label-3.c: New test.
	* gcc.target/i386/cet-property-3.c: Likewise.
	* gcc.target/i386/cet-sjlj-7.c: Likewise.
	* gcc.target/i386/pr85417-1.c: Likewise.
	* gcc.target/i386/indirect-thunk-attr-7.c: Also expect
	__x86_indirect_thunk_nt_(r|e)ax
	* gcc.target/i386/indirect-thunk-extern-7.c: Likewise.
	* gcc.target/i386/pr85403.c: Remove dg-error,
---
 gcc/config/i386/cet.c                              |  4 +-
 gcc/config/i386/i386-c.c                           |  6 ++-
 gcc/config/i386/i386.c                             | 54 +++-------------------
 gcc/config/i386/i386.md                            |  6 +--
 gcc/config/i386/i386.opt                           |  9 ++--
 gcc/doc/invoke.texi                                | 28 ++++-------
 gcc/testsuite/c-c++-common/attr-nocf-check-1.c     |  1 +
 gcc/testsuite/c-c++-common/attr-nocf-check-3.c     |  1 +
 gcc/testsuite/c-c++-common/fcf-protection-1.c      |  1 -
 gcc/testsuite/c-c++-common/fcf-protection-2.c      |  1 -
 gcc/testsuite/c-c++-common/fcf-protection-3.c      |  1 -
 gcc/testsuite/c-c++-common/fcf-protection-5.c      |  1 -
 gcc/testsuite/c-c++-common/fcf-protection-6.c      |  2 -
 gcc/testsuite/c-c++-common/fcf-protection-7.c      |  2 -
 gcc/testsuite/gcc.dg/march-generic.c               |  2 +-
 gcc/testsuite/gcc.target/i386/align-limit.c        |  2 +-
 gcc/testsuite/gcc.target/i386/cet-label-3.c        | 16 +++++++
 gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c  |  2 +-
 gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c  |  2 +-
 gcc/testsuite/gcc.target/i386/cet-property-2.c     |  2 +-
 gcc/testsuite/gcc.target/i386/cet-property-3.c     | 11 +++++
 gcc/testsuite/gcc.target/i386/cet-sjlj-7.c         | 48 +++++++++++++++++++
 .../gcc.target/i386/indirect-thunk-attr-7.c        |  2 +-
 .../gcc.target/i386/indirect-thunk-extern-7.c      |  2 +-
 gcc/testsuite/gcc.target/i386/pr85403.c            |  2 +-
 gcc/testsuite/gcc.target/i386/pr85417-1.c          | 17 +++++++
 gcc/testsuite/gcc.target/i386/ret-thunk-26.c       |  2 +-
 27 files changed, 133 insertions(+), 94 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/i386/cet-label-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/cet-property-3.c
 create mode 100644 gcc/testsuite/gcc.target/i386/cet-sjlj-7.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr85417-1.c

diff --git a/gcc/config/i386/cet.c b/gcc/config/i386/cet.c
index 4a1e013fdde..eb3be171471 100644
--- a/gcc/config/i386/cet.c
+++ b/gcc/config/i386/cet.c
@@ -34,11 +34,11 @@ file_end_indicate_exec_stack_and_cet (void)
 
   unsigned int feature_1 = 0;
 
-  if (TARGET_IBT)
+  if (flag_cf_protection & CF_BRANCH)
     /* GNU_PROPERTY_X86_FEATURE_1_IBT.  */
     feature_1 |= 0x1;
 
-  if (TARGET_SHSTK)
+  if (flag_cf_protection & CF_RETURN)
     /* GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */
     feature_1 |= 0x2;
 
diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c
index 2e0e9f66c9e..9961d418ee9 100644
--- a/gcc/config/i386/i386-c.c
+++ b/gcc/config/i386/i386-c.c
@@ -499,13 +499,15 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
     def_or_undef (parse_in, "__RDPID__");
   if (isa_flag & OPTION_MASK_ISA_GFNI)
     def_or_undef (parse_in, "__GFNI__");
-  if (isa_flag2 & OPTION_MASK_ISA_IBT)
+  if ((isa_flag2 & OPTION_MASK_ISA_IBT)
+      || (flag_cf_protection & CF_BRANCH))
     {
       def_or_undef (parse_in, "__IBT__");
       if (flag_cf_protection != CF_NONE)
 	def_or_undef (parse_in, "__CET__");
     }
-  if (isa_flag & OPTION_MASK_ISA_SHSTK)
+  if ((isa_flag & OPTION_MASK_ISA_SHSTK)
+      || (flag_cf_protection & CF_RETURN))
     {
       def_or_undef (parse_in, "__SHSTK__");
       if (flag_cf_protection != CF_NONE)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d24c81b0dfe..2a628734068 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2701,7 +2701,7 @@ public:
   /* opt_pass methods: */
   virtual bool gate (function *)
     {
-      return ((flag_cf_protection & CF_BRANCH) && TARGET_IBT);
+      return ((flag_cf_protection & CF_BRANCH));
     }
 
   virtual unsigned int execute (function *)
@@ -4931,49 +4931,9 @@ ix86_option_override_internal (bool main_args_p,
     target_option_default_node = target_option_current_node
       = build_target_option_node (opts);
 
-  /* Do not support control flow instrumentation if CET is not enabled.  */
-  cf_protection_level cf_protection
-    = (cf_protection_level) (opts->x_flag_cf_protection & ~CF_SET);
-  if (cf_protection != CF_NONE)
-    {
-      switch (cf_protection)
-	{
-	case CF_BRANCH:
-	  if (! TARGET_IBT_P (opts->x_ix86_isa_flags2))
-	    {
-	      error ("%<-fcf-protection=branch%> requires Intel CET "
-		     "support. Use -mcet or -mibt option to enable CET");
-	      flag_cf_protection = CF_NONE;
-	      return false;
-	    }
-	  break;
-	case CF_RETURN:
-	  if (! TARGET_SHSTK_P (opts->x_ix86_isa_flags))
-	    {
-	      error ("%<-fcf-protection=return%> requires Intel CET "
-		     "support. Use -mcet or -mshstk option to enable CET");
-	      flag_cf_protection = CF_NONE;
-	      return false;
-	    }
-	  break;
-	case CF_FULL:
-	  if (   ! TARGET_IBT_P (opts->x_ix86_isa_flags2)
-		 || ! TARGET_SHSTK_P (opts->x_ix86_isa_flags))
-	    {
-	      error ("%<-fcf-protection=full%> requires Intel CET "
-		     "support. Use -mcet or both of -mibt and "
-		     "-mshstk options to enable CET");
-	      flag_cf_protection = CF_NONE;
-	      return false;
-	    }
-	  break;
-	default:
-	  gcc_unreachable ();
-	}
-
-      opts->x_flag_cf_protection =
-	(cf_protection_level) (cf_protection | CF_SET);
-    }
+  if (opts->x_flag_cf_protection != CF_NONE)
+    opts->x_flag_cf_protection =
+      (cf_protection_level) (opts->x_flag_cf_protection | CF_SET);
 
   if (ix86_tune_features [X86_TUNE_AVOID_128FMA_CHAINS])
     maybe_set_param_value (PARAM_AVOID_FMA_MAX_BITS, 128,
@@ -30408,7 +30368,7 @@ ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
   rtx mem, fnaddr;
   int opcode;
   int offset = 0;
-  bool need_endbr = (flag_cf_protection & CF_BRANCH) && TARGET_IBT;
+  bool need_endbr = (flag_cf_protection & CF_BRANCH);
 
   fnaddr = XEXP (DECL_RTL (fndecl), 0);
 
@@ -41766,7 +41726,7 @@ x86_output_mi_thunk (FILE *file, tree, HOST_WIDE_INT delta,
   emit_note (NOTE_INSN_PROLOGUE_END);
 
   /* CET is enabled, insert EB instruction.  */
-  if ((flag_cf_protection & CF_BRANCH) && TARGET_IBT)
+  if ((flag_cf_protection & CF_BRANCH))
     emit_insn (gen_nop_endbr ());
 
   /* If VCALL_OFFSET, we'll need THIS in a register.  Might as well
@@ -49766,7 +49726,7 @@ ix86_bnd_prefixed_insn_p (rtx insn)
 static bool
 ix86_notrack_prefixed_insn_p (rtx insn)
 {
-  if (!insn || !((flag_cf_protection & CF_BRANCH) && TARGET_IBT))
+  if (!insn || !((flag_cf_protection & CF_BRANCH)))
     return false;
 
   if (CALL_P (insn))
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 95ca2cf9e3d..48daff1c9eb 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -20278,7 +20278,7 @@
 (define_insn "rdssp<mode>"
   [(set (match_operand:SWI48x 0 "register_operand" "=r")
 	(unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
-  "TARGET_SHSTK"
+  "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
   "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
   [(set_attr "length" "6")
    (set_attr "type" "other")])
@@ -20286,7 +20286,7 @@
 (define_insn "incssp<mode>"
   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
 		   UNSPECV_INCSSP)]
-  "TARGET_SHSTK"
+  "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
   "incssp<mskmodesuffix>\t%0"
   [(set_attr "length" "4")
    (set_attr "type" "other")])
@@ -20341,7 +20341,7 @@
 
 (define_insn "nop_endbr"
   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
-  "TARGET_IBT"
+  "TARGET_IBT || (flag_cf_protection & CF_BRANCH)"
   "*
 { return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }"
   [(set_attr "length" "4")
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index c063ae8b1ae..e55acf83d97 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -1008,17 +1008,16 @@ Generate code which uses only the general registers.
 
 mcet
 Target Report Var(flag_cet) Init(0)
-Support Control-flow Enforcement Technology (CET) built-in functions
-and code generation.
+Support Control-flow Enforcement Technology (CET) built-in functions.
 
 mibt
 Target Report Mask(ISA_IBT) Var(ix86_isa_flags2) Save
-Specifically enables an indirect branch tracking feature from Control-flow
-Enforcement Technology (CET).
+Specifically enable indirect branch tracking built-in functions from
+Control-flow Enforcement Technology (CET).
 
 mshstk
 Target Report Mask(ISA_SHSTK) Var(ix86_isa_flags) Save
-Specifically enables an shadow stack support feature from Control-flow
+Specifically enable shadow stack built-in functions from Control-flow
 Enforcement Technology (CET).
 
 mcet-switch
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 8c0d275626f..1d8a0bd0ca0 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -11833,9 +11833,7 @@ which functions and calls should be skipped from instrumentation
 (@pxref{Function Attributes}).
 
 Currently the x86 GNU/Linux target provides an implementation based
-on Intel Control-flow Enforcement Technology (CET).  Instrumentation
-for x86 is controlled by target-specific options @option{-mcet},
-@option{-mibt} and @option{-mshstk} (@pxref{x86 Options}).
+on Intel Control-flow Enforcement Technology (CET).
 
 @item -fstack-protector
 @opindex fstack-protector
@@ -27345,11 +27343,9 @@ the file containing the CPU detection code should be compiled without
 these options.
 
 The @option{-mcet} option turns on the @option{-mibt} and @option{-mshstk}
-options.  The @option{-mibt} option enables indirect branch tracking support
-and the @option{-mshstk} option enables shadow stack support from
-Intel Control-flow Enforcement Technology (CET).  The compiler also provides
-a number of built-in functions for fine-grained control in a CET-based
-application.  See @xref{x86 Built-in Functions}, for more information.
+options.  The compiler provides a number of built-in functions for
+fine-grained control in a CET-based application.  See
+@xref{x86 Built-in Functions}, for more information.
 
 @item -mdump-tune-features
 @opindex mdump-tune-features
@@ -27445,19 +27441,15 @@ This option enables use of the @code{movbe} instruction to implement
 
 @item -mibt
 @opindex mibt
-This option tells the compiler to use indirect branch tracking support
-(for indirect calls and jumps) from x86 Control-flow Enforcement
-Technology (CET).  The option has effect only if the
-@option{-fcf-protection=full} or @option{-fcf-protection=branch} option
-is specified. The option @option{-mibt} is on by default when the
-@code{-mcet} option is specified.
+This option enables indirect branch tracking built-in functions from
+x86 Control-flow Enforcement Technology (CET).  The option
+@option{-mibt} is on by default when the @code{-mcet} option is
+specified.
 
 @item -mshstk
 @opindex mshstk
-This option tells the compiler to use shadow stack support (return
-address tracking) from x86 Control-flow Enforcement Technology (CET).
-The option has effect only if the @option{-fcf-protection=full} or
-@option{-fcf-protection=return} option is specified.  The option
+This option enables shadow stack built-in functions from x86
+Control-flow Enforcement Technology (CET).  The option
 @option{-mshstk} is on by default when the @option{-mcet} option is
 specified.
 
diff --git a/gcc/testsuite/c-c++-common/attr-nocf-check-1.c b/gcc/testsuite/c-c++-common/attr-nocf-check-1.c
index 15f69731b91..c5ac7cb9f86 100644
--- a/gcc/testsuite/c-c++-common/attr-nocf-check-1.c
+++ b/gcc/testsuite/c-c++-common/attr-nocf-check-1.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-additional-options "-fcf-protection=none" } */
 
 int func (int) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */
 int (*fptr) (int) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */
diff --git a/gcc/testsuite/c-c++-common/attr-nocf-check-3.c b/gcc/testsuite/c-c++-common/attr-nocf-check-3.c
index ad1ca7eec9b..02b56cb155e 100644
--- a/gcc/testsuite/c-c++-common/attr-nocf-check-3.c
+++ b/gcc/testsuite/c-c++-common/attr-nocf-check-3.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-additional-options "-fcf-protection=none" } */
 
 int  foo (void) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */
 void (*foo1) (void) __attribute__((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-1.c b/gcc/testsuite/c-c++-common/fcf-protection-1.c
index 8e71f47dde0..f59a8fbdfdc 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-1.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-1.c
@@ -1,4 +1,3 @@
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection=full" } */
-/* { dg-error "'-fcf-protection=full' requires Intel CET.*-mcet.*-mibt and -mshstk option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
 /* { dg-error "'-fcf-protection=full' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-2.c b/gcc/testsuite/c-c++-common/fcf-protection-2.c
index d7d6db0e95d..61059725af6 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-2.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-2.c
@@ -1,4 +1,3 @@
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection=branch" } */
-/* { dg-error "'-fcf-protection=branch' requires Intel CET.*-mcet or -mibt option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
 /* { dg-error "'-fcf-protection=branch' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-3.c b/gcc/testsuite/c-c++-common/fcf-protection-3.c
index 5b903c5fa51..257e944c4a6 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-3.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-3.c
@@ -1,4 +1,3 @@
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection=return" } */
-/* { dg-error "'-fcf-protection=return' requires Intel CET.*-mcet or -mshstk option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
 /* { dg-error "'-fcf-protection=return' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-5.c b/gcc/testsuite/c-c++-common/fcf-protection-5.c
index d7a67801e2e..dc317f84b07 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-5.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-5.c
@@ -1,4 +1,3 @@
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection" } */
-/* { dg-error "'-fcf-protection=full' requires Intel CET.*-mcet.*-mibt and -mshstk option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
 /* { dg-error "'-fcf-protection=full' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-6.c b/gcc/testsuite/c-c++-common/fcf-protection-6.c
index 532e76e6915..61059725af6 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-6.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-6.c
@@ -1,5 +1,3 @@
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection=branch" } */
-/* { dg-additional-options "-mshstk" { target { i?86-*-* x86_64-*-* } } } */
-/* { dg-error "'-fcf-protection=branch' requires Intel CET.*-mcet or -mibt option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
 /* { dg-error "'-fcf-protection=branch' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-7.c b/gcc/testsuite/c-c++-common/fcf-protection-7.c
index 4c879692708..257e944c4a6 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-7.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-7.c
@@ -1,5 +1,3 @@
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection=return" } */
-/* { dg-additional-options "-mibt" { target { i?86-*-* x86_64-*-* } } } */
-/* { dg-error "'-fcf-protection=return' requires Intel CET.*-mcet or -mshstk option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
 /* { dg-error "'-fcf-protection=return' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/gcc.dg/march-generic.c b/gcc/testsuite/gcc.dg/march-generic.c
index fb5b83c7d74..f9c00e4a1c1 100644
--- a/gcc/testsuite/gcc.dg/march-generic.c
+++ b/gcc/testsuite/gcc.dg/march-generic.c
@@ -1,6 +1,6 @@
 /* { dg-do compile { target i?86-*-* x86_64-*-* } } */
 /* { dg-skip-if "" { *-*-* } { "-march=*" } { "" } } */
-/* { dg-options "-march=generic" } */
+/* { dg-options "-march=generic -fcf-protection=none" } */
 /* { dg-error "'generic' CPU can be used only for '-mtune=' switch" "" { target *-*-* } 0 } */
 /* { dg-bogus "march" "" { target *-*-* } 0 } */
 int i;
diff --git a/gcc/testsuite/gcc.target/i386/align-limit.c b/gcc/testsuite/gcc.target/i386/align-limit.c
index d3d8dc5656e..849d741189c 100644
--- a/gcc/testsuite/gcc.target/i386/align-limit.c
+++ b/gcc/testsuite/gcc.target/i386/align-limit.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -falign-functions=64 -flimit-function-alignment -march=amdfam10" } */
+/* { dg-options "-O2 -falign-functions=64 -flimit-function-alignment -march=amdfam10 -fcf-protection=none" } */
 /* { dg-final { scan-assembler ".p2align 6,,1" } } */
 /* { dg-final { scan-assembler-not ".p2align 6,,63" } } */
 
diff --git a/gcc/testsuite/gcc.target/i386/cet-label-3.c b/gcc/testsuite/gcc.target/i386/cet-label-3.c
new file mode 100644
index 00000000000..5e0892e5b4d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cet-label-3.c
@@ -0,0 +1,16 @@
+/* Verify that -fcf-protection works without -mcet.  */
+/* { dg-do compile } */
+/* { dg-options "-O -fcf-protection" } */
+/* { dg-final { scan-assembler-times "endbr32" 3 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "endbr64" 3 { target { ! ia32 } } } } */
+
+int func (int arg)
+{
+  static void *array[] = { &&foo, &&bar };
+
+  goto *array[arg];
+foo:
+  return arg*111;
+bar:
+  return arg*777;
+}
diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c
index 7987d53d305..0bddf54862a 100644
--- a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c
+++ b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c
@@ -1,6 +1,6 @@
 /* Verify nocf_check functions are not ICF optimized.  */
 /* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -fcf-protection=none" } */
 /* { dg-final { scan-assembler-not "endbr" } } */
 /* { dg-final { scan-assembler-not "fn3:" } } */
 /* { dg-final { scan-assembler "set\[ \t]+fn2,fn1" } } */
diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c
index 07c4a6b61ef..ed2d53ac5ef 100644
--- a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c
+++ b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c
@@ -1,6 +1,6 @@
 /* Verify nocf_check function calls are not ICF optimized.  */
 /* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -fcf-protection=none" } */
 /* { dg-final { scan-assembler-not "endbr" } } */
 /* { dg-final { scan-assembler-not "fn2:" } } */
 /* { dg-final { scan-assembler "set\[ \t]+fn2,fn1" } } */
diff --git a/gcc/testsuite/gcc.target/i386/cet-property-2.c b/gcc/testsuite/gcc.target/i386/cet-property-2.c
index 5a87dab92f1..bca6f6cdeb7 100644
--- a/gcc/testsuite/gcc.target/i386/cet-property-2.c
+++ b/gcc/testsuite/gcc.target/i386/cet-property-2.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-mcet" } */
+/* { dg-options "-mcet -fcf-protection=none" } */
 /* { dg-final { scan-assembler-not ".note.gnu.property" } } */
 
 extern void foo (void);
diff --git a/gcc/testsuite/gcc.target/i386/cet-property-3.c b/gcc/testsuite/gcc.target/i386/cet-property-3.c
new file mode 100644
index 00000000000..3e211c970aa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cet-property-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-fcf-protection" } */
+/* { dg-final { scan-assembler ".note.gnu.property" } } */
+
+extern void foo (void);
+
+void
+bar (void)
+{
+  foo ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/cet-sjlj-7.c b/gcc/testsuite/gcc.target/i386/cet-sjlj-7.c
new file mode 100644
index 00000000000..1b624327d0f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cet-sjlj-7.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fcf-protection" } */
+/* { dg-final { scan-assembler-times "endbr32" 2 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "endbr64" 2 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "call	_?setjmp" 1 } } */
+/* { dg-final { scan-assembler-times "call	longjmp" 1 } } */
+
+#include <stdio.h>
+#include <setjmp.h>
+
+jmp_buf buf;
+static int bar (int);
+
+__attribute__ ((noinline, noclone))
+static int
+foo (int i)
+{
+  int j = i * 11;
+
+  if (!setjmp (buf))
+    {
+      j += 33;
+      printf ("After setjmp: j = %d\n", j);
+      bar (j);
+    }
+
+  return j + i;
+}
+
+__attribute__ ((noinline, noclone))
+static int
+bar (int i)
+{
+ int j = i;
+
+  j -= 111;
+  printf ("In longjmp: j = %d\n", j);
+  longjmp (buf, 1);
+
+  return j;
+}
+
+int
+main ()
+{
+  foo (10);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
index d53fc887dcc..ffe7350fce4 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
@@ -37,7 +37,7 @@ bar (int i)
 }
 
 /* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk(_nt|)_(r|e)ax" } } */
 /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
 /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
index 2b9a33e93dc..b7339745116 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
@@ -36,7 +36,7 @@ bar (int i)
 }
 
 /* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */
-/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */
+/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk(_nt|)_(r|e)ax" } } */
 /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */
 /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */
 /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr85403.c b/gcc/testsuite/gcc.target/i386/pr85403.c
index f4fb12dd4e2..0bbd7ca5610 100644
--- a/gcc/testsuite/gcc.target/i386/pr85403.c
+++ b/gcc/testsuite/gcc.target/i386/pr85403.c
@@ -7,4 +7,4 @@ int
 foo ()
 {
   return -2;
-} /* { dg-error "requires Intel CET support" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr85417-1.c b/gcc/testsuite/gcc.target/i386/pr85417-1.c
new file mode 100644
index 00000000000..17d52403744
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr85417-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O3 -fcf-protection" } */
+/* { dg-final { scan-assembler "vpshufb" } } */
+/* { dg-final { scan-assembler "punpcklbw" } } */
+
+__attribute__((target_clones("arch=core-avx2","arch=slm","default")))
+void
+foo(char *in, char *out, int size)
+{
+  int i;
+  for(i = 0; i < size; i++)
+    {
+	out[2 * i] = in[i];
+	out[2 * i + 1] = in[i];
+    }
+}
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-26.c b/gcc/testsuite/gcc.target/i386/ret-thunk-26.c
index 9144e988735..dc722c2f5f9 100644
--- a/gcc/testsuite/gcc.target/i386/ret-thunk-26.c
+++ b/gcc/testsuite/gcc.target/i386/ret-thunk-26.c
@@ -1,6 +1,6 @@
 /* PR target/r84530 */
 /* { dg-do run } */
-/* { dg-options "-Os -mfunction-return=thunk" } */
+/* { dg-options "-Os -mfunction-return=thunk -fcf-protection=none" } */
 
 struct S { int i; };
 __attribute__((const, noinline, noclone))
-- 
2.14.3
Uros Bizjak April 19, 2018, 1:35 p.m. | #19
On Thu, Apr 19, 2018 at 3:30 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Wed, Apr 18, 2018 at 01:35:33PM +0200, Richard Biener wrote:

>> On Wed, Apr 18, 2018 at 1:24 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>> > On Tue, Apr 17, 2018 at 12:25 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>> >> On Tue, Apr 17, 2018 at 12:25 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>> >>> On Tue, Apr 17, 2018 at 12:03 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>> >>>> On Tue, Apr 17, 2018 at 11:55 AM, Uros Bizjak <ubizjak@gmail.com> wrote:

>> >>>>> On Tue, Apr 17, 2018 at 8:42 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:

>> >>>>>> -fcf-protection -mcet can't be used with IFUNC features, like symbol

>> >>>>>> multiversioning or target clone, since IBT/SHSTK are applied to the whole

>> >>>>>> program and they may be disabled in some functions.  But -fcf-protection

>> >>>>>> is implemented with multi-byte NOPs on all 64-bit processors as well as

>> >>>>>> 32-bit processors starting with Pentium Pro.  If -fcf-protection requires

>> >>>>>> -mcet, IFUNC features can't be used on Linux when -fcf-protection is

>> >>>>>> enabled by default.

>> >>>>>>

>> >>>>>> This patch changes -fcf-protection to to enable the NOP portion of CET

>> >>>>>> ISAs unless IBT and/or SHSTK are disabled explicitly.  The rest of CET

>> >>>>>> ISAs, including intrinsics, still requires -mcet, -mibt or -mshstk.

>> >>>>>>

>> >>>>>> OK for trunk?

>> >>>>>

>> >>>>> As said in the PR, NOP sequences have non-zero cost in the executable

>> >>>>> (they enlarge the executable), so I don't think this feature should be

>> >>>>> enabled by default.

>> >>>>>

>> >>>>> There is always a configure option if someone wants their compiler to

>> >>>>> always emit relevant multi-byte nops.

>> >>>>

>> >>>> What we need is an option to enable -fcf-function with multi-byte NOPs

>> >>>> without -mcet which enables the full CET ISAs.  A configure option

>> >>>> without the corresponding the command-line option makes test and

>> >>>> debug difficult.   I can add

>> >>>>

>> >>>> --enable-cf-function-nop or --with-cf-function-nop

>> >>>>

>> >>>> with

>> >>>>

>> >>>> -fct-function-nop

>> >>>>

>> >>>

>> >>> How about adding -mno-cet, which enables the NOP portion of CET

>> >>

>> >> I meant -mnop-cet, not -mno-cet.

>> >>

>> >

>> > Here is a patch to add -mnop and use it with -fcf-protection.

>>

>> +mnop

>> +Target Report Var(flag_nop) Init(0)

>> +Support multi-byte NOP code generation.

>>

>> the option name is incredibly bad and the documentation doesn't make it

>> better either.  The invoke.texi docs refer to duplicate {-mcet}.

>>

>> Isn't there a -fcf-protection sub-set that can be used to automatically

>> enable this?  Or simply do this mode by default when

>> -fcf-protection is used but neither -mcet nor -mibt is enabled?

>>

>

> Since multi-byte NOPs are used to implement -fcf-protection on x86, we

> propose a new design for -fcf-protection:

>

> 1. -fcf-protection option will report the unsupported error on non-x86

> platform. On x86 platform it's supported and inserts endbr-nop

> instructions and properties, depending on its value (full/branch/return)

> 2. -mcet/-mibt/-mshstk options control intrinsics only.

> 3. These options are independent and do not influence each other so no

> need for cross checking between them.

>

> OK for trunk?


This patch touches only CET related code, so Igor's OK should be enough.

Uros.
Richard Biener April 19, 2018, 1:56 p.m. | #20
On Thu, Apr 19, 2018 at 3:30 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Wed, Apr 18, 2018 at 01:35:33PM +0200, Richard Biener wrote:

>> On Wed, Apr 18, 2018 at 1:24 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>> > On Tue, Apr 17, 2018 at 12:25 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>> >> On Tue, Apr 17, 2018 at 12:25 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>> >>> On Tue, Apr 17, 2018 at 12:03 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

>> >>>> On Tue, Apr 17, 2018 at 11:55 AM, Uros Bizjak <ubizjak@gmail.com> wrote:

>> >>>>> On Tue, Apr 17, 2018 at 8:42 PM, H.J. Lu <hongjiu.lu@intel.com> wrote:

>> >>>>>> -fcf-protection -mcet can't be used with IFUNC features, like symbol

>> >>>>>> multiversioning or target clone, since IBT/SHSTK are applied to the whole

>> >>>>>> program and they may be disabled in some functions.  But -fcf-protection

>> >>>>>> is implemented with multi-byte NOPs on all 64-bit processors as well as

>> >>>>>> 32-bit processors starting with Pentium Pro.  If -fcf-protection requires

>> >>>>>> -mcet, IFUNC features can't be used on Linux when -fcf-protection is

>> >>>>>> enabled by default.

>> >>>>>>

>> >>>>>> This patch changes -fcf-protection to to enable the NOP portion of CET

>> >>>>>> ISAs unless IBT and/or SHSTK are disabled explicitly.  The rest of CET

>> >>>>>> ISAs, including intrinsics, still requires -mcet, -mibt or -mshstk.

>> >>>>>>

>> >>>>>> OK for trunk?

>> >>>>>

>> >>>>> As said in the PR, NOP sequences have non-zero cost in the executable

>> >>>>> (they enlarge the executable), so I don't think this feature should be

>> >>>>> enabled by default.

>> >>>>>

>> >>>>> There is always a configure option if someone wants their compiler to

>> >>>>> always emit relevant multi-byte nops.

>> >>>>

>> >>>> What we need is an option to enable -fcf-function with multi-byte NOPs

>> >>>> without -mcet which enables the full CET ISAs.  A configure option

>> >>>> without the corresponding the command-line option makes test and

>> >>>> debug difficult.   I can add

>> >>>>

>> >>>> --enable-cf-function-nop or --with-cf-function-nop

>> >>>>

>> >>>> with

>> >>>>

>> >>>> -fct-function-nop

>> >>>>

>> >>>

>> >>> How about adding -mno-cet, which enables the NOP portion of CET

>> >>

>> >> I meant -mnop-cet, not -mno-cet.

>> >>

>> >

>> > Here is a patch to add -mnop and use it with -fcf-protection.

>>

>> +mnop

>> +Target Report Var(flag_nop) Init(0)

>> +Support multi-byte NOP code generation.

>>

>> the option name is incredibly bad and the documentation doesn't make it

>> better either.  The invoke.texi docs refer to duplicate {-mcet}.

>>

>> Isn't there a -fcf-protection sub-set that can be used to automatically

>> enable this?  Or simply do this mode by default when

>> -fcf-protection is used but neither -mcet nor -mibt is enabled?

>>

>

> Since multi-byte NOPs are used to implement -fcf-protection on x86, we

> propose a new design for -fcf-protection:

>

> 1. -fcf-protection option will report the unsupported error on non-x86

> platform. On x86 platform it's supported and inserts endbr-nop

> instructions and properties, depending on its value (full/branch/return)

> 2. -mcet/-mibt/-mshstk options control intrinsics only.

> 3. These options are independent and do not influence each other so no

> need for cross checking between them.

>

> OK for trunk?


I think it makes more sense this way, thanks for doing the change
(this isn't an approval).

Richard.

>

> H.J.

> ----

> ----

> -fcf-protection -mcet can't be used with IFUNC features, like symbol

> multiversioning or target clone, since IBT/SHSTK are applied to the whole

> program and they may be disabled in some functions.  But -fcf-protection

> is implemented with multi-byte NOPs on all 64-bit processors as well as

> 32-bit processors starting with Pentium Pro.  If -fcf-protection requires

> -mcet, IFUNC features can't be used on Linux when -fcf-protection is

> enabled by default.

>

> This patch changes -fcf-protection to implement indirect branch and

> return address tracking with multi-byte NOPs.  -mibt and -mshstk are

> changed to only CET built-in functions.  CET tests are updated to

> allow -fcf-protection without -mibt, -mshstk and -mcet on x86.

> -fcf-protection=none are also added to tests which fail with

> -fcf-protection so that -fcf-protection can be added to RUNTESTFLAGS

> to verify -fcf-protection implementation.

>

> gcc/

>

>         PR target/85417

>         * config/i386/cet.c (file_end_indicate_exec_stack_and_cet):

>         Check flag_cf_protection instead of TARGET_IBT and TARGET_SHSTK.

>         * config/i386/i386-c.c (ix86_target_macros_internal): Also

>         define __IBT__ and __SHSTK__ for -fcf-protection.

>         * config/i386/i386.c (pass_insert_endbranch::gate): Don't check

>         TARGET_IBT.

>         (ix86_trampoline_init): Likewise.

>         (x86_output_mi_thunk): Likewise.

>         (ix86_notrack_prefixed_insn_p): Likewise.

>         (ix86_option_override_internal): Don't disallow -fcf-protection.

>         * config/i386/i386.md (rdssp<mode>): Also enable for

>         -fcf-protection.

>         (incssp<mode>): Likewise.

>         (nop_endbr): Likewise.

>         * config/i386/i386.opt (mcet): Change help message to built-in

>         functions only.

>         (mibt): Likewise.

>         (mshstk): Likewise.

>         * doc/invoke.texi: Remove -mcet, -mibt and -mshstk condition

>         on -fcf-protection.  Change -mcet, -mibt and -mshstk to only

>         enable CET built-in functions.

>

> gcc/testsuite/

>

>         PR target/85417

>         * c-c++-common/attr-nocf-check-1.c: Compile with

>         -fcf-protection=none.

>         * c-c++-common/attr-nocf-check-3.c: Likewise.

>         * gcc.dg/march-generic.c: Likewise.

>         * gcc.target/i386/align-limit.c: Likewise.

>         * gcc.target/i386/cet-notrack-icf-1.c: Likewise.

>         * gcc.target/i386/cet-notrack-icf-3.c: Likewise.

>         * gcc.target/i386/cet-property-2.c: Likewise.

>         * gcc.target/i386/ret-thunk-26.c: Likewise.

>         * c-c++-common/fcf-protection-1.c: Remove dg-error for x86

>         targets.

>         * c-c++-common/fcf-protection-2.c: Likewise.

>         * c-c++-common/fcf-protection-3.c: Likewise.

>         * c-c++-common/fcf-protection-5.c: Likewise.

>         * c-c++-common/fcf-protection-6.c: Likewise.

>         * c-c++-common/fcf-protection-7.c: Likewise.

>         * gcc.target/i386/cet-label-3.c: New test.

>         * gcc.target/i386/cet-property-3.c: Likewise.

>         * gcc.target/i386/cet-sjlj-7.c: Likewise.

>         * gcc.target/i386/pr85417-1.c: Likewise.

>         * gcc.target/i386/indirect-thunk-attr-7.c: Also expect

>         __x86_indirect_thunk_nt_(r|e)ax

>         * gcc.target/i386/indirect-thunk-extern-7.c: Likewise.

>         * gcc.target/i386/pr85403.c: Remove dg-error,

> ---

>  gcc/config/i386/cet.c                              |  4 +-

>  gcc/config/i386/i386-c.c                           |  6 ++-

>  gcc/config/i386/i386.c                             | 54 +++-------------------

>  gcc/config/i386/i386.md                            |  6 +--

>  gcc/config/i386/i386.opt                           |  9 ++--

>  gcc/doc/invoke.texi                                | 28 ++++-------

>  gcc/testsuite/c-c++-common/attr-nocf-check-1.c     |  1 +

>  gcc/testsuite/c-c++-common/attr-nocf-check-3.c     |  1 +

>  gcc/testsuite/c-c++-common/fcf-protection-1.c      |  1 -

>  gcc/testsuite/c-c++-common/fcf-protection-2.c      |  1 -

>  gcc/testsuite/c-c++-common/fcf-protection-3.c      |  1 -

>  gcc/testsuite/c-c++-common/fcf-protection-5.c      |  1 -

>  gcc/testsuite/c-c++-common/fcf-protection-6.c      |  2 -

>  gcc/testsuite/c-c++-common/fcf-protection-7.c      |  2 -

>  gcc/testsuite/gcc.dg/march-generic.c               |  2 +-

>  gcc/testsuite/gcc.target/i386/align-limit.c        |  2 +-

>  gcc/testsuite/gcc.target/i386/cet-label-3.c        | 16 +++++++

>  gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c  |  2 +-

>  gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c  |  2 +-

>  gcc/testsuite/gcc.target/i386/cet-property-2.c     |  2 +-

>  gcc/testsuite/gcc.target/i386/cet-property-3.c     | 11 +++++

>  gcc/testsuite/gcc.target/i386/cet-sjlj-7.c         | 48 +++++++++++++++++++

>  .../gcc.target/i386/indirect-thunk-attr-7.c        |  2 +-

>  .../gcc.target/i386/indirect-thunk-extern-7.c      |  2 +-

>  gcc/testsuite/gcc.target/i386/pr85403.c            |  2 +-

>  gcc/testsuite/gcc.target/i386/pr85417-1.c          | 17 +++++++

>  gcc/testsuite/gcc.target/i386/ret-thunk-26.c       |  2 +-

>  27 files changed, 133 insertions(+), 94 deletions(-)

>  create mode 100644 gcc/testsuite/gcc.target/i386/cet-label-3.c

>  create mode 100644 gcc/testsuite/gcc.target/i386/cet-property-3.c

>  create mode 100644 gcc/testsuite/gcc.target/i386/cet-sjlj-7.c

>  create mode 100644 gcc/testsuite/gcc.target/i386/pr85417-1.c

>

> diff --git a/gcc/config/i386/cet.c b/gcc/config/i386/cet.c

> index 4a1e013fdde..eb3be171471 100644

> --- a/gcc/config/i386/cet.c

> +++ b/gcc/config/i386/cet.c

> @@ -34,11 +34,11 @@ file_end_indicate_exec_stack_and_cet (void)

>

>    unsigned int feature_1 = 0;

>

> -  if (TARGET_IBT)

> +  if (flag_cf_protection & CF_BRANCH)

>      /* GNU_PROPERTY_X86_FEATURE_1_IBT.  */

>      feature_1 |= 0x1;

>

> -  if (TARGET_SHSTK)

> +  if (flag_cf_protection & CF_RETURN)

>      /* GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */

>      feature_1 |= 0x2;

>

> diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c

> index 2e0e9f66c9e..9961d418ee9 100644

> --- a/gcc/config/i386/i386-c.c

> +++ b/gcc/config/i386/i386-c.c

> @@ -499,13 +499,15 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,

>      def_or_undef (parse_in, "__RDPID__");

>    if (isa_flag & OPTION_MASK_ISA_GFNI)

>      def_or_undef (parse_in, "__GFNI__");

> -  if (isa_flag2 & OPTION_MASK_ISA_IBT)

> +  if ((isa_flag2 & OPTION_MASK_ISA_IBT)

> +      || (flag_cf_protection & CF_BRANCH))

>      {

>        def_or_undef (parse_in, "__IBT__");

>        if (flag_cf_protection != CF_NONE)

>         def_or_undef (parse_in, "__CET__");

>      }

> -  if (isa_flag & OPTION_MASK_ISA_SHSTK)

> +  if ((isa_flag & OPTION_MASK_ISA_SHSTK)

> +      || (flag_cf_protection & CF_RETURN))

>      {

>        def_or_undef (parse_in, "__SHSTK__");

>        if (flag_cf_protection != CF_NONE)

> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c

> index d24c81b0dfe..2a628734068 100644

> --- a/gcc/config/i386/i386.c

> +++ b/gcc/config/i386/i386.c

> @@ -2701,7 +2701,7 @@ public:

>    /* opt_pass methods: */

>    virtual bool gate (function *)

>      {

> -      return ((flag_cf_protection & CF_BRANCH) && TARGET_IBT);

> +      return ((flag_cf_protection & CF_BRANCH));

>      }

>

>    virtual unsigned int execute (function *)

> @@ -4931,49 +4931,9 @@ ix86_option_override_internal (bool main_args_p,

>      target_option_default_node = target_option_current_node

>        = build_target_option_node (opts);

>

> -  /* Do not support control flow instrumentation if CET is not enabled.  */

> -  cf_protection_level cf_protection

> -    = (cf_protection_level) (opts->x_flag_cf_protection & ~CF_SET);

> -  if (cf_protection != CF_NONE)

> -    {

> -      switch (cf_protection)

> -       {

> -       case CF_BRANCH:

> -         if (! TARGET_IBT_P (opts->x_ix86_isa_flags2))

> -           {

> -             error ("%<-fcf-protection=branch%> requires Intel CET "

> -                    "support. Use -mcet or -mibt option to enable CET");

> -             flag_cf_protection = CF_NONE;

> -             return false;

> -           }

> -         break;

> -       case CF_RETURN:

> -         if (! TARGET_SHSTK_P (opts->x_ix86_isa_flags))

> -           {

> -             error ("%<-fcf-protection=return%> requires Intel CET "

> -                    "support. Use -mcet or -mshstk option to enable CET");

> -             flag_cf_protection = CF_NONE;

> -             return false;

> -           }

> -         break;

> -       case CF_FULL:

> -         if (   ! TARGET_IBT_P (opts->x_ix86_isa_flags2)

> -                || ! TARGET_SHSTK_P (opts->x_ix86_isa_flags))

> -           {

> -             error ("%<-fcf-protection=full%> requires Intel CET "

> -                    "support. Use -mcet or both of -mibt and "

> -                    "-mshstk options to enable CET");

> -             flag_cf_protection = CF_NONE;

> -             return false;

> -           }

> -         break;

> -       default:

> -         gcc_unreachable ();

> -       }

> -

> -      opts->x_flag_cf_protection =

> -       (cf_protection_level) (cf_protection | CF_SET);

> -    }

> +  if (opts->x_flag_cf_protection != CF_NONE)

> +    opts->x_flag_cf_protection =

> +      (cf_protection_level) (opts->x_flag_cf_protection | CF_SET);

>

>    if (ix86_tune_features [X86_TUNE_AVOID_128FMA_CHAINS])

>      maybe_set_param_value (PARAM_AVOID_FMA_MAX_BITS, 128,

> @@ -30408,7 +30368,7 @@ ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)

>    rtx mem, fnaddr;

>    int opcode;

>    int offset = 0;

> -  bool need_endbr = (flag_cf_protection & CF_BRANCH) && TARGET_IBT;

> +  bool need_endbr = (flag_cf_protection & CF_BRANCH);

>

>    fnaddr = XEXP (DECL_RTL (fndecl), 0);

>

> @@ -41766,7 +41726,7 @@ x86_output_mi_thunk (FILE *file, tree, HOST_WIDE_INT delta,

>    emit_note (NOTE_INSN_PROLOGUE_END);

>

>    /* CET is enabled, insert EB instruction.  */

> -  if ((flag_cf_protection & CF_BRANCH) && TARGET_IBT)

> +  if ((flag_cf_protection & CF_BRANCH))

>      emit_insn (gen_nop_endbr ());

>

>    /* If VCALL_OFFSET, we'll need THIS in a register.  Might as well

> @@ -49766,7 +49726,7 @@ ix86_bnd_prefixed_insn_p (rtx insn)

>  static bool

>  ix86_notrack_prefixed_insn_p (rtx insn)

>  {

> -  if (!insn || !((flag_cf_protection & CF_BRANCH) && TARGET_IBT))

> +  if (!insn || !((flag_cf_protection & CF_BRANCH)))

>      return false;

>

>    if (CALL_P (insn))

> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md

> index 95ca2cf9e3d..48daff1c9eb 100644

> --- a/gcc/config/i386/i386.md

> +++ b/gcc/config/i386/i386.md

> @@ -20278,7 +20278,7 @@

>  (define_insn "rdssp<mode>"

>    [(set (match_operand:SWI48x 0 "register_operand" "=r")

>         (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]

> -  "TARGET_SHSTK"

> +  "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"

>    "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"

>    [(set_attr "length" "6")

>     (set_attr "type" "other")])

> @@ -20286,7 +20286,7 @@

>  (define_insn "incssp<mode>"

>    [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]

>                    UNSPECV_INCSSP)]

> -  "TARGET_SHSTK"

> +  "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"

>    "incssp<mskmodesuffix>\t%0"

>    [(set_attr "length" "4")

>     (set_attr "type" "other")])

> @@ -20341,7 +20341,7 @@

>

>  (define_insn "nop_endbr"

>    [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]

> -  "TARGET_IBT"

> +  "TARGET_IBT || (flag_cf_protection & CF_BRANCH)"

>    "*

>  { return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }"

>    [(set_attr "length" "4")

> diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt

> index c063ae8b1ae..e55acf83d97 100644

> --- a/gcc/config/i386/i386.opt

> +++ b/gcc/config/i386/i386.opt

> @@ -1008,17 +1008,16 @@ Generate code which uses only the general registers.

>

>  mcet

>  Target Report Var(flag_cet) Init(0)

> -Support Control-flow Enforcement Technology (CET) built-in functions

> -and code generation.

> +Support Control-flow Enforcement Technology (CET) built-in functions.

>

>  mibt

>  Target Report Mask(ISA_IBT) Var(ix86_isa_flags2) Save

> -Specifically enables an indirect branch tracking feature from Control-flow

> -Enforcement Technology (CET).

> +Specifically enable indirect branch tracking built-in functions from

> +Control-flow Enforcement Technology (CET).

>

>  mshstk

>  Target Report Mask(ISA_SHSTK) Var(ix86_isa_flags) Save

> -Specifically enables an shadow stack support feature from Control-flow

> +Specifically enable shadow stack built-in functions from Control-flow

>  Enforcement Technology (CET).

>

>  mcet-switch

> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi

> index 8c0d275626f..1d8a0bd0ca0 100644

> --- a/gcc/doc/invoke.texi

> +++ b/gcc/doc/invoke.texi

> @@ -11833,9 +11833,7 @@ which functions and calls should be skipped from instrumentation

>  (@pxref{Function Attributes}).

>

>  Currently the x86 GNU/Linux target provides an implementation based

> -on Intel Control-flow Enforcement Technology (CET).  Instrumentation

> -for x86 is controlled by target-specific options @option{-mcet},

> -@option{-mibt} and @option{-mshstk} (@pxref{x86 Options}).

> +on Intel Control-flow Enforcement Technology (CET).

>

>  @item -fstack-protector

>  @opindex fstack-protector

> @@ -27345,11 +27343,9 @@ the file containing the CPU detection code should be compiled without

>  these options.

>

>  The @option{-mcet} option turns on the @option{-mibt} and @option{-mshstk}

> -options.  The @option{-mibt} option enables indirect branch tracking support

> -and the @option{-mshstk} option enables shadow stack support from

> -Intel Control-flow Enforcement Technology (CET).  The compiler also provides

> -a number of built-in functions for fine-grained control in a CET-based

> -application.  See @xref{x86 Built-in Functions}, for more information.

> +options.  The compiler provides a number of built-in functions for

> +fine-grained control in a CET-based application.  See

> +@xref{x86 Built-in Functions}, for more information.

>

>  @item -mdump-tune-features

>  @opindex mdump-tune-features

> @@ -27445,19 +27441,15 @@ This option enables use of the @code{movbe} instruction to implement

>

>  @item -mibt

>  @opindex mibt

> -This option tells the compiler to use indirect branch tracking support

> -(for indirect calls and jumps) from x86 Control-flow Enforcement

> -Technology (CET).  The option has effect only if the

> -@option{-fcf-protection=full} or @option{-fcf-protection=branch} option

> -is specified. The option @option{-mibt} is on by default when the

> -@code{-mcet} option is specified.

> +This option enables indirect branch tracking built-in functions from

> +x86 Control-flow Enforcement Technology (CET).  The option

> +@option{-mibt} is on by default when the @code{-mcet} option is

> +specified.

>

>  @item -mshstk

>  @opindex mshstk

> -This option tells the compiler to use shadow stack support (return

> -address tracking) from x86 Control-flow Enforcement Technology (CET).

> -The option has effect only if the @option{-fcf-protection=full} or

> -@option{-fcf-protection=return} option is specified.  The option

> +This option enables shadow stack built-in functions from x86

> +Control-flow Enforcement Technology (CET).  The option

>  @option{-mshstk} is on by default when the @option{-mcet} option is

>  specified.

>

> diff --git a/gcc/testsuite/c-c++-common/attr-nocf-check-1.c b/gcc/testsuite/c-c++-common/attr-nocf-check-1.c

> index 15f69731b91..c5ac7cb9f86 100644

> --- a/gcc/testsuite/c-c++-common/attr-nocf-check-1.c

> +++ b/gcc/testsuite/c-c++-common/attr-nocf-check-1.c

> @@ -1,4 +1,5 @@

>  /* { dg-do compile } */

> +/* { dg-additional-options "-fcf-protection=none" } */

>

>  int func (int) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */

>  int (*fptr) (int) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */

> diff --git a/gcc/testsuite/c-c++-common/attr-nocf-check-3.c b/gcc/testsuite/c-c++-common/attr-nocf-check-3.c

> index ad1ca7eec9b..02b56cb155e 100644

> --- a/gcc/testsuite/c-c++-common/attr-nocf-check-3.c

> +++ b/gcc/testsuite/c-c++-common/attr-nocf-check-3.c

> @@ -1,4 +1,5 @@

>  /* { dg-do compile } */

> +/* { dg-additional-options "-fcf-protection=none" } */

>

>  int  foo (void) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */

>  void (*foo1) (void) __attribute__((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */

> diff --git a/gcc/testsuite/c-c++-common/fcf-protection-1.c b/gcc/testsuite/c-c++-common/fcf-protection-1.c

> index 8e71f47dde0..f59a8fbdfdc 100644

> --- a/gcc/testsuite/c-c++-common/fcf-protection-1.c

> +++ b/gcc/testsuite/c-c++-common/fcf-protection-1.c

> @@ -1,4 +1,3 @@

>  /* { dg-do compile } */

>  /* { dg-options "-fcf-protection=full" } */

> -/* { dg-error "'-fcf-protection=full' requires Intel CET.*-mcet.*-mibt and -mshstk option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */

>  /* { dg-error "'-fcf-protection=full' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */

> diff --git a/gcc/testsuite/c-c++-common/fcf-protection-2.c b/gcc/testsuite/c-c++-common/fcf-protection-2.c

> index d7d6db0e95d..61059725af6 100644

> --- a/gcc/testsuite/c-c++-common/fcf-protection-2.c

> +++ b/gcc/testsuite/c-c++-common/fcf-protection-2.c

> @@ -1,4 +1,3 @@

>  /* { dg-do compile } */

>  /* { dg-options "-fcf-protection=branch" } */

> -/* { dg-error "'-fcf-protection=branch' requires Intel CET.*-mcet or -mibt option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */

>  /* { dg-error "'-fcf-protection=branch' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */

> diff --git a/gcc/testsuite/c-c++-common/fcf-protection-3.c b/gcc/testsuite/c-c++-common/fcf-protection-3.c

> index 5b903c5fa51..257e944c4a6 100644

> --- a/gcc/testsuite/c-c++-common/fcf-protection-3.c

> +++ b/gcc/testsuite/c-c++-common/fcf-protection-3.c

> @@ -1,4 +1,3 @@

>  /* { dg-do compile } */

>  /* { dg-options "-fcf-protection=return" } */

> -/* { dg-error "'-fcf-protection=return' requires Intel CET.*-mcet or -mshstk option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */

>  /* { dg-error "'-fcf-protection=return' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */

> diff --git a/gcc/testsuite/c-c++-common/fcf-protection-5.c b/gcc/testsuite/c-c++-common/fcf-protection-5.c

> index d7a67801e2e..dc317f84b07 100644

> --- a/gcc/testsuite/c-c++-common/fcf-protection-5.c

> +++ b/gcc/testsuite/c-c++-common/fcf-protection-5.c

> @@ -1,4 +1,3 @@

>  /* { dg-do compile } */

>  /* { dg-options "-fcf-protection" } */

> -/* { dg-error "'-fcf-protection=full' requires Intel CET.*-mcet.*-mibt and -mshstk option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */

>  /* { dg-error "'-fcf-protection=full' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */

> diff --git a/gcc/testsuite/c-c++-common/fcf-protection-6.c b/gcc/testsuite/c-c++-common/fcf-protection-6.c

> index 532e76e6915..61059725af6 100644

> --- a/gcc/testsuite/c-c++-common/fcf-protection-6.c

> +++ b/gcc/testsuite/c-c++-common/fcf-protection-6.c

> @@ -1,5 +1,3 @@

>  /* { dg-do compile } */

>  /* { dg-options "-fcf-protection=branch" } */

> -/* { dg-additional-options "-mshstk" { target { i?86-*-* x86_64-*-* } } } */

> -/* { dg-error "'-fcf-protection=branch' requires Intel CET.*-mcet or -mibt option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */

>  /* { dg-error "'-fcf-protection=branch' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */

> diff --git a/gcc/testsuite/c-c++-common/fcf-protection-7.c b/gcc/testsuite/c-c++-common/fcf-protection-7.c

> index 4c879692708..257e944c4a6 100644

> --- a/gcc/testsuite/c-c++-common/fcf-protection-7.c

> +++ b/gcc/testsuite/c-c++-common/fcf-protection-7.c

> @@ -1,5 +1,3 @@

>  /* { dg-do compile } */

>  /* { dg-options "-fcf-protection=return" } */

> -/* { dg-additional-options "-mibt" { target { i?86-*-* x86_64-*-* } } } */

> -/* { dg-error "'-fcf-protection=return' requires Intel CET.*-mcet or -mshstk option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */

>  /* { dg-error "'-fcf-protection=return' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */

> diff --git a/gcc/testsuite/gcc.dg/march-generic.c b/gcc/testsuite/gcc.dg/march-generic.c

> index fb5b83c7d74..f9c00e4a1c1 100644

> --- a/gcc/testsuite/gcc.dg/march-generic.c

> +++ b/gcc/testsuite/gcc.dg/march-generic.c

> @@ -1,6 +1,6 @@

>  /* { dg-do compile { target i?86-*-* x86_64-*-* } } */

>  /* { dg-skip-if "" { *-*-* } { "-march=*" } { "" } } */

> -/* { dg-options "-march=generic" } */

> +/* { dg-options "-march=generic -fcf-protection=none" } */

>  /* { dg-error "'generic' CPU can be used only for '-mtune=' switch" "" { target *-*-* } 0 } */

>  /* { dg-bogus "march" "" { target *-*-* } 0 } */

>  int i;

> diff --git a/gcc/testsuite/gcc.target/i386/align-limit.c b/gcc/testsuite/gcc.target/i386/align-limit.c

> index d3d8dc5656e..849d741189c 100644

> --- a/gcc/testsuite/gcc.target/i386/align-limit.c

> +++ b/gcc/testsuite/gcc.target/i386/align-limit.c

> @@ -1,5 +1,5 @@

>  /* { dg-do compile } */

> -/* { dg-options "-O2 -falign-functions=64 -flimit-function-alignment -march=amdfam10" } */

> +/* { dg-options "-O2 -falign-functions=64 -flimit-function-alignment -march=amdfam10 -fcf-protection=none" } */

>  /* { dg-final { scan-assembler ".p2align 6,,1" } } */

>  /* { dg-final { scan-assembler-not ".p2align 6,,63" } } */

>

> diff --git a/gcc/testsuite/gcc.target/i386/cet-label-3.c b/gcc/testsuite/gcc.target/i386/cet-label-3.c

> new file mode 100644

> index 00000000000..5e0892e5b4d

> --- /dev/null

> +++ b/gcc/testsuite/gcc.target/i386/cet-label-3.c

> @@ -0,0 +1,16 @@

> +/* Verify that -fcf-protection works without -mcet.  */

> +/* { dg-do compile } */

> +/* { dg-options "-O -fcf-protection" } */

> +/* { dg-final { scan-assembler-times "endbr32" 3 { target ia32 } } } */

> +/* { dg-final { scan-assembler-times "endbr64" 3 { target { ! ia32 } } } } */

> +

> +int func (int arg)

> +{

> +  static void *array[] = { &&foo, &&bar };

> +

> +  goto *array[arg];

> +foo:

> +  return arg*111;

> +bar:

> +  return arg*777;

> +}

> diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c

> index 7987d53d305..0bddf54862a 100644

> --- a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c

> +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c

> @@ -1,6 +1,6 @@

>  /* Verify nocf_check functions are not ICF optimized.  */

>  /* { dg-do compile } */

> -/* { dg-options "-O2" } */

> +/* { dg-options "-O2 -fcf-protection=none" } */

>  /* { dg-final { scan-assembler-not "endbr" } } */

>  /* { dg-final { scan-assembler-not "fn3:" } } */

>  /* { dg-final { scan-assembler "set\[ \t]+fn2,fn1" } } */

> diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c

> index 07c4a6b61ef..ed2d53ac5ef 100644

> --- a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c

> +++ b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c

> @@ -1,6 +1,6 @@

>  /* Verify nocf_check function calls are not ICF optimized.  */

>  /* { dg-do compile } */

> -/* { dg-options "-O2" } */

> +/* { dg-options "-O2 -fcf-protection=none" } */

>  /* { dg-final { scan-assembler-not "endbr" } } */

>  /* { dg-final { scan-assembler-not "fn2:" } } */

>  /* { dg-final { scan-assembler "set\[ \t]+fn2,fn1" } } */

> diff --git a/gcc/testsuite/gcc.target/i386/cet-property-2.c b/gcc/testsuite/gcc.target/i386/cet-property-2.c

> index 5a87dab92f1..bca6f6cdeb7 100644

> --- a/gcc/testsuite/gcc.target/i386/cet-property-2.c

> +++ b/gcc/testsuite/gcc.target/i386/cet-property-2.c

> @@ -1,5 +1,5 @@

>  /* { dg-do compile } */

> -/* { dg-options "-mcet" } */

> +/* { dg-options "-mcet -fcf-protection=none" } */

>  /* { dg-final { scan-assembler-not ".note.gnu.property" } } */

>

>  extern void foo (void);

> diff --git a/gcc/testsuite/gcc.target/i386/cet-property-3.c b/gcc/testsuite/gcc.target/i386/cet-property-3.c

> new file mode 100644

> index 00000000000..3e211c970aa

> --- /dev/null

> +++ b/gcc/testsuite/gcc.target/i386/cet-property-3.c

> @@ -0,0 +1,11 @@

> +/* { dg-do compile { target *-*-linux* } } */

> +/* { dg-options "-fcf-protection" } */

> +/* { dg-final { scan-assembler ".note.gnu.property" } } */

> +

> +extern void foo (void);

> +

> +void

> +bar (void)

> +{

> +  foo ();

> +}

> diff --git a/gcc/testsuite/gcc.target/i386/cet-sjlj-7.c b/gcc/testsuite/gcc.target/i386/cet-sjlj-7.c

> new file mode 100644

> index 00000000000..1b624327d0f

> --- /dev/null

> +++ b/gcc/testsuite/gcc.target/i386/cet-sjlj-7.c

> @@ -0,0 +1,48 @@

> +/* { dg-do compile } */

> +/* { dg-options "-O -fcf-protection" } */

> +/* { dg-final { scan-assembler-times "endbr32" 2 { target ia32 } } } */

> +/* { dg-final { scan-assembler-times "endbr64" 2 { target { ! ia32 } } } } */

> +/* { dg-final { scan-assembler-times "call     _?setjmp" 1 } } */

> +/* { dg-final { scan-assembler-times "call     longjmp" 1 } } */

> +

> +#include <stdio.h>

> +#include <setjmp.h>

> +

> +jmp_buf buf;

> +static int bar (int);

> +

> +__attribute__ ((noinline, noclone))

> +static int

> +foo (int i)

> +{

> +  int j = i * 11;

> +

> +  if (!setjmp (buf))

> +    {

> +      j += 33;

> +      printf ("After setjmp: j = %d\n", j);

> +      bar (j);

> +    }

> +

> +  return j + i;

> +}

> +

> +__attribute__ ((noinline, noclone))

> +static int

> +bar (int i)

> +{

> + int j = i;

> +

> +  j -= 111;

> +  printf ("In longjmp: j = %d\n", j);

> +  longjmp (buf, 1);

> +

> +  return j;

> +}

> +

> +int

> +main ()

> +{

> +  foo (10);

> +  return 0;

> +}

> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c

> index d53fc887dcc..ffe7350fce4 100644

> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c

> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c

> @@ -37,7 +37,7 @@ bar (int i)

>  }

>

>  /* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */

> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */

> +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk(_nt|)_(r|e)ax" } } */

>  /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */

>  /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */

>  /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */

> diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c

> index 2b9a33e93dc..b7339745116 100644

> --- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c

> +++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c

> @@ -36,7 +36,7 @@ bar (int i)

>  }

>

>  /* { dg-final { scan-assembler "mov(?:l|q)\[ \t\]*\.L\[0-9\]+\\(,%" { target *-*-linux* } } } */

> -/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk_(r|e)ax" } } */

> +/* { dg-final { scan-assembler "jmp\[ \t\]*__x86_indirect_thunk(_nt|)_(r|e)ax" } } */

>  /* { dg-final { scan-assembler-not {\t(lfence|pause)} } } */

>  /* { dg-final { scan-assembler-not "jmp\[ \t\]*\.LIND" } } */

>  /* { dg-final { scan-assembler-not "call\[ \t\]*\.LIND" } } */

> diff --git a/gcc/testsuite/gcc.target/i386/pr85403.c b/gcc/testsuite/gcc.target/i386/pr85403.c

> index f4fb12dd4e2..0bbd7ca5610 100644

> --- a/gcc/testsuite/gcc.target/i386/pr85403.c

> +++ b/gcc/testsuite/gcc.target/i386/pr85403.c

> @@ -7,4 +7,4 @@ int

>  foo ()

>  {

>    return -2;

> -} /* { dg-error "requires Intel CET support" } */

> +}

> diff --git a/gcc/testsuite/gcc.target/i386/pr85417-1.c b/gcc/testsuite/gcc.target/i386/pr85417-1.c

> new file mode 100644

> index 00000000000..17d52403744

> --- /dev/null

> +++ b/gcc/testsuite/gcc.target/i386/pr85417-1.c

> @@ -0,0 +1,17 @@

> +/* { dg-do compile } */

> +/* { dg-require-ifunc "" } */

> +/* { dg-options "-O3 -fcf-protection" } */

> +/* { dg-final { scan-assembler "vpshufb" } } */

> +/* { dg-final { scan-assembler "punpcklbw" } } */

> +

> +__attribute__((target_clones("arch=core-avx2","arch=slm","default")))

> +void

> +foo(char *in, char *out, int size)

> +{

> +  int i;

> +  for(i = 0; i < size; i++)

> +    {

> +       out[2 * i] = in[i];

> +       out[2 * i + 1] = in[i];

> +    }

> +}

> diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-26.c b/gcc/testsuite/gcc.target/i386/ret-thunk-26.c

> index 9144e988735..dc722c2f5f9 100644

> --- a/gcc/testsuite/gcc.target/i386/ret-thunk-26.c

> +++ b/gcc/testsuite/gcc.target/i386/ret-thunk-26.c

> @@ -1,6 +1,6 @@

>  /* PR target/r84530 */

>  /* { dg-do run } */

> -/* { dg-options "-Os -mfunction-return=thunk" } */

> +/* { dg-options "-Os -mfunction-return=thunk -fcf-protection=none" } */

>

>  struct S { int i; };

>  __attribute__((const, noinline, noclone))

> --

> 2.14.3

>
Tsimbalist, Igor V April 19, 2018, 2:07 p.m. | #21
> -----Original Message-----

> From: Uros Bizjak [mailto:ubizjak@gmail.com]

> Sent: Thursday, April 19, 2018 3:36 PM

> To: H.J. Lu <hjl.tools@gmail.com>

> Cc: Richard Biener <richard.guenther@gmail.com>; gcc-

> patches@gcc.gnu.org; Tsimbalist, Igor V <igor.v.tsimbalist@intel.com>

> Subject: Re: [PATCH] x86: Allow -fcf-protection with multi-byte NOPs

> 

> On Thu, Apr 19, 2018 at 3:30 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

> > On Wed, Apr 18, 2018 at 01:35:33PM +0200, Richard Biener wrote:

> >> On Wed, Apr 18, 2018 at 1:24 PM, H.J. Lu <hjl.tools@gmail.com> wrote:

> >> > On Tue, Apr 17, 2018 at 12:25 PM, H.J. Lu <hjl.tools@gmail.com>

> wrote:

> >> >> On Tue, Apr 17, 2018 at 12:25 PM, H.J. Lu <hjl.tools@gmail.com>

> wrote:

> >> >>> On Tue, Apr 17, 2018 at 12:03 PM, H.J. Lu <hjl.tools@gmail.com>

> wrote:

> >> >>>> On Tue, Apr 17, 2018 at 11:55 AM, Uros Bizjak

> <ubizjak@gmail.com> wrote:

> >> >>>>> On Tue, Apr 17, 2018 at 8:42 PM, H.J. Lu

> <hongjiu.lu@intel.com> wrote:

> >> >>>>>> -fcf-protection -mcet can't be used with IFUNC features, like

> symbol

> >> >>>>>> multiversioning or target clone, since IBT/SHSTK are applied to

> the whole

> >> >>>>>> program and they may be disabled in some functions.  But -

> fcf-protection

> >> >>>>>> is implemented with multi-byte NOPs on all 64-bit processors

> as well as

> >> >>>>>> 32-bit processors starting with Pentium Pro.  If -fcf-protection

> requires

> >> >>>>>> -mcet, IFUNC features can't be used on Linux when -fcf-

> protection is

> >> >>>>>> enabled by default.

> >> >>>>>>

> >> >>>>>> This patch changes -fcf-protection to to enable the NOP

> portion of CET

> >> >>>>>> ISAs unless IBT and/or SHSTK are disabled explicitly.  The rest of

> CET

> >> >>>>>> ISAs, including intrinsics, still requires -mcet, -mibt or -mshstk.

> >> >>>>>>

> >> >>>>>> OK for trunk?

> >> >>>>>

> >> >>>>> As said in the PR, NOP sequences have non-zero cost in the

> executable

> >> >>>>> (they enlarge the executable), so I don't think this feature should

> be

> >> >>>>> enabled by default.

> >> >>>>>

> >> >>>>> There is always a configure option if someone wants their

> compiler to

> >> >>>>> always emit relevant multi-byte nops.

> >> >>>>

> >> >>>> What we need is an option to enable -fcf-function with multi-byte

> NOPs

> >> >>>> without -mcet which enables the full CET ISAs.  A configure option

> >> >>>> without the corresponding the command-line option makes test

> and

> >> >>>> debug difficult.   I can add

> >> >>>>

> >> >>>> --enable-cf-function-nop or --with-cf-function-nop

> >> >>>>

> >> >>>> with

> >> >>>>

> >> >>>> -fct-function-nop

> >> >>>>

> >> >>>

> >> >>> How about adding -mno-cet, which enables the NOP portion of

> CET

> >> >>

> >> >> I meant -mnop-cet, not -mno-cet.

> >> >>

> >> >

> >> > Here is a patch to add -mnop and use it with -fcf-protection.

> >>

> >> +mnop

> >> +Target Report Var(flag_nop) Init(0)

> >> +Support multi-byte NOP code generation.

> >>

> >> the option name is incredibly bad and the documentation doesn't make it

> >> better either.  The invoke.texi docs refer to duplicate {-mcet}.

> >>

> >> Isn't there a -fcf-protection sub-set that can be used to automatically

> >> enable this?  Or simply do this mode by default when

> >> -fcf-protection is used but neither -mcet nor -mibt is enabled?

> >>

> >

> > Since multi-byte NOPs are used to implement -fcf-protection on x86, we

> > propose a new design for -fcf-protection:

> >

> > 1. -fcf-protection option will report the unsupported error on non-x86

> > platform. On x86 platform it's supported and inserts endbr-nop

> > instructions and properties, depending on its value (full/branch/return)

> > 2. -mcet/-mibt/-mshstk options control intrinsics only.

> > 3. These options are independent and do not influence each other so no

> > need for cross checking between them.

> >

> > OK for trunk?

> 

> This patch touches only CET related code, so Igor's OK should be enough.


I have reviewed the patch and I'm ok with it.

Igor

> Uros.
Jakub Jelinek April 19, 2018, 7:25 p.m. | #22
On Thu, Apr 19, 2018 at 06:30:37AM -0700, H.J. Lu wrote:
> 	* config/i386/i386-c.c (ix86_target_macros_internal): Also

> 	define __IBT__ and __SHSTK__ for -fcf-protection.


> --- a/gcc/config/i386/i386-c.c

> +++ b/gcc/config/i386/i386-c.c

> @@ -499,13 +499,15 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,

>      def_or_undef (parse_in, "__RDPID__");

>    if (isa_flag & OPTION_MASK_ISA_GFNI)

>      def_or_undef (parse_in, "__GFNI__");

> -  if (isa_flag2 & OPTION_MASK_ISA_IBT)

> +  if ((isa_flag2 & OPTION_MASK_ISA_IBT)

> +      || (flag_cf_protection & CF_BRANCH))

>      {

>        def_or_undef (parse_in, "__IBT__");

>        if (flag_cf_protection != CF_NONE)

>  	def_or_undef (parse_in, "__CET__");

>      }

> -  if (isa_flag & OPTION_MASK_ISA_SHSTK)

> +  if ((isa_flag & OPTION_MASK_ISA_SHSTK)

> +      || (flag_cf_protection & CF_RETURN))

>      {

>        def_or_undef (parse_in, "__SHSTK__");

>        if (flag_cf_protection != CF_NONE)

>	def_or_undef (parse_in, "__CET__");

>      }


This looks completely wrong to me.
1) there is no way to find out through preprocessor macros if
-mibt or -mshstk was actually used or not, so e.g. if you
#include <cetintrin.h>
and compile with -fcf-protection -mno-cet, then
#ifndef __SHSTK__
#pragma GCC push_options
#pragma GCC target ("shstk")
#define __DISABLE_SHSTK__
#endif /* __SHSTK__ */
will not be done and thus the intrinsics will appear to be in
in the default target (-mno-cet)
2) preexisting - __CET__ is predefined twice, it should be done only
once using a condition that covers all cases when the macro should be
defined

Don't you want to just predefine __CET__ and not __IBT__/__SHSTK__
if -fcf-protection -mno-cet, to make it clear?

	Jakub
H.J. Lu April 19, 2018, 8:02 p.m. | #23
On Thu, Apr 19, 2018 at 12:25 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Thu, Apr 19, 2018 at 06:30:37AM -0700, H.J. Lu wrote:

>>       * config/i386/i386-c.c (ix86_target_macros_internal): Also

>>       define __IBT__ and __SHSTK__ for -fcf-protection.

>

>> --- a/gcc/config/i386/i386-c.c

>> +++ b/gcc/config/i386/i386-c.c

>> @@ -499,13 +499,15 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,

>>      def_or_undef (parse_in, "__RDPID__");

>>    if (isa_flag & OPTION_MASK_ISA_GFNI)

>>      def_or_undef (parse_in, "__GFNI__");

>> -  if (isa_flag2 & OPTION_MASK_ISA_IBT)

>> +  if ((isa_flag2 & OPTION_MASK_ISA_IBT)

>> +      || (flag_cf_protection & CF_BRANCH))

>>      {

>>        def_or_undef (parse_in, "__IBT__");

>>        if (flag_cf_protection != CF_NONE)

>>       def_or_undef (parse_in, "__CET__");

>>      }

>> -  if (isa_flag & OPTION_MASK_ISA_SHSTK)

>> +  if ((isa_flag & OPTION_MASK_ISA_SHSTK)

>> +      || (flag_cf_protection & CF_RETURN))

>>      {

>>        def_or_undef (parse_in, "__SHSTK__");

>>        if (flag_cf_protection != CF_NONE)

>>       def_or_undef (parse_in, "__CET__");

>>      }

>

> This looks completely wrong to me.

> 1) there is no way to find out through preprocessor macros if

> -mibt or -mshstk was actually used or not, so e.g. if you

> #include <cetintrin.h>

> and compile with -fcf-protection -mno-cet, then

> #ifndef __SHSTK__

> #pragma GCC push_options

> #pragma GCC target ("shstk")

> #define __DISABLE_SHSTK__

> #endif /* __SHSTK__ */

> will not be done and thus the intrinsics will appear to be in

> in the default target (-mno-cet)

> 2) preexisting - __CET__ is predefined twice, it should be done only

> once using a condition that covers all cases when the macro should be

> defined

>

> Don't you want to just predefine __CET__ and not __IBT__/__SHSTK__

> if -fcf-protection -mno-cet, to make it clear?

>


We are removing -mibt:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85469

How about this?


diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c
index fa8b3682b0c..26c7641075d 100644
--- a/gcc/config/i386/i386-c.c
+++ b/gcc/config/i386/i386-c.c
@@ -499,20 +499,14 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
     def_or_undef (parse_in, "__RDPID__");
   if (isa_flag & OPTION_MASK_ISA_GFNI)
     def_or_undef (parse_in, "__GFNI__");
-  if ((isa_flag2 & OPTION_MASK_ISA_IBT)
-      || (flag_cf_protection & CF_BRANCH))
-    {
-      def_or_undef (parse_in, "__IBT__");
-      if (flag_cf_protection != CF_NONE)
-  def_or_undef (parse_in, "__CET__");
-    }
-  if ((isa_flag & OPTION_MASK_ISA_SHSTK)
-      || (flag_cf_protection & CF_RETURN))
-    {
-      def_or_undef (parse_in, "__SHSTK__");
-      if (flag_cf_protection != CF_NONE)
-  def_or_undef (parse_in, "__CET__");
-    }
+  if ((isa_flag & OPTION_MASK_ISA_SHSTK))
+    def_or_undef (parse_in, "__SHSTK__");
+  if (flag_cf_protection != CF_NONE)
+    def_or_undef (parse_in, "__CET__");
+  if ((flag_cf_protection & CF_BRANCH))
+    def_or_undef (parse_in, "__CET_IBT__");
+  if ((flag_cf_protection & CF_RETURN))
+    def_or_undef (parse_in, "__CET_SHSTK__");
   if (isa_flag2 & OPTION_MASK_ISA_VAES)
     def_or_undef (parse_in, "__VAES__");
   if (isa_flag & OPTION_MASK_ISA_VPCLMULQDQ)

This adds __CET_IBT__ and __CET_SHSTK__.


-- 
H.J.
Tsimbalist, Igor V April 19, 2018, 9:18 p.m. | #24
> -----Original Message-----

> From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-

> owner@gcc.gnu.org] On Behalf Of H.J. Lu

> Sent: Thursday, April 19, 2018 10:02 PM

> To: Jakub Jelinek <jakub@redhat.com>

> Cc: Richard Biener <richard.guenther@gmail.com>; Uros Bizjak

> <ubizjak@gmail.com>; gcc-patches@gcc.gnu.org; Tsimbalist, Igor V

> <igor.v.tsimbalist@intel.com>

> Subject: Re: [PATCH] x86: Allow -fcf-protection with multi-byte NOPs

> 

> On Thu, Apr 19, 2018 at 12:25 PM, Jakub Jelinek <jakub@redhat.com>

> wrote:

> > On Thu, Apr 19, 2018 at 06:30:37AM -0700, H.J. Lu wrote:

> >>       * config/i386/i386-c.c (ix86_target_macros_internal): Also

> >>       define __IBT__ and __SHSTK__ for -fcf-protection.

> >

> >> --- a/gcc/config/i386/i386-c.c

> >> +++ b/gcc/config/i386/i386-c.c

> >> @@ -499,13 +499,15 @@ ix86_target_macros_internal (HOST_WIDE_INT

> isa_flag,

> >>      def_or_undef (parse_in, "__RDPID__");

> >>    if (isa_flag & OPTION_MASK_ISA_GFNI)

> >>      def_or_undef (parse_in, "__GFNI__");

> >> -  if (isa_flag2 & OPTION_MASK_ISA_IBT)

> >> +  if ((isa_flag2 & OPTION_MASK_ISA_IBT)

> >> +      || (flag_cf_protection & CF_BRANCH))

> >>      {

> >>        def_or_undef (parse_in, "__IBT__");

> >>        if (flag_cf_protection != CF_NONE)

> >>       def_or_undef (parse_in, "__CET__");

> >>      }

> >> -  if (isa_flag & OPTION_MASK_ISA_SHSTK)

> >> +  if ((isa_flag & OPTION_MASK_ISA_SHSTK)

> >> +      || (flag_cf_protection & CF_RETURN))

> >>      {

> >>        def_or_undef (parse_in, "__SHSTK__");

> >>        if (flag_cf_protection != CF_NONE)

> >>       def_or_undef (parse_in, "__CET__");

> >>      }

> >

> > This looks completely wrong to me.

> > 1) there is no way to find out through preprocessor macros if

> > -mibt or -mshstk was actually used or not, so e.g. if you

> > #include <cetintrin.h>

> > and compile with -fcf-protection -mno-cet, then

> > #ifndef __SHSTK__

> > #pragma GCC push_options

> > #pragma GCC target ("shstk")

> > #define __DISABLE_SHSTK__

> > #endif /* __SHSTK__ */

> > will not be done and thus the intrinsics will appear to be in

> > in the default target (-mno-cet)

> > 2) preexisting - __CET__ is predefined twice, it should be done only

> > once using a condition that covers all cases when the macro should be

> > defined

> >

> > Don't you want to just predefine __CET__ and not __IBT__/__SHSTK__

> > if -fcf-protection -mno-cet, to make it clear?

> >

> 

> We are removing -mibt:

> 

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85469

> 

> How about this?

> 

> 

> diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c

> index fa8b3682b0c..26c7641075d 100644

> --- a/gcc/config/i386/i386-c.c

> +++ b/gcc/config/i386/i386-c.c

> @@ -499,20 +499,14 @@ ix86_target_macros_internal (HOST_WIDE_INT

> isa_flag,

>      def_or_undef (parse_in, "__RDPID__");

>    if (isa_flag & OPTION_MASK_ISA_GFNI)

>      def_or_undef (parse_in, "__GFNI__");

> -  if ((isa_flag2 & OPTION_MASK_ISA_IBT)

> -      || (flag_cf_protection & CF_BRANCH))

> -    {

> -      def_or_undef (parse_in, "__IBT__");

> -      if (flag_cf_protection != CF_NONE)

> -  def_or_undef (parse_in, "__CET__");

> -    }

> -  if ((isa_flag & OPTION_MASK_ISA_SHSTK)

> -      || (flag_cf_protection & CF_RETURN))

> -    {

> -      def_or_undef (parse_in, "__SHSTK__");

> -      if (flag_cf_protection != CF_NONE)

> -  def_or_undef (parse_in, "__CET__");

> -    }

> +  if ((isa_flag & OPTION_MASK_ISA_SHSTK))

> +    def_or_undef (parse_in, "__SHSTK__");

> +  if (flag_cf_protection != CF_NONE)

> +    def_or_undef (parse_in, "__CET__");

> +  if ((flag_cf_protection & CF_BRANCH))

> +    def_or_undef (parse_in, "__CET_IBT__");

> +  if ((flag_cf_protection & CF_RETURN))

> +    def_or_undef (parse_in, "__CET_SHSTK__");

>    if (isa_flag2 & OPTION_MASK_ISA_VAES)

>      def_or_undef (parse_in, "__VAES__");

>    if (isa_flag & OPTION_MASK_ISA_VPCLMULQDQ)

> 

> This adds __CET_IBT__ and __CET_SHSTK__.


As -fcf-protection and -mcet/-mibt/-mshstk are are disjoint and
control different parts I agree with

+  if ((isa_flag & OPTION_MASK_ISA_SHSTK))
+    def_or_undef (parse_in, "__SHSTK__");
+  if (flag_cf_protection != CF_NONE)
+    def_or_undef (parse_in, "__CET__");

Why __CET_IBT__ and __CET_SHSTK__ are needed? Moreover the naming is
confusing as 'IBT' and 'SHSTK' are related to HW features which are controlled
by -m options. __CET__ seems to be enough.

Igor

> 

> --

> H.J.
H.J. Lu April 19, 2018, 10:08 p.m. | #25
On Thu, Apr 19, 2018 at 2:18 PM, Tsimbalist, Igor V
<igor.v.tsimbalist@intel.com> wrote:
>> -----Original Message-----

>> From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-

>> owner@gcc.gnu.org] On Behalf Of H.J. Lu

>> Sent: Thursday, April 19, 2018 10:02 PM

>> To: Jakub Jelinek <jakub@redhat.com>

>> Cc: Richard Biener <richard.guenther@gmail.com>; Uros Bizjak

>> <ubizjak@gmail.com>; gcc-patches@gcc.gnu.org; Tsimbalist, Igor V

>> <igor.v.tsimbalist@intel.com>

>> Subject: Re: [PATCH] x86: Allow -fcf-protection with multi-byte NOPs

>>

>> On Thu, Apr 19, 2018 at 12:25 PM, Jakub Jelinek <jakub@redhat.com>

>> wrote:

>> > On Thu, Apr 19, 2018 at 06:30:37AM -0700, H.J. Lu wrote:

>> >>       * config/i386/i386-c.c (ix86_target_macros_internal): Also

>> >>       define __IBT__ and __SHSTK__ for -fcf-protection.

>> >

>> >> --- a/gcc/config/i386/i386-c.c

>> >> +++ b/gcc/config/i386/i386-c.c

>> >> @@ -499,13 +499,15 @@ ix86_target_macros_internal (HOST_WIDE_INT

>> isa_flag,

>> >>      def_or_undef (parse_in, "__RDPID__");

>> >>    if (isa_flag & OPTION_MASK_ISA_GFNI)

>> >>      def_or_undef (parse_in, "__GFNI__");

>> >> -  if (isa_flag2 & OPTION_MASK_ISA_IBT)

>> >> +  if ((isa_flag2 & OPTION_MASK_ISA_IBT)

>> >> +      || (flag_cf_protection & CF_BRANCH))

>> >>      {

>> >>        def_or_undef (parse_in, "__IBT__");

>> >>        if (flag_cf_protection != CF_NONE)

>> >>       def_or_undef (parse_in, "__CET__");

>> >>      }

>> >> -  if (isa_flag & OPTION_MASK_ISA_SHSTK)

>> >> +  if ((isa_flag & OPTION_MASK_ISA_SHSTK)

>> >> +      || (flag_cf_protection & CF_RETURN))

>> >>      {

>> >>        def_or_undef (parse_in, "__SHSTK__");

>> >>        if (flag_cf_protection != CF_NONE)

>> >>       def_or_undef (parse_in, "__CET__");

>> >>      }

>> >

>> > This looks completely wrong to me.

>> > 1) there is no way to find out through preprocessor macros if

>> > -mibt or -mshstk was actually used or not, so e.g. if you

>> > #include <cetintrin.h>

>> > and compile with -fcf-protection -mno-cet, then

>> > #ifndef __SHSTK__

>> > #pragma GCC push_options

>> > #pragma GCC target ("shstk")

>> > #define __DISABLE_SHSTK__

>> > #endif /* __SHSTK__ */

>> > will not be done and thus the intrinsics will appear to be in

>> > in the default target (-mno-cet)

>> > 2) preexisting - __CET__ is predefined twice, it should be done only

>> > once using a condition that covers all cases when the macro should be

>> > defined

>> >

>> > Don't you want to just predefine __CET__ and not __IBT__/__SHSTK__

>> > if -fcf-protection -mno-cet, to make it clear?

>> >

>>

>> We are removing -mibt:

>>

>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85469

>>

>> How about this?

>>

>>

>> diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c

>> index fa8b3682b0c..26c7641075d 100644

>> --- a/gcc/config/i386/i386-c.c

>> +++ b/gcc/config/i386/i386-c.c

>> @@ -499,20 +499,14 @@ ix86_target_macros_internal (HOST_WIDE_INT

>> isa_flag,

>>      def_or_undef (parse_in, "__RDPID__");

>>    if (isa_flag & OPTION_MASK_ISA_GFNI)

>>      def_or_undef (parse_in, "__GFNI__");

>> -  if ((isa_flag2 & OPTION_MASK_ISA_IBT)

>> -      || (flag_cf_protection & CF_BRANCH))

>> -    {

>> -      def_or_undef (parse_in, "__IBT__");

>> -      if (flag_cf_protection != CF_NONE)

>> -  def_or_undef (parse_in, "__CET__");

>> -    }

>> -  if ((isa_flag & OPTION_MASK_ISA_SHSTK)

>> -      || (flag_cf_protection & CF_RETURN))

>> -    {

>> -      def_or_undef (parse_in, "__SHSTK__");

>> -      if (flag_cf_protection != CF_NONE)

>> -  def_or_undef (parse_in, "__CET__");

>> -    }

>> +  if ((isa_flag & OPTION_MASK_ISA_SHSTK))

>> +    def_or_undef (parse_in, "__SHSTK__");

>> +  if (flag_cf_protection != CF_NONE)

>> +    def_or_undef (parse_in, "__CET__");

>> +  if ((flag_cf_protection & CF_BRANCH))

>> +    def_or_undef (parse_in, "__CET_IBT__");

>> +  if ((flag_cf_protection & CF_RETURN))

>> +    def_or_undef (parse_in, "__CET_SHSTK__");

>>    if (isa_flag2 & OPTION_MASK_ISA_VAES)

>>      def_or_undef (parse_in, "__VAES__");

>>    if (isa_flag & OPTION_MASK_ISA_VPCLMULQDQ)

>>

>> This adds __CET_IBT__ and __CET_SHSTK__.

>

> As -fcf-protection and -mcet/-mibt/-mshstk are are disjoint and

> control different parts I agree with

>

> +  if ((isa_flag & OPTION_MASK_ISA_SHSTK))

> +    def_or_undef (parse_in, "__SHSTK__");

> +  if (flag_cf_protection != CF_NONE)

> +    def_or_undef (parse_in, "__CET__");

>

> Why __CET_IBT__ and __CET_SHSTK__ are needed? Moreover the naming is

> confusing as 'IBT' and 'SHSTK' are related to HW features which are controlled

> by -m options. __CET__ seems to be enough.

>


One needs to know if IBT and SHSTK are enabled by -fcf-protection.  They will
be checked by <cet.h> and glibc.

-- 
H.J.
Jakub Jelinek April 19, 2018, 10:37 p.m. | #26
On Thu, Apr 19, 2018 at 03:08:06PM -0700, H.J. Lu wrote:
> > As -fcf-protection and -mcet/-mibt/-mshstk are are disjoint and

> > control different parts I agree with

> >

> > +  if ((isa_flag & OPTION_MASK_ISA_SHSTK))

> > +    def_or_undef (parse_in, "__SHSTK__");

> > +  if (flag_cf_protection != CF_NONE)

> > +    def_or_undef (parse_in, "__CET__");

> >

> > Why __CET_IBT__ and __CET_SHSTK__ are needed? Moreover the naming is

> > confusing as 'IBT' and 'SHSTK' are related to HW features which are controlled

> > by -m options. __CET__ seems to be enough.

> >

> 

> One needs to know if IBT and SHSTK are enabled by -fcf-protection.  They will

> be checked by <cet.h> and glibc.


So can't you define __CET__ to 3 if CF_FULL, to 1 if CF_BRANCH and 2 if
CF_RETURN?  Then if code doesn't care which one it is, it can just #ifdef
__CET__, otherwise it can test which of those is enabled.
Implementation-wise it would probably need to be:
  if (flag_cf_protection != CF_NONE)
    {
      if (def_or_undef == cpp_undef)
	def_or_undef (parse_in, "__CET__");
      else if ((flag_cf_protection & CF_FULL) == CF_FULL)
	def_or_undef (parse_in, "__CET__=3");
      else if (flag_cf_protection & CF_BRANCH)
	def_or_undef (parse_in, "__CET__=1");
      else if (flag_cf_protection & CF_RETURN)
	def_or_undef (parse_in, "__CET__=2");
    }
or so.  Actually, because it doesn't depend on something that can change
depending on target attributes, it probably doesn't even belong in this
function, but to ix86_target_macros and there you can just cpp_define
it, don't deal with cpp_undef at all.

	Jakub
Tsimbalist, Igor V April 19, 2018, 10:47 p.m. | #27
> -----Original Message-----

> From: H.J. Lu [mailto:hjl.tools@gmail.com]

> Sent: Friday, April 20, 2018 12:08 AM

> To: Tsimbalist, Igor V <igor.v.tsimbalist@intel.com>

> Cc: Jakub Jelinek <jakub@redhat.com>; Richard Biener

> <richard.guenther@gmail.com>; Uros Bizjak <ubizjak@gmail.com>; gcc-

> patches@gcc.gnu.org

> Subject: Re: [PATCH] x86: Allow -fcf-protection with multi-byte NOPs

> 

> On Thu, Apr 19, 2018 at 2:18 PM, Tsimbalist, Igor V

> <igor.v.tsimbalist@intel.com> wrote:

> >> -----Original Message-----

> >> From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-

> >> owner@gcc.gnu.org] On Behalf Of H.J. Lu

> >> Sent: Thursday, April 19, 2018 10:02 PM

> >> To: Jakub Jelinek <jakub@redhat.com>

> >> Cc: Richard Biener <richard.guenther@gmail.com>; Uros Bizjak

> >> <ubizjak@gmail.com>; gcc-patches@gcc.gnu.org; Tsimbalist, Igor V

> >> <igor.v.tsimbalist@intel.com>

> >> Subject: Re: [PATCH] x86: Allow -fcf-protection with multi-byte NOPs

> >>

> >> On Thu, Apr 19, 2018 at 12:25 PM, Jakub Jelinek <jakub@redhat.com>

> >> wrote:

> >> > On Thu, Apr 19, 2018 at 06:30:37AM -0700, H.J. Lu wrote:

> >> >>       * config/i386/i386-c.c (ix86_target_macros_internal): Also

> >> >>       define __IBT__ and __SHSTK__ for -fcf-protection.

> >> >

> >> >> --- a/gcc/config/i386/i386-c.c

> >> >> +++ b/gcc/config/i386/i386-c.c

> >> >> @@ -499,13 +499,15 @@ ix86_target_macros_internal

> (HOST_WIDE_INT

> >> isa_flag,

> >> >>      def_or_undef (parse_in, "__RDPID__");

> >> >>    if (isa_flag & OPTION_MASK_ISA_GFNI)

> >> >>      def_or_undef (parse_in, "__GFNI__");

> >> >> -  if (isa_flag2 & OPTION_MASK_ISA_IBT)

> >> >> +  if ((isa_flag2 & OPTION_MASK_ISA_IBT)

> >> >> +      || (flag_cf_protection & CF_BRANCH))

> >> >>      {

> >> >>        def_or_undef (parse_in, "__IBT__");

> >> >>        if (flag_cf_protection != CF_NONE)

> >> >>       def_or_undef (parse_in, "__CET__");

> >> >>      }

> >> >> -  if (isa_flag & OPTION_MASK_ISA_SHSTK)

> >> >> +  if ((isa_flag & OPTION_MASK_ISA_SHSTK)

> >> >> +      || (flag_cf_protection & CF_RETURN))

> >> >>      {

> >> >>        def_or_undef (parse_in, "__SHSTK__");

> >> >>        if (flag_cf_protection != CF_NONE)

> >> >>       def_or_undef (parse_in, "__CET__");

> >> >>      }

> >> >

> >> > This looks completely wrong to me.

> >> > 1) there is no way to find out through preprocessor macros if

> >> > -mibt or -mshstk was actually used or not, so e.g. if you

> >> > #include <cetintrin.h>

> >> > and compile with -fcf-protection -mno-cet, then

> >> > #ifndef __SHSTK__

> >> > #pragma GCC push_options

> >> > #pragma GCC target ("shstk")

> >> > #define __DISABLE_SHSTK__

> >> > #endif /* __SHSTK__ */

> >> > will not be done and thus the intrinsics will appear to be in

> >> > in the default target (-mno-cet)

> >> > 2) preexisting - __CET__ is predefined twice, it should be done only

> >> > once using a condition that covers all cases when the macro should be

> >> > defined

> >> >

> >> > Don't you want to just predefine __CET__ and not __IBT__/__SHSTK__

> >> > if -fcf-protection -mno-cet, to make it clear?

> >> >

> >>

> >> We are removing -mibt:

> >>

> >> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85469

> >>

> >> How about this?

> >>

> >>

> >> diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c

> >> index fa8b3682b0c..26c7641075d 100644

> >> --- a/gcc/config/i386/i386-c.c

> >> +++ b/gcc/config/i386/i386-c.c

> >> @@ -499,20 +499,14 @@ ix86_target_macros_internal (HOST_WIDE_INT

> >> isa_flag,

> >>      def_or_undef (parse_in, "__RDPID__");

> >>    if (isa_flag & OPTION_MASK_ISA_GFNI)

> >>      def_or_undef (parse_in, "__GFNI__");

> >> -  if ((isa_flag2 & OPTION_MASK_ISA_IBT)

> >> -      || (flag_cf_protection & CF_BRANCH))

> >> -    {

> >> -      def_or_undef (parse_in, "__IBT__");

> >> -      if (flag_cf_protection != CF_NONE)

> >> -  def_or_undef (parse_in, "__CET__");

> >> -    }

> >> -  if ((isa_flag & OPTION_MASK_ISA_SHSTK)

> >> -      || (flag_cf_protection & CF_RETURN))

> >> -    {

> >> -      def_or_undef (parse_in, "__SHSTK__");

> >> -      if (flag_cf_protection != CF_NONE)

> >> -  def_or_undef (parse_in, "__CET__");

> >> -    }

> >> +  if ((isa_flag & OPTION_MASK_ISA_SHSTK))

> >> +    def_or_undef (parse_in, "__SHSTK__");

> >> +  if (flag_cf_protection != CF_NONE)

> >> +    def_or_undef (parse_in, "__CET__");

> >> +  if ((flag_cf_protection & CF_BRANCH))

> >> +    def_or_undef (parse_in, "__CET_IBT__");

> >> +  if ((flag_cf_protection & CF_RETURN))

> >> +    def_or_undef (parse_in, "__CET_SHSTK__");

> >>    if (isa_flag2 & OPTION_MASK_ISA_VAES)

> >>      def_or_undef (parse_in, "__VAES__");

> >>    if (isa_flag & OPTION_MASK_ISA_VPCLMULQDQ)

> >>

> >> This adds __CET_IBT__ and __CET_SHSTK__.

> >

> > As -fcf-protection and -mcet/-mibt/-mshstk are are disjoint and

> > control different parts I agree with

> >

> > +  if ((isa_flag & OPTION_MASK_ISA_SHSTK))

> > +    def_or_undef (parse_in, "__SHSTK__");

> > +  if (flag_cf_protection != CF_NONE)

> > +    def_or_undef (parse_in, "__CET__");

> >

> > Why __CET_IBT__ and __CET_SHSTK__ are needed? Moreover the naming is

> > confusing as 'IBT' and 'SHSTK' are related to HW features which are

> controlled

> > by -m options. __CET__ seems to be enough.

> >

> 

> One needs to know if IBT and SHSTK are enabled by -fcf-protection.  They will

> be checked by <cet.h> and glibc.


Ok. But then __CET__ could be removed as it's easily calculated given these two _CET_IBT_
and _CET_SHSTK_ macros. Also individual macro is used mostly.

Igor

> --

> H.J.
H.J. Lu April 20, 2018, 1:17 a.m. | #28
On Thu, Apr 19, 2018 at 3:37 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Thu, Apr 19, 2018 at 03:08:06PM -0700, H.J. Lu wrote:

>> > As -fcf-protection and -mcet/-mibt/-mshstk are are disjoint and

>> > control different parts I agree with

>> >

>> > +  if ((isa_flag & OPTION_MASK_ISA_SHSTK))

>> > +    def_or_undef (parse_in, "__SHSTK__");

>> > +  if (flag_cf_protection != CF_NONE)

>> > +    def_or_undef (parse_in, "__CET__");

>> >

>> > Why __CET_IBT__ and __CET_SHSTK__ are needed? Moreover the naming is

>> > confusing as 'IBT' and 'SHSTK' are related to HW features which are controlled

>> > by -m options. __CET__ seems to be enough.

>> >

>>

>> One needs to know if IBT and SHSTK are enabled by -fcf-protection.  They will

>> be checked by <cet.h> and glibc.

>

> So can't you define __CET__ to 3 if CF_FULL, to 1 if CF_BRANCH and 2 if

> CF_RETURN?  Then if code doesn't care which one it is, it can just #ifdef

> __CET__, otherwise it can test which of those is enabled.

> Implementation-wise it would probably need to be:

>   if (flag_cf_protection != CF_NONE)

>     {

>       if (def_or_undef == cpp_undef)

>         def_or_undef (parse_in, "__CET__");

>       else if ((flag_cf_protection & CF_FULL) == CF_FULL)

>         def_or_undef (parse_in, "__CET__=3");

>       else if (flag_cf_protection & CF_BRANCH)

>         def_or_undef (parse_in, "__CET__=1");

>       else if (flag_cf_protection & CF_RETURN)

>         def_or_undef (parse_in, "__CET__=2");

>     }

> or so.  Actually, because it doesn't depend on something that can change

> depending on target attributes, it probably doesn't even belong in this

> function, but to ix86_target_macros and there you can just cpp_define

> it, don't deal with cpp_undef at all.


Something like this?


-- 
H.J.
From 435b905d0dd60c3e6b00f42d7614a47972d69551 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 19 Apr 2018 14:09:51 -0700
Subject: [PATCH] Define __CET__ with flag_cf_protection and remove -mibt

---
 gcc/common/config/i386/i386-common.c | 17 -----------------
 gcc/config/i386/cet.h                |  6 +++---
 gcc/config/i386/i386-c.c             | 20 ++++++--------------
 gcc/config/i386/i386.c               |  2 --
 gcc/config/i386/i386.md              |  2 +-
 gcc/config/i386/i386.opt             | 12 ++++--------
 gcc/doc/invoke.texi                  | 23 ++++++-----------------
 7 files changed, 20 insertions(+), 62 deletions(-)

diff --git a/gcc/common/config/i386/i386-common.c b/gcc/common/config/i386/i386-common.c
index 0bb2783cfab..74a3490f7a3 100644
--- a/gcc/common/config/i386/i386-common.c
+++ b/gcc/common/config/i386/i386-common.c
@@ -147,7 +147,6 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_MASK_ISA_PKU_SET OPTION_MASK_ISA_PKU
 #define OPTION_MASK_ISA_RDPID_SET OPTION_MASK_ISA_RDPID
 #define OPTION_MASK_ISA_GFNI_SET OPTION_MASK_ISA_GFNI
-#define OPTION_MASK_ISA_IBT_SET OPTION_MASK_ISA_IBT
 #define OPTION_MASK_ISA_SHSTK_SET OPTION_MASK_ISA_SHSTK
 #define OPTION_MASK_ISA_VAES_SET OPTION_MASK_ISA_VAES
 #define OPTION_MASK_ISA_VPCLMULQDQ_SET OPTION_MASK_ISA_VPCLMULQDQ
@@ -224,7 +223,6 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_MASK_ISA_PKU_UNSET OPTION_MASK_ISA_PKU
 #define OPTION_MASK_ISA_RDPID_UNSET OPTION_MASK_ISA_RDPID
 #define OPTION_MASK_ISA_GFNI_UNSET OPTION_MASK_ISA_GFNI
-#define OPTION_MASK_ISA_IBT_UNSET OPTION_MASK_ISA_IBT
 #define OPTION_MASK_ISA_SHSTK_UNSET OPTION_MASK_ISA_SHSTK
 #define OPTION_MASK_ISA_VAES_UNSET OPTION_MASK_ISA_VAES
 #define OPTION_MASK_ISA_VPCLMULQDQ_UNSET OPTION_MASK_ISA_VPCLMULQDQ
@@ -546,21 +544,6 @@ ix86_handle_option (struct gcc_options *opts,
       return true;
 
     case OPT_mcet:
-    case OPT_mibt:
-      if (value)
-	{
-	  opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA_IBT_SET;
-	  opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA_IBT_SET;
-	}
-      else
-	{
-	  opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA_IBT_UNSET;
-	  opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA_IBT_UNSET;
-	}
-      if (code != OPT_mcet)
-	return true;
-      /* fall through.  */
-
     case OPT_mshstk:
       if (value)
 	{
diff --git a/gcc/config/i386/cet.h b/gcc/config/i386/cet.h
index 9dca41bad2d..c38e594ad92 100644
--- a/gcc/config/i386/cet.h
+++ b/gcc/config/i386/cet.h
@@ -32,7 +32,7 @@
 
 #ifdef __ASSEMBLER__
 
-# ifdef __IBT__
+# if (__CET__ & 1) != 0
 #  ifdef __x86_64__
 #   define _CET_ENDBR endbr64
 #  else
@@ -44,14 +44,14 @@
 
 # ifdef __ELF__
 #  ifdef __CET__
-#   ifdef __IBT__
+#   if (__CET__ & 1) != 0
 /* GNU_PROPERTY_X86_FEATURE_1_IBT.  */
 #    define __PROPERTY_IBT 0x1
 #   else
 #    define __PROPERTY_IBT 0x0
 #   endif
 
-#   ifdef __SHSTK__
+#   if (__CET__ & 2) != 0
 /* GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */
 #    define __PROPERTY_SHSTK 0x2
 #   else
diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c
index fa8b3682b0c..ae7d678e77e 100644
--- a/gcc/config/i386/i386-c.c
+++ b/gcc/config/i386/i386-c.c
@@ -499,20 +499,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
     def_or_undef (parse_in, "__RDPID__");
   if (isa_flag & OPTION_MASK_ISA_GFNI)
     def_or_undef (parse_in, "__GFNI__");
-  if ((isa_flag2 & OPTION_MASK_ISA_IBT)
-      || (flag_cf_protection & CF_BRANCH))
-    {
-      def_or_undef (parse_in, "__IBT__");
-      if (flag_cf_protection != CF_NONE)
-	def_or_undef (parse_in, "__CET__");
-    }
-  if ((isa_flag & OPTION_MASK_ISA_SHSTK)
-      || (flag_cf_protection & CF_RETURN))
-    {
-      def_or_undef (parse_in, "__SHSTK__");
-      if (flag_cf_protection != CF_NONE)
-	def_or_undef (parse_in, "__CET__");
-    }
+  if ((isa_flag & OPTION_MASK_ISA_SHSTK))
+    def_or_undef (parse_in, "__SHSTK__");
   if (isa_flag2 & OPTION_MASK_ISA_VAES)
     def_or_undef (parse_in, "__VAES__");
   if (isa_flag & OPTION_MASK_ISA_VPCLMULQDQ)
@@ -680,6 +668,10 @@ ix86_target_macros (void)
 
   cpp_define (parse_in, "__SEG_FS");
   cpp_define (parse_in, "__SEG_GS");
+
+  if (flag_cf_protection != CF_NONE)
+    cpp_define_formatted (parse_in, "__CET__=%d",
+			  flag_cf_protection & ~CF_SET);
 }
 
 
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index a0435377872..dc80b34f302 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2766,7 +2766,6 @@ ix86_target_string (HOST_WIDE_INT isa, HOST_WIDE_INT isa2,
     { "-msgx",		OPTION_MASK_ISA_SGX },
     { "-mavx5124vnniw", OPTION_MASK_ISA_AVX5124VNNIW },
     { "-mavx5124fmaps", OPTION_MASK_ISA_AVX5124FMAPS },
-    { "-mibt",		OPTION_MASK_ISA_IBT },
     { "-mhle",		OPTION_MASK_ISA_HLE },
     { "-mmovbe",	OPTION_MASK_ISA_MOVBE },
     { "-mclzero",	OPTION_MASK_ISA_CLZERO },
@@ -5377,7 +5376,6 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[],
     IX86_ATTR_ISA ("clwb",	OPT_mclwb),
     IX86_ATTR_ISA ("rdpid",	OPT_mrdpid),
     IX86_ATTR_ISA ("gfni",	OPT_mgfni),
-    IX86_ATTR_ISA ("ibt",	OPT_mibt),
     IX86_ATTR_ISA ("shstk",	OPT_mshstk),
     IX86_ATTR_ISA ("vaes",	OPT_mvaes),
     IX86_ATTR_ISA ("vpclmulqdq", OPT_mvpclmulqdq),
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 33e8060fa56..a134ca88014 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -20332,7 +20332,7 @@
 
 (define_insn "nop_endbr"
   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
-  "TARGET_IBT || (flag_cf_protection & CF_BRANCH)"
+  "(flag_cf_protection & CF_BRANCH)"
   "*
 { return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }"
   [(set_attr "length" "4")
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 646cfcbbd3b..815eceb713d 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -1008,17 +1008,13 @@ Generate code which uses only the general registers.
 
 mcet
 Target Report Var(flag_cet) Init(0)
-Support Control-flow Enforcement Technology (CET) built-in functions.
-
-mibt
-Target Report Mask(ISA_IBT) Var(ix86_isa_flags2) Save
-Specifically enable indirect branch tracking built-in functions from
-Control-flow Enforcement Technology (CET).
+Enable shadow stack built-in functions from Control-flow Enforcement
+Technology (CET).
 
 mshstk
 Target Report Mask(ISA_SHSTK) Var(ix86_isa_flags) Save
-Specifically enable shadow stack built-in functions from Control-flow
-Enforcement Technology (CET).
+Enable shadow stack built-in functions from Control-flow Enforcement
+Technology (CET).
 
 mcet-switch
 Target Report Undocumented Var(flag_cet_switch) Init(0)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 0f2c83964f4..43eded693ec 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1261,7 +1261,7 @@ See RS/6000 and PowerPC Options.
 -msse4a  -m3dnow  -m3dnowa  -mpopcnt  -mabm  -mbmi  -mtbm  -mfma4  -mxop @gol
 -mlzcnt  -mbmi2  -mfxsr  -mxsave  -mxsaveopt  -mrtm  -mlwp  -mmpx  @gol
 -mmwaitx  -mclzero  -mpku  -mthreads -mgfni  -mvaes  @gol
--mcet -mibt -mshstk -mforce-indirect-call -mavx512vbmi2 @gol
+-mcet -mshstk -mforce-indirect-call -mavx512vbmi2 @gol
 -mvpclmulqdq -mavx512bitalg -mmovdiri -mmovdir64b -mavx512vpopcntdq @gol
 -mms-bitfields  -mno-align-stringops  -minline-all-stringops @gol
 -minline-stringops-dynamically  -mstringop-strategy=@var{alg} @gol
@@ -27349,11 +27349,6 @@ supported architecture, using the appropriate flags.  In particular,
 the file containing the CPU detection code should be compiled without
 these options.
 
-The @option{-mcet} option turns on the @option{-mibt} and @option{-mshstk}
-options.  The compiler provides a number of built-in functions for
-fine-grained control in a CET-based application.  See
-@xref{x86 Built-in Functions}, for more information.
-
 @item -mdump-tune-features
 @opindex mdump-tune-features
 This option instructs GCC to dump the names of the x86 performance 
@@ -27446,19 +27441,13 @@ see @ref{Other Builtins} for details.
 This option enables use of the @code{movbe} instruction to implement
 @code{__builtin_bswap32} and @code{__builtin_bswap64}.
 
-@item -mibt
-@opindex mibt
-This option enables indirect branch tracking built-in functions from
-x86 Control-flow Enforcement Technology (CET).  The option
-@option{-mibt} is on by default when the @code{-mcet} option is
-specified.
-
 @item -mshstk
+@itemx -mcet
 @opindex mshstk
-This option enables shadow stack built-in functions from x86
-Control-flow Enforcement Technology (CET).  The option
-@option{-mshstk} is on by default when the @option{-mcet} option is
-specified.
+@opindex mcet
+The @option{-mshstk} option enables shadow stack built-in functions
+from x86 Control-flow Enforcement Technology (CET).  The @option{-mcet}
+option is an alias for the @option{-mshstk} option.
 
 @item -mcrc32
 @opindex mcrc32
Tsimbalist, Igor V April 20, 2018, 6:25 a.m. | #29
> -----Original Message-----

> From: H.J. Lu [mailto:hjl.tools@gmail.com]

> Sent: Friday, April 20, 2018 3:17 AM

> To: Jakub Jelinek <jakub@redhat.com>

> Cc: Tsimbalist, Igor V <igor.v.tsimbalist@intel.com>; Richard Biener

> <richard.guenther@gmail.com>; Uros Bizjak <ubizjak@gmail.com>; gcc-

> patches@gcc.gnu.org

> Subject: Re: [PATCH] x86: Allow -fcf-protection with multi-byte NOPs

> 

> On Thu, Apr 19, 2018 at 3:37 PM, Jakub Jelinek <jakub@redhat.com> wrote:

> > On Thu, Apr 19, 2018 at 03:08:06PM -0700, H.J. Lu wrote:

> >> > As -fcf-protection and -mcet/-mibt/-mshstk are are disjoint and

> >> > control different parts I agree with

> >> >

> >> > +  if ((isa_flag & OPTION_MASK_ISA_SHSTK))

> >> > +    def_or_undef (parse_in, "__SHSTK__");

> >> > +  if (flag_cf_protection != CF_NONE)

> >> > +    def_or_undef (parse_in, "__CET__");

> >> >

> >> > Why __CET_IBT__ and __CET_SHSTK__ are needed? Moreover the

> naming is

> >> > confusing as 'IBT' and 'SHSTK' are related to HW features which are

> controlled

> >> > by -m options. __CET__ seems to be enough.

> >> >

> >>

> >> One needs to know if IBT and SHSTK are enabled by -fcf-protection.

> They will

> >> be checked by <cet.h> and glibc.

> >

> > So can't you define __CET__ to 3 if CF_FULL, to 1 if CF_BRANCH and 2 if

> > CF_RETURN?  Then if code doesn't care which one it is, it can just #ifdef

> > __CET__, otherwise it can test which of those is enabled.

> > Implementation-wise it would probably need to be:

> >   if (flag_cf_protection != CF_NONE)

> >     {

> >       if (def_or_undef == cpp_undef)

> >         def_or_undef (parse_in, "__CET__");

> >       else if ((flag_cf_protection & CF_FULL) == CF_FULL)

> >         def_or_undef (parse_in, "__CET__=3");

> >       else if (flag_cf_protection & CF_BRANCH)

> >         def_or_undef (parse_in, "__CET__=1");

> >       else if (flag_cf_protection & CF_RETURN)

> >         def_or_undef (parse_in, "__CET__=2");

> >     }

> > or so.  Actually, because it doesn't depend on something that can change

> > depending on target attributes, it probably doesn't even belong in this

> > function, but to ix86_target_macros and there you can just cpp_define

> > it, don't deal with cpp_undef at all.

> 

> Something like this?


Shouldn't this

-# ifdef __IBT__
+# if (__CET__ & 1) != 0

Be as

-# ifdef __IBT__
+#ifdef __CET__
+# if (__CET__ & 1) != 0

OK otherwise.

Igor

> 

> --

> H.J.
Jakub Jelinek April 20, 2018, 7:39 a.m. | #30
On Fri, Apr 20, 2018 at 06:25:10AM +0000, Tsimbalist, Igor V wrote:
> > Something like this?

> 

> Shouldn't this

> 

> -# ifdef __IBT__

> +# if (__CET__ & 1) != 0

> 

> Be as

> 

> -# ifdef __IBT__

> +#ifdef __CET__

> +# if (__CET__ & 1) != 0

> 

> OK otherwise.


Only if you use -Wundef warning (not part of -Wall or -W) and, if this
is a system header, only with -Wundef -Wsystem-headers.
But perhaps it doesn't hurt to wrap it.

	Jakub
H.J. Lu April 20, 2018, 11:15 a.m. | #31
On Fri, Apr 20, 2018 at 09:39:58AM +0200, Jakub Jelinek wrote:
> On Fri, Apr 20, 2018 at 06:25:10AM +0000, Tsimbalist, Igor V wrote:

> > > Something like this?

> > 

> > Shouldn't this

> > 

> > -# ifdef __IBT__

> > +# if (__CET__ & 1) != 0

> > 

> > Be as

> > 

> > -# ifdef __IBT__

> > +#ifdef __CET__

> > +# if (__CET__ & 1) != 0

> > 

> > OK otherwise.

> 

> Only if you use -Wundef warning (not part of -Wall or -W) and, if this

> is a system header, only with -Wundef -Wsystem-headers.

> But perhaps it doesn't hurt to wrap it.

> 

> 	Jakub


Here is the patch.  OK for trunk?

Thanks.


H.J.
---
With revision 259496:

commit b1384095a7c1d06a44b70853372ebe037b2f7867
Author: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Thu Apr 19 15:15:04 2018 +0000

    x86: Enable -fcf-protection with multi-byte NOPs

-mibt does nothing and can be removed.  Define __CET__ to indicate level
protection with -fcf-protection:

(__CET__ & 1) != 0: -fcf-protection=branch or -fcf-protection=full
(__CET__ & 2) != 0: -fcf-protection=return or -fcf-protection=full

gcc/

	PR target/85469
	* common/config/i386/i386-common.c (OPTION_MASK_ISA_IBT_SET):
	Removed.
	(OPTION_MASK_ISA_IBT_UNSET): Likewise.
	(ix86_handle_option): Don't handle OPT_mibt.
	* config/i386/cet.h: Check __CET__ instead of __IBT__ and
	__SHSTK__.
	* config/i386/driver-i386.c (host_detect_local_cpu): Remove
	has_ibt and ibt.
	* config/i386/i386-c.c (ix86_target_macros_internal): Don't
	check OPTION_MASK_ISA_IBT nor flag_cf_protection.
	(ix86_target_macros): Define __CET__ with flag_cf_protection
	for -fcf-protection.
	* config/i386/i386.c (isa2_opts): Remove -mibt.
	* config/i386/i386.h (TARGET_IBT): Removed.
	(TARGET_IBT_P): Likewise.
	(ix86_valid_target_attribute_inner_p): Don't check OPT_mibt.
	* config/i386/i386.md (nop_endbr): Don't check TARGET_IBT.
	* config/i386/i386.opt (mcet): Update help message.
	(mshstk): Likewise.
	(mibt): Removed.
	* doc/invoke.texi: Remove -mibt.  Document __CET__.  Document
	-mcet as an alias for -mshstk.

gcc/testsuite/

	PR target/85469
	* gcc.target/i386/pr85044.c (dg-options): Remove -mibt.
	* gcc.target/i386/sse-26.c (dg-options): Remove -mno-ibt.
---
 gcc/common/config/i386/i386-common.c    | 17 -----------------
 gcc/config/i386/cet.h                   |  6 +++---
 gcc/config/i386/driver-i386.c           |  6 ++----
 gcc/config/i386/i386-c.c                | 20 ++++++--------------
 gcc/config/i386/i386.c                  |  2 --
 gcc/config/i386/i386.h                  |  2 --
 gcc/config/i386/i386.md                 |  2 +-
 gcc/config/i386/i386.opt                | 12 ++++--------
 gcc/doc/invoke.texi                     | 28 +++++++++++-----------------
 gcc/testsuite/gcc.target/i386/pr85044.c |  2 +-
 gcc/testsuite/gcc.target/i386/sse-26.c  |  2 +-
 11 files changed, 29 insertions(+), 70 deletions(-)

diff --git a/gcc/common/config/i386/i386-common.c b/gcc/common/config/i386/i386-common.c
index 0bb2783cfab..74a3490f7a3 100644
--- a/gcc/common/config/i386/i386-common.c
+++ b/gcc/common/config/i386/i386-common.c
@@ -147,7 +147,6 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_MASK_ISA_PKU_SET OPTION_MASK_ISA_PKU
 #define OPTION_MASK_ISA_RDPID_SET OPTION_MASK_ISA_RDPID
 #define OPTION_MASK_ISA_GFNI_SET OPTION_MASK_ISA_GFNI
-#define OPTION_MASK_ISA_IBT_SET OPTION_MASK_ISA_IBT
 #define OPTION_MASK_ISA_SHSTK_SET OPTION_MASK_ISA_SHSTK
 #define OPTION_MASK_ISA_VAES_SET OPTION_MASK_ISA_VAES
 #define OPTION_MASK_ISA_VPCLMULQDQ_SET OPTION_MASK_ISA_VPCLMULQDQ
@@ -224,7 +223,6 @@ along with GCC; see the file COPYING3.  If not see
 #define OPTION_MASK_ISA_PKU_UNSET OPTION_MASK_ISA_PKU
 #define OPTION_MASK_ISA_RDPID_UNSET OPTION_MASK_ISA_RDPID
 #define OPTION_MASK_ISA_GFNI_UNSET OPTION_MASK_ISA_GFNI
-#define OPTION_MASK_ISA_IBT_UNSET OPTION_MASK_ISA_IBT
 #define OPTION_MASK_ISA_SHSTK_UNSET OPTION_MASK_ISA_SHSTK
 #define OPTION_MASK_ISA_VAES_UNSET OPTION_MASK_ISA_VAES
 #define OPTION_MASK_ISA_VPCLMULQDQ_UNSET OPTION_MASK_ISA_VPCLMULQDQ
@@ -546,21 +544,6 @@ ix86_handle_option (struct gcc_options *opts,
       return true;
 
     case OPT_mcet:
-    case OPT_mibt:
-      if (value)
-	{
-	  opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA_IBT_SET;
-	  opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA_IBT_SET;
-	}
-      else
-	{
-	  opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA_IBT_UNSET;
-	  opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA_IBT_UNSET;
-	}
-      if (code != OPT_mcet)
-	return true;
-      /* fall through.  */
-
     case OPT_mshstk:
       if (value)
 	{
diff --git a/gcc/config/i386/cet.h b/gcc/config/i386/cet.h
index 9dca41bad2d..309f6428735 100644
--- a/gcc/config/i386/cet.h
+++ b/gcc/config/i386/cet.h
@@ -32,7 +32,7 @@
 
 #ifdef __ASSEMBLER__
 
-# ifdef __IBT__
+# if defined __CET__ && (__CET__ & 1) != 0
 #  ifdef __x86_64__
 #   define _CET_ENDBR endbr64
 #  else
@@ -44,14 +44,14 @@
 
 # ifdef __ELF__
 #  ifdef __CET__
-#   ifdef __IBT__
+#   if (__CET__ & 1) != 0
 /* GNU_PROPERTY_X86_FEATURE_1_IBT.  */
 #    define __PROPERTY_IBT 0x1
 #   else
 #    define __PROPERTY_IBT 0x0
 #   endif
 
-#   ifdef __SHSTK__
+#   if (__CET__ & 2) != 0
 /* GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */
 #    define __PROPERTY_SHSTK 0x2
 #   else
diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c
index 19db252dfc0..704cadd8fcf 100644
--- a/gcc/config/i386/driver-i386.c
+++ b/gcc/config/i386/driver-i386.c
@@ -420,7 +420,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
   unsigned int has_avx5124fmaps = 0, has_avx5124vnniw = 0;
   unsigned int has_gfni = 0, has_avx512vbmi2 = 0;
   unsigned int has_avx512bitalg = 0;
-  unsigned int has_ibt = 0, has_shstk = 0;
+  unsigned int has_shstk = 0;
   unsigned int has_avx512vnni = 0, has_vaes = 0;
   unsigned int has_vpclmulqdq = 0;
   unsigned int has_movdiri = 0, has_movdir64b = 0;
@@ -526,7 +526,6 @@ const char *host_detect_local_cpu (int argc, const char **argv)
       has_avx5124fmaps = edx & bit_AVX5124FMAPS;
 
       has_shstk = ecx & bit_SHSTK;
-      has_ibt = edx & bit_IBT;
       has_pconfig = edx & bit_PCONFIG;
     }
 
@@ -1095,7 +1094,6 @@ const char *host_detect_local_cpu (int argc, const char **argv)
       const char *pku = has_pku ? " -mpku" : " -mno-pku";
       const char *rdpid = has_rdpid ? " -mrdpid" : " -mno-rdpid";
       const char *gfni = has_gfni ? " -mgfni" : " -mno-gfni";
-      const char *ibt = has_ibt ? " -mibt" : " -mno-ibt";
       const char *shstk = has_shstk ? " -mshstk" : " -mno-shstk";
       const char *vaes = has_vaes ? " -mvaes" : " -mno-vaes";
       const char *vpclmulqdq = has_vpclmulqdq ? " -mvpclmulqdq" : " -mno-vpclmulqdq";
@@ -1112,7 +1110,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
 			avx512cd, avx512pf, prefetchwt1, clflushopt,
 			xsavec, xsaves, avx512dq, avx512bw, avx512vl,
 			avx512ifma, avx512vbmi, avx5124fmaps, avx5124vnniw,
-			clwb, mwaitx, clzero, pku, rdpid, gfni, ibt, shstk,
+			clwb, mwaitx, clzero, pku, rdpid, gfni, shstk,
 			avx512vbmi2, avx512vnni, vaes, vpclmulqdq,
 			avx512bitalg, movdiri, movdir64b, NULL);
     }
diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c
index fa8b3682b0c..ae7d678e77e 100644
--- a/gcc/config/i386/i386-c.c
+++ b/gcc/config/i386/i386-c.c
@@ -499,20 +499,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
     def_or_undef (parse_in, "__RDPID__");
   if (isa_flag & OPTION_MASK_ISA_GFNI)
     def_or_undef (parse_in, "__GFNI__");
-  if ((isa_flag2 & OPTION_MASK_ISA_IBT)
-      || (flag_cf_protection & CF_BRANCH))
-    {
-      def_or_undef (parse_in, "__IBT__");
-      if (flag_cf_protection != CF_NONE)
-	def_or_undef (parse_in, "__CET__");
-    }
-  if ((isa_flag & OPTION_MASK_ISA_SHSTK)
-      || (flag_cf_protection & CF_RETURN))
-    {
-      def_or_undef (parse_in, "__SHSTK__");
-      if (flag_cf_protection != CF_NONE)
-	def_or_undef (parse_in, "__CET__");
-    }
+  if ((isa_flag & OPTION_MASK_ISA_SHSTK))
+    def_or_undef (parse_in, "__SHSTK__");
   if (isa_flag2 & OPTION_MASK_ISA_VAES)
     def_or_undef (parse_in, "__VAES__");
   if (isa_flag & OPTION_MASK_ISA_VPCLMULQDQ)
@@ -680,6 +668,10 @@ ix86_target_macros (void)
 
   cpp_define (parse_in, "__SEG_FS");
   cpp_define (parse_in, "__SEG_GS");
+
+  if (flag_cf_protection != CF_NONE)
+    cpp_define_formatted (parse_in, "__CET__=%d",
+			  flag_cf_protection & ~CF_SET);
 }
 
 
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index a0435377872..dc80b34f302 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2766,7 +2766,6 @@ ix86_target_string (HOST_WIDE_INT isa, HOST_WIDE_INT isa2,
     { "-msgx",		OPTION_MASK_ISA_SGX },
     { "-mavx5124vnniw", OPTION_MASK_ISA_AVX5124VNNIW },
     { "-mavx5124fmaps", OPTION_MASK_ISA_AVX5124FMAPS },
-    { "-mibt",		OPTION_MASK_ISA_IBT },
     { "-mhle",		OPTION_MASK_ISA_HLE },
     { "-mmovbe",	OPTION_MASK_ISA_MOVBE },
     { "-mclzero",	OPTION_MASK_ISA_CLZERO },
@@ -5377,7 +5376,6 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[],
     IX86_ATTR_ISA ("clwb",	OPT_mclwb),
     IX86_ATTR_ISA ("rdpid",	OPT_mrdpid),
     IX86_ATTR_ISA ("gfni",	OPT_mgfni),
-    IX86_ATTR_ISA ("ibt",	OPT_mibt),
     IX86_ATTR_ISA ("shstk",	OPT_mshstk),
     IX86_ATTR_ISA ("vaes",	OPT_mvaes),
     IX86_ATTR_ISA ("vpclmulqdq", OPT_mvpclmulqdq),
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 3734ba1bc12..795ad2a322b 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -183,8 +183,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define TARGET_MWAITX_P(x)	TARGET_ISA_MWAITX_P(x)
 #define TARGET_PKU	TARGET_ISA_PKU
 #define TARGET_PKU_P(x)	TARGET_ISA_PKU_P(x)
-#define TARGET_IBT	TARGET_ISA_IBT
-#define TARGET_IBT_P(x)	TARGET_ISA_IBT_P(x)
 #define TARGET_SHSTK	TARGET_ISA_SHSTK
 #define TARGET_SHSTK_P(x)	TARGET_ISA_SHSTK_P(x)
 #define TARGET_MOVDIRI	TARGET_ISA_MOVDIRI
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 33e8060fa56..a134ca88014 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -20332,7 +20332,7 @@
 
 (define_insn "nop_endbr"
   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
-  "TARGET_IBT || (flag_cf_protection & CF_BRANCH)"
+  "(flag_cf_protection & CF_BRANCH)"
   "*
 { return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }"
   [(set_attr "length" "4")
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 646cfcbbd3b..815eceb713d 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -1008,17 +1008,13 @@ Generate code which uses only the general registers.
 
 mcet
 Target Report Var(flag_cet) Init(0)
-Support Control-flow Enforcement Technology (CET) built-in functions.
-
-mibt
-Target Report Mask(ISA_IBT) Var(ix86_isa_flags2) Save
-Specifically enable indirect branch tracking built-in functions from
-Control-flow Enforcement Technology (CET).
+Enable shadow stack built-in functions from Control-flow Enforcement
+Technology (CET).
 
 mshstk
 Target Report Mask(ISA_SHSTK) Var(ix86_isa_flags) Save
-Specifically enable shadow stack built-in functions from Control-flow
-Enforcement Technology (CET).
+Enable shadow stack built-in functions from Control-flow Enforcement
+Technology (CET).
 
 mcet-switch
 Target Report Undocumented Var(flag_cet_switch) Init(0)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 0f2c83964f4..b6784b75fa2 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -1261,7 +1261,7 @@ See RS/6000 and PowerPC Options.
 -msse4a  -m3dnow  -m3dnowa  -mpopcnt  -mabm  -mbmi  -mtbm  -mfma4  -mxop @gol
 -mlzcnt  -mbmi2  -mfxsr  -mxsave  -mxsaveopt  -mrtm  -mlwp  -mmpx  @gol
 -mmwaitx  -mclzero  -mpku  -mthreads -mgfni  -mvaes  @gol
--mcet -mibt -mshstk -mforce-indirect-call -mavx512vbmi2 @gol
+-mcet -mshstk -mforce-indirect-call -mavx512vbmi2 @gol
 -mvpclmulqdq -mavx512bitalg -mmovdiri -mmovdir64b -mavx512vpopcntdq @gol
 -mms-bitfields  -mno-align-stringops  -minline-all-stringops @gol
 -minline-stringops-dynamically  -mstringop-strategy=@var{alg} @gol
@@ -11829,6 +11829,11 @@ function.  The value @code{full} is an alias for specifying both
 @code{branch} and @code{return}. The value @code{none} turns off
 instrumentation.
 
+The macro @code{__CET__} is defined when @option{-fcf-protection} is
+used.  The first bit of @code{__CET__} is set to 1 for the value
+@code{branch} and the second bit of @code{__CET__} is set to 1 for
+the @code{return}.
+
 You can also use the @code{nocf_check} attribute to identify
 which functions and calls should be skipped from instrumentation
 (@pxref{Function Attributes}).
@@ -27349,11 +27354,6 @@ supported architecture, using the appropriate flags.  In particular,
 the file containing the CPU detection code should be compiled without
 these options.
 
-The @option{-mcet} option turns on the @option{-mibt} and @option{-mshstk}
-options.  The compiler provides a number of built-in functions for
-fine-grained control in a CET-based application.  See
-@xref{x86 Built-in Functions}, for more information.
-
 @item -mdump-tune-features
 @opindex mdump-tune-features
 This option instructs GCC to dump the names of the x86 performance 
@@ -27446,19 +27446,13 @@ see @ref{Other Builtins} for details.
 This option enables use of the @code{movbe} instruction to implement
 @code{__builtin_bswap32} and @code{__builtin_bswap64}.
 
-@item -mibt
-@opindex mibt
-This option enables indirect branch tracking built-in functions from
-x86 Control-flow Enforcement Technology (CET).  The option
-@option{-mibt} is on by default when the @code{-mcet} option is
-specified.
-
 @item -mshstk
+@itemx -mcet
 @opindex mshstk
-This option enables shadow stack built-in functions from x86
-Control-flow Enforcement Technology (CET).  The option
-@option{-mshstk} is on by default when the @option{-mcet} option is
-specified.
+@opindex mcet
+The @option{-mshstk} option enables shadow stack built-in functions
+from x86 Control-flow Enforcement Technology (CET).  The @option{-mcet}
+option is an alias for the @option{-mshstk} option.
 
 @item -mcrc32
 @opindex mcrc32
diff --git a/gcc/testsuite/gcc.target/i386/pr85044.c b/gcc/testsuite/gcc.target/i386/pr85044.c
index 332f582d79b..a25cc7fe325 100644
--- a/gcc/testsuite/gcc.target/i386/pr85044.c
+++ b/gcc/testsuite/gcc.target/i386/pr85044.c
@@ -1,5 +1,5 @@
 /* { dg-do run { target cet } } */
-/* { dg-options "-O2 -fcf-protection=branch -mibt" } */
+/* { dg-options "-O2 -fcf-protection=branch" } */
 
 void callme (void (*callback) (void));
 
diff --git a/gcc/testsuite/gcc.target/i386/sse-26.c b/gcc/testsuite/gcc.target/i386/sse-26.c
index f2607e64b59..04ffe10f42a 100644
--- a/gcc/testsuite/gcc.target/i386/sse-26.c
+++ b/gcc/testsuite/gcc.target/i386/sse-26.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse2 -mmmx -mno-sse3 -mno-3dnow -mno-fma -mno-fxsr -mno-xsave -mno-rtm -mno-prfchw -mno-rdseed -mno-adx -mno-prefetchwt1 -mno-clflushopt -mno-xsavec -mno-xsaves -mno-clwb -mno-mwaitx -mno-clzero -mno-pku -mno-rdpid -mno-gfni -mno-ibt -mno-shstk -mno-vaes -mno-vpclmulqdq" } */
+/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse2 -mmmx -mno-sse3 -mno-3dnow -mno-fma -mno-fxsr -mno-xsave -mno-rtm -mno-prfchw -mno-rdseed -mno-adx -mno-prefetchwt1 -mno-clflushopt -mno-xsavec -mno-xsaves -mno-clwb -mno-mwaitx -mno-clzero -mno-pku -mno-rdpid -mno-gfni -mno-shstk -mno-vaes -mno-vpclmulqdq" } */
 /* { dg-add-options bind_pic_locally } */
 
 #include "sse-13.c"
-- 
2.14.3
Tsimbalist, Igor V April 20, 2018, 1:22 p.m. | #32
> -----Original Message-----

> From: H.J. Lu [mailto:hjl.tools@gmail.com]

> Sent: Friday, April 20, 2018 1:15 PM

> To: Jakub Jelinek <jakub@redhat.com>

> Cc: Tsimbalist, Igor V <igor.v.tsimbalist@intel.com>; Richard Biener

> <richard.guenther@gmail.com>; Uros Bizjak <ubizjak@gmail.com>; gcc-

> patches@gcc.gnu.org

> Subject: Re: [PATCH] x86: Allow -fcf-protection with multi-byte NOPs

> 

> On Fri, Apr 20, 2018 at 09:39:58AM +0200, Jakub Jelinek wrote:

> > On Fri, Apr 20, 2018 at 06:25:10AM +0000, Tsimbalist, Igor V wrote:

> > > > Something like this?

> > >

> > > Shouldn't this

> > >

> > > -# ifdef __IBT__

> > > +# if (__CET__ & 1) != 0

> > >

> > > Be as

> > >

> > > -# ifdef __IBT__

> > > +#ifdef __CET__

> > > +# if (__CET__ & 1) != 0

> > >

> > > OK otherwise.

> >

> > Only if you use -Wundef warning (not part of -Wall or -W) and, if this

> > is a system header, only with -Wundef -Wsystem-headers.

> > But perhaps it doesn't hurt to wrap it.

> >

> > 	Jakub

> 

> Here is the patch.  OK for trunk?

> 

> Thanks.


OK.

Igor

> 

> H.J.

> ---

> With revision 259496:

> 

> commit b1384095a7c1d06a44b70853372ebe037b2f7867

> Author: hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4>

> Date:   Thu Apr 19 15:15:04 2018 +0000

> 

>     x86: Enable -fcf-protection with multi-byte NOPs

> 

> -mibt does nothing and can be removed.  Define __CET__ to indicate level

> protection with -fcf-protection:

> 

> (__CET__ & 1) != 0: -fcf-protection=branch or -fcf-protection=full

> (__CET__ & 2) != 0: -fcf-protection=return or -fcf-protection=full

> 

> gcc/

> 

> 	PR target/85469

> 	* common/config/i386/i386-common.c

> (OPTION_MASK_ISA_IBT_SET):

> 	Removed.

> 	(OPTION_MASK_ISA_IBT_UNSET): Likewise.

> 	(ix86_handle_option): Don't handle OPT_mibt.

> 	* config/i386/cet.h: Check __CET__ instead of __IBT__ and

> 	__SHSTK__.

> 	* config/i386/driver-i386.c (host_detect_local_cpu): Remove

> 	has_ibt and ibt.

> 	* config/i386/i386-c.c (ix86_target_macros_internal): Don't

> 	check OPTION_MASK_ISA_IBT nor flag_cf_protection.

> 	(ix86_target_macros): Define __CET__ with flag_cf_protection

> 	for -fcf-protection.

> 	* config/i386/i386.c (isa2_opts): Remove -mibt.

> 	* config/i386/i386.h (TARGET_IBT): Removed.

> 	(TARGET_IBT_P): Likewise.

> 	(ix86_valid_target_attribute_inner_p): Don't check OPT_mibt.

> 	* config/i386/i386.md (nop_endbr): Don't check TARGET_IBT.

> 	* config/i386/i386.opt (mcet): Update help message.

> 	(mshstk): Likewise.

> 	(mibt): Removed.

> 	* doc/invoke.texi: Remove -mibt.  Document __CET__.  Document

> 	-mcet as an alias for -mshstk.

> 

> gcc/testsuite/

> 

> 	PR target/85469

> 	* gcc.target/i386/pr85044.c (dg-options): Remove -mibt.

> 	* gcc.target/i386/sse-26.c (dg-options): Remove -mno-ibt.

> ---

>  gcc/common/config/i386/i386-common.c    | 17 -----------------

>  gcc/config/i386/cet.h                   |  6 +++---

>  gcc/config/i386/driver-i386.c           |  6 ++----

>  gcc/config/i386/i386-c.c                | 20 ++++++--------------

>  gcc/config/i386/i386.c                  |  2 --

>  gcc/config/i386/i386.h                  |  2 --

>  gcc/config/i386/i386.md                 |  2 +-

>  gcc/config/i386/i386.opt                | 12 ++++--------

>  gcc/doc/invoke.texi                     | 28 +++++++++++-----------------

>  gcc/testsuite/gcc.target/i386/pr85044.c |  2 +-

>  gcc/testsuite/gcc.target/i386/sse-26.c  |  2 +-

>  11 files changed, 29 insertions(+), 70 deletions(-)

> 

> diff --git a/gcc/common/config/i386/i386-common.c

> b/gcc/common/config/i386/i386-common.c

> index 0bb2783cfab..74a3490f7a3 100644

> --- a/gcc/common/config/i386/i386-common.c

> +++ b/gcc/common/config/i386/i386-common.c

> @@ -147,7 +147,6 @@ along with GCC; see the file COPYING3.  If not see

>  #define OPTION_MASK_ISA_PKU_SET OPTION_MASK_ISA_PKU

>  #define OPTION_MASK_ISA_RDPID_SET OPTION_MASK_ISA_RDPID

>  #define OPTION_MASK_ISA_GFNI_SET OPTION_MASK_ISA_GFNI

> -#define OPTION_MASK_ISA_IBT_SET OPTION_MASK_ISA_IBT

>  #define OPTION_MASK_ISA_SHSTK_SET OPTION_MASK_ISA_SHSTK

>  #define OPTION_MASK_ISA_VAES_SET OPTION_MASK_ISA_VAES

>  #define OPTION_MASK_ISA_VPCLMULQDQ_SET

> OPTION_MASK_ISA_VPCLMULQDQ

> @@ -224,7 +223,6 @@ along with GCC; see the file COPYING3.  If not see

>  #define OPTION_MASK_ISA_PKU_UNSET OPTION_MASK_ISA_PKU

>  #define OPTION_MASK_ISA_RDPID_UNSET OPTION_MASK_ISA_RDPID

>  #define OPTION_MASK_ISA_GFNI_UNSET OPTION_MASK_ISA_GFNI

> -#define OPTION_MASK_ISA_IBT_UNSET OPTION_MASK_ISA_IBT

>  #define OPTION_MASK_ISA_SHSTK_UNSET OPTION_MASK_ISA_SHSTK

>  #define OPTION_MASK_ISA_VAES_UNSET OPTION_MASK_ISA_VAES

>  #define OPTION_MASK_ISA_VPCLMULQDQ_UNSET

> OPTION_MASK_ISA_VPCLMULQDQ

> @@ -546,21 +544,6 @@ ix86_handle_option (struct gcc_options *opts,

>        return true;

> 

>      case OPT_mcet:

> -    case OPT_mibt:

> -      if (value)

> -	{

> -	  opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA_IBT_SET;

> -	  opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA_IBT_SET;

> -	}

> -      else

> -	{

> -	  opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA_IBT_UNSET;

> -	  opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA_IBT_UNSET;

> -	}

> -      if (code != OPT_mcet)

> -	return true;

> -      /* fall through.  */

> -

>      case OPT_mshstk:

>        if (value)

>  	{

> diff --git a/gcc/config/i386/cet.h b/gcc/config/i386/cet.h

> index 9dca41bad2d..309f6428735 100644

> --- a/gcc/config/i386/cet.h

> +++ b/gcc/config/i386/cet.h

> @@ -32,7 +32,7 @@

> 

>  #ifdef __ASSEMBLER__

> 

> -# ifdef __IBT__

> +# if defined __CET__ && (__CET__ & 1) != 0

>  #  ifdef __x86_64__

>  #   define _CET_ENDBR endbr64

>  #  else

> @@ -44,14 +44,14 @@

> 

>  # ifdef __ELF__

>  #  ifdef __CET__

> -#   ifdef __IBT__

> +#   if (__CET__ & 1) != 0

>  /* GNU_PROPERTY_X86_FEATURE_1_IBT.  */

>  #    define __PROPERTY_IBT 0x1

>  #   else

>  #    define __PROPERTY_IBT 0x0

>  #   endif

> 

> -#   ifdef __SHSTK__

> +#   if (__CET__ & 2) != 0

>  /* GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */

>  #    define __PROPERTY_SHSTK 0x2

>  #   else

> diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c

> index 19db252dfc0..704cadd8fcf 100644

> --- a/gcc/config/i386/driver-i386.c

> +++ b/gcc/config/i386/driver-i386.c

> @@ -420,7 +420,7 @@ const char *host_detect_local_cpu (int argc, const

> char **argv)

>    unsigned int has_avx5124fmaps = 0, has_avx5124vnniw = 0;

>    unsigned int has_gfni = 0, has_avx512vbmi2 = 0;

>    unsigned int has_avx512bitalg = 0;

> -  unsigned int has_ibt = 0, has_shstk = 0;

> +  unsigned int has_shstk = 0;

>    unsigned int has_avx512vnni = 0, has_vaes = 0;

>    unsigned int has_vpclmulqdq = 0;

>    unsigned int has_movdiri = 0, has_movdir64b = 0;

> @@ -526,7 +526,6 @@ const char *host_detect_local_cpu (int argc, const

> char **argv)

>        has_avx5124fmaps = edx & bit_AVX5124FMAPS;

> 

>        has_shstk = ecx & bit_SHSTK;

> -      has_ibt = edx & bit_IBT;

>        has_pconfig = edx & bit_PCONFIG;

>      }

> 

> @@ -1095,7 +1094,6 @@ const char *host_detect_local_cpu (int argc, const

> char **argv)

>        const char *pku = has_pku ? " -mpku" : " -mno-pku";

>        const char *rdpid = has_rdpid ? " -mrdpid" : " -mno-rdpid";

>        const char *gfni = has_gfni ? " -mgfni" : " -mno-gfni";

> -      const char *ibt = has_ibt ? " -mibt" : " -mno-ibt";

>        const char *shstk = has_shstk ? " -mshstk" : " -mno-shstk";

>        const char *vaes = has_vaes ? " -mvaes" : " -mno-vaes";

>        const char *vpclmulqdq = has_vpclmulqdq ? " -mvpclmulqdq" : " -mno-

> vpclmulqdq";

> @@ -1112,7 +1110,7 @@ const char *host_detect_local_cpu (int argc, const

> char **argv)

>  			avx512cd, avx512pf, prefetchwt1, clflushopt,

>  			xsavec, xsaves, avx512dq, avx512bw, avx512vl,

>  			avx512ifma, avx512vbmi, avx5124fmaps,

> avx5124vnniw,

> -			clwb, mwaitx, clzero, pku, rdpid, gfni, ibt, shstk,

> +			clwb, mwaitx, clzero, pku, rdpid, gfni, shstk,

>  			avx512vbmi2, avx512vnni, vaes, vpclmulqdq,

>  			avx512bitalg, movdiri, movdir64b, NULL);

>      }

> diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c

> index fa8b3682b0c..ae7d678e77e 100644

> --- a/gcc/config/i386/i386-c.c

> +++ b/gcc/config/i386/i386-c.c

> @@ -499,20 +499,8 @@ ix86_target_macros_internal (HOST_WIDE_INT

> isa_flag,

>      def_or_undef (parse_in, "__RDPID__");

>    if (isa_flag & OPTION_MASK_ISA_GFNI)

>      def_or_undef (parse_in, "__GFNI__");

> -  if ((isa_flag2 & OPTION_MASK_ISA_IBT)

> -      || (flag_cf_protection & CF_BRANCH))

> -    {

> -      def_or_undef (parse_in, "__IBT__");

> -      if (flag_cf_protection != CF_NONE)

> -	def_or_undef (parse_in, "__CET__");

> -    }

> -  if ((isa_flag & OPTION_MASK_ISA_SHSTK)

> -      || (flag_cf_protection & CF_RETURN))

> -    {

> -      def_or_undef (parse_in, "__SHSTK__");

> -      if (flag_cf_protection != CF_NONE)

> -	def_or_undef (parse_in, "__CET__");

> -    }

> +  if ((isa_flag & OPTION_MASK_ISA_SHSTK))

> +    def_or_undef (parse_in, "__SHSTK__");

>    if (isa_flag2 & OPTION_MASK_ISA_VAES)

>      def_or_undef (parse_in, "__VAES__");

>    if (isa_flag & OPTION_MASK_ISA_VPCLMULQDQ)

> @@ -680,6 +668,10 @@ ix86_target_macros (void)

> 

>    cpp_define (parse_in, "__SEG_FS");

>    cpp_define (parse_in, "__SEG_GS");

> +

> +  if (flag_cf_protection != CF_NONE)

> +    cpp_define_formatted (parse_in, "__CET__=%d",

> +			  flag_cf_protection & ~CF_SET);

>  }

> 

>  


> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c

> index a0435377872..dc80b34f302 100644

> --- a/gcc/config/i386/i386.c

> +++ b/gcc/config/i386/i386.c

> @@ -2766,7 +2766,6 @@ ix86_target_string (HOST_WIDE_INT isa,

> HOST_WIDE_INT isa2,

>      { "-msgx",		OPTION_MASK_ISA_SGX },

>      { "-mavx5124vnniw", OPTION_MASK_ISA_AVX5124VNNIW },

>      { "-mavx5124fmaps", OPTION_MASK_ISA_AVX5124FMAPS },

> -    { "-mibt",		OPTION_MASK_ISA_IBT },

>      { "-mhle",		OPTION_MASK_ISA_HLE },

>      { "-mmovbe",	OPTION_MASK_ISA_MOVBE },

>      { "-mclzero",	OPTION_MASK_ISA_CLZERO },

> @@ -5377,7 +5376,6 @@ ix86_valid_target_attribute_inner_p (tree args,

> char *p_strings[],

>      IX86_ATTR_ISA ("clwb",	OPT_mclwb),

>      IX86_ATTR_ISA ("rdpid",	OPT_mrdpid),

>      IX86_ATTR_ISA ("gfni",	OPT_mgfni),

> -    IX86_ATTR_ISA ("ibt",	OPT_mibt),

>      IX86_ATTR_ISA ("shstk",	OPT_mshstk),

>      IX86_ATTR_ISA ("vaes",	OPT_mvaes),

>      IX86_ATTR_ISA ("vpclmulqdq", OPT_mvpclmulqdq),

> diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h

> index 3734ba1bc12..795ad2a322b 100644

> --- a/gcc/config/i386/i386.h

> +++ b/gcc/config/i386/i386.h

> @@ -183,8 +183,6 @@ see the files COPYING3 and COPYING.RUNTIME

> respectively.  If not, see

>  #define TARGET_MWAITX_P(x)	TARGET_ISA_MWAITX_P(x)

>  #define TARGET_PKU	TARGET_ISA_PKU

>  #define TARGET_PKU_P(x)	TARGET_ISA_PKU_P(x)

> -#define TARGET_IBT	TARGET_ISA_IBT

> -#define TARGET_IBT_P(x)	TARGET_ISA_IBT_P(x)

>  #define TARGET_SHSTK	TARGET_ISA_SHSTK

>  #define TARGET_SHSTK_P(x)	TARGET_ISA_SHSTK_P(x)

>  #define TARGET_MOVDIRI	TARGET_ISA_MOVDIRI

> diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md

> index 33e8060fa56..a134ca88014 100644

> --- a/gcc/config/i386/i386.md

> +++ b/gcc/config/i386/i386.md

> @@ -20332,7 +20332,7 @@

> 

>  (define_insn "nop_endbr"

>    [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]

> -  "TARGET_IBT || (flag_cf_protection & CF_BRANCH)"

> +  "(flag_cf_protection & CF_BRANCH)"

>    "*

>  { return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }"

>    [(set_attr "length" "4")

> diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt

> index 646cfcbbd3b..815eceb713d 100644

> --- a/gcc/config/i386/i386.opt

> +++ b/gcc/config/i386/i386.opt

> @@ -1008,17 +1008,13 @@ Generate code which uses only the general

> registers.

> 

>  mcet

>  Target Report Var(flag_cet) Init(0)

> -Support Control-flow Enforcement Technology (CET) built-in functions.

> -

> -mibt

> -Target Report Mask(ISA_IBT) Var(ix86_isa_flags2) Save

> -Specifically enable indirect branch tracking built-in functions from

> -Control-flow Enforcement Technology (CET).

> +Enable shadow stack built-in functions from Control-flow Enforcement

> +Technology (CET).

> 

>  mshstk

>  Target Report Mask(ISA_SHSTK) Var(ix86_isa_flags) Save

> -Specifically enable shadow stack built-in functions from Control-flow

> -Enforcement Technology (CET).

> +Enable shadow stack built-in functions from Control-flow Enforcement

> +Technology (CET).

> 

>  mcet-switch

>  Target Report Undocumented Var(flag_cet_switch) Init(0)

> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi

> index 0f2c83964f4..b6784b75fa2 100644

> --- a/gcc/doc/invoke.texi

> +++ b/gcc/doc/invoke.texi

> @@ -1261,7 +1261,7 @@ See RS/6000 and PowerPC Options.

>  -msse4a  -m3dnow  -m3dnowa  -mpopcnt  -mabm  -mbmi  -mtbm  -

> mfma4  -mxop @gol

>  -mlzcnt  -mbmi2  -mfxsr  -mxsave  -mxsaveopt  -mrtm  -mlwp  -mmpx

> @gol

>  -mmwaitx  -mclzero  -mpku  -mthreads -mgfni  -mvaes  @gol

> --mcet -mibt -mshstk -mforce-indirect-call -mavx512vbmi2 @gol

> +-mcet -mshstk -mforce-indirect-call -mavx512vbmi2 @gol

>  -mvpclmulqdq -mavx512bitalg -mmovdiri -mmovdir64b -

> mavx512vpopcntdq @gol

>  -mms-bitfields  -mno-align-stringops  -minline-all-stringops @gol

>  -minline-stringops-dynamically  -mstringop-strategy=@var{alg} @gol

> @@ -11829,6 +11829,11 @@ function.  The value @code{full} is an alias for

> specifying both

>  @code{branch} and @code{return}. The value @code{none} turns off

>  instrumentation.

> 

> +The macro @code{__CET__} is defined when @option{-fcf-protection} is

> +used.  The first bit of @code{__CET__} is set to 1 for the value

> +@code{branch} and the second bit of @code{__CET__} is set to 1 for

> +the @code{return}.

> +

>  You can also use the @code{nocf_check} attribute to identify

>  which functions and calls should be skipped from instrumentation

>  (@pxref{Function Attributes}).

> @@ -27349,11 +27354,6 @@ supported architecture, using the appropriate

> flags.  In particular,

>  the file containing the CPU detection code should be compiled without

>  these options.

> 

> -The @option{-mcet} option turns on the @option{-mibt} and @option{-

> mshstk}

> -options.  The compiler provides a number of built-in functions for

> -fine-grained control in a CET-based application.  See

> -@xref{x86 Built-in Functions}, for more information.

> -

>  @item -mdump-tune-features

>  @opindex mdump-tune-features

>  This option instructs GCC to dump the names of the x86 performance

> @@ -27446,19 +27446,13 @@ see @ref{Other Builtins} for details.

>  This option enables use of the @code{movbe} instruction to implement

>  @code{__builtin_bswap32} and @code{__builtin_bswap64}.

> 

> -@item -mibt

> -@opindex mibt

> -This option enables indirect branch tracking built-in functions from

> -x86 Control-flow Enforcement Technology (CET).  The option

> -@option{-mibt} is on by default when the @code{-mcet} option is

> -specified.

> -

>  @item -mshstk

> +@itemx -mcet

>  @opindex mshstk

> -This option enables shadow stack built-in functions from x86

> -Control-flow Enforcement Technology (CET).  The option

> -@option{-mshstk} is on by default when the @option{-mcet} option is

> -specified.

> +@opindex mcet

> +The @option{-mshstk} option enables shadow stack built-in functions

> +from x86 Control-flow Enforcement Technology (CET).  The @option{-mcet}

> +option is an alias for the @option{-mshstk} option.

> 

>  @item -mcrc32

>  @opindex mcrc32

> diff --git a/gcc/testsuite/gcc.target/i386/pr85044.c

> b/gcc/testsuite/gcc.target/i386/pr85044.c

> index 332f582d79b..a25cc7fe325 100644

> --- a/gcc/testsuite/gcc.target/i386/pr85044.c

> +++ b/gcc/testsuite/gcc.target/i386/pr85044.c

> @@ -1,5 +1,5 @@

>  /* { dg-do run { target cet } } */

> -/* { dg-options "-O2 -fcf-protection=branch -mibt" } */

> +/* { dg-options "-O2 -fcf-protection=branch" } */

> 

>  void callme (void (*callback) (void));

> 

> diff --git a/gcc/testsuite/gcc.target/i386/sse-26.c

> b/gcc/testsuite/gcc.target/i386/sse-26.c

> index f2607e64b59..04ffe10f42a 100644

> --- a/gcc/testsuite/gcc.target/i386/sse-26.c

> +++ b/gcc/testsuite/gcc.target/i386/sse-26.c

> @@ -1,5 +1,5 @@

>  /* { dg-do compile } */

> -/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -

> msse2 -mmmx -mno-sse3 -mno-3dnow -mno-fma -mno-fxsr -mno-xsave -

> mno-rtm -mno-prfchw -mno-rdseed -mno-adx -mno-prefetchwt1 -mno-

> clflushopt -mno-xsavec -mno-xsaves -mno-clwb -mno-mwaitx -mno-clzero -

> mno-pku -mno-rdpid -mno-gfni -mno-ibt -mno-shstk -mno-vaes -mno-

> vpclmulqdq" } */

> +/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -

> msse2 -mmmx -mno-sse3 -mno-3dnow -mno-fma -mno-fxsr -mno-xsave -

> mno-rtm -mno-prfchw -mno-rdseed -mno-adx -mno-prefetchwt1 -mno-

> clflushopt -mno-xsavec -mno-xsaves -mno-clwb -mno-mwaitx -mno-clzero -

> mno-pku -mno-rdpid -mno-gfni -mno-shstk -mno-vaes -mno-vpclmulqdq"

> } */

>  /* { dg-add-options bind_pic_locally } */

> 

>  #include "sse-13.c"

> --

> 2.14.3

Patch

diff --git a/gcc/config/i386/cet.c b/gcc/config/i386/cet.c
index 4a1e013fdde..eb3be171471 100644
--- a/gcc/config/i386/cet.c
+++ b/gcc/config/i386/cet.c
@@ -34,11 +34,11 @@  file_end_indicate_exec_stack_and_cet (void)
 
   unsigned int feature_1 = 0;
 
-  if (TARGET_IBT)
+  if (flag_cf_protection & CF_BRANCH)
     /* GNU_PROPERTY_X86_FEATURE_1_IBT.  */
     feature_1 |= 0x1;
 
-  if (TARGET_SHSTK)
+  if (flag_cf_protection & CF_RETURN)
     /* GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */
     feature_1 |= 0x2;
 
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 9074526b8a1..5e96e19a0fb 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2701,7 +2701,7 @@  public:
   /* opt_pass methods: */
   virtual bool gate (function *)
     {
-      return ((flag_cf_protection & CF_BRANCH) && TARGET_IBT);
+      return ((flag_cf_protection & CF_BRANCH));
     }
 
   virtual unsigned int execute (function *)
@@ -4936,10 +4936,15 @@  ix86_option_override_internal (bool main_args_p,
     = (cf_protection_level) (opts->x_flag_cf_protection & ~CF_SET);
   if (cf_protection != CF_NONE)
     {
+      /* Since -fcf-protection is implemented with multi-byte NOPs on
+	 all 64-bit processors as well as 32-bit processors starting
+	 with Pentium Pro, allow -fcf-protection to enable the NOP
+	 portion of CET unless CET is disabled explicitly.  */
       switch (cf_protection)
 	{
 	case CF_BRANCH:
-	  if (! TARGET_IBT_P (opts->x_ix86_isa_flags2))
+	  if (!TARGET_IBT_P (opts->x_ix86_isa_flags2)
+	      && opts->x_flag_cet >= 0)
 	    {
 	      error ("%<-fcf-protection=branch%> requires Intel CET "
 		     "support. Use -mcet or -mibt option to enable CET");
@@ -4948,7 +4953,8 @@  ix86_option_override_internal (bool main_args_p,
 	    }
 	  break;
 	case CF_RETURN:
-	  if (! TARGET_SHSTK_P (opts->x_ix86_isa_flags))
+	  if (!TARGET_SHSTK_P (opts->x_ix86_isa_flags)
+	      && opts->x_flag_cet >= 0)
 	    {
 	      error ("%<-fcf-protection=return%> requires Intel CET "
 		     "support. Use -mcet or -mshstk option to enable CET");
@@ -4957,8 +4963,9 @@  ix86_option_override_internal (bool main_args_p,
 	    }
 	  break;
 	case CF_FULL:
-	  if (   ! TARGET_IBT_P (opts->x_ix86_isa_flags2)
-		 || ! TARGET_SHSTK_P (opts->x_ix86_isa_flags))
+	  if ((!TARGET_IBT_P (opts->x_ix86_isa_flags2)
+	       || !TARGET_SHSTK_P (opts->x_ix86_isa_flags))
+	      && opts->x_flag_cet >= 0)
 	    {
 	      error ("%<-fcf-protection=full%> requires Intel CET "
 		     "support. Use -mcet or both of -mibt and "
@@ -30399,7 +30406,7 @@  ix86_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
   rtx mem, fnaddr;
   int opcode;
   int offset = 0;
-  bool need_endbr = (flag_cf_protection & CF_BRANCH) && TARGET_IBT;
+  bool need_endbr = (flag_cf_protection & CF_BRANCH);
 
   fnaddr = XEXP (DECL_RTL (fndecl), 0);
 
@@ -41757,7 +41764,7 @@  x86_output_mi_thunk (FILE *file, tree, HOST_WIDE_INT delta,
   emit_note (NOTE_INSN_PROLOGUE_END);
 
   /* CET is enabled, insert EB instruction.  */
-  if ((flag_cf_protection & CF_BRANCH) && TARGET_IBT)
+  if ((flag_cf_protection & CF_BRANCH))
     emit_insn (gen_nop_endbr ());
 
   /* If VCALL_OFFSET, we'll need THIS in a register.  Might as well
@@ -49757,7 +49764,7 @@  ix86_bnd_prefixed_insn_p (rtx insn)
 static bool
 ix86_notrack_prefixed_insn_p (rtx insn)
 {
-  if (!insn || !((flag_cf_protection & CF_BRANCH) && TARGET_IBT))
+  if (!insn || !((flag_cf_protection & CF_BRANCH)))
     return false;
 
   if (CALL_P (insn))
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 352212094ec..b7bd71dc3ec 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -20278,7 +20278,7 @@ 
 (define_insn "rdssp<mode>"
   [(set (match_operand:SWI48x 0 "register_operand" "=r")
 	(unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
-  "TARGET_SHSTK"
+  "TARGET_SHSTK || flag_cet"
   "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
   [(set_attr "length" "6")
    (set_attr "type" "other")])
@@ -20286,7 +20286,7 @@ 
 (define_insn "incssp<mode>"
   [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
 		   UNSPECV_INCSSP)]
-  "TARGET_SHSTK"
+  "TARGET_SHSTK || flag_cet"
   "incssp<mskmodesuffix>\t%0"
   [(set_attr "length" "4")
    (set_attr "type" "other")])
@@ -20341,7 +20341,7 @@ 
 
 (define_insn "nop_endbr"
   [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
-  "TARGET_IBT"
+  "TARGET_IBT || flag_cet"
   "*
 { return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }"
   [(set_attr "length" "4")
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index c063ae8b1ae..dea8551bf7f 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -1007,7 +1007,7 @@  Target Report RejectNegative Mask(GENERAL_REGS_ONLY) Var(ix86_target_flags) Save
 Generate code which uses only the general registers.
 
 mcet
-Target Report Var(flag_cet) Init(0)
+Target Report Var(flag_cet) Init(-1)
 Support Control-flow Enforcement Technology (CET) built-in functions
 and code generation.
 
diff --git a/gcc/testsuite/c-c++-common/attr-nocf-check-1.c b/gcc/testsuite/c-c++-common/attr-nocf-check-1.c
index 15f69731b91..c5ac7cb9f86 100644
--- a/gcc/testsuite/c-c++-common/attr-nocf-check-1.c
+++ b/gcc/testsuite/c-c++-common/attr-nocf-check-1.c
@@ -1,4 +1,5 @@ 
 /* { dg-do compile } */
+/* { dg-additional-options "-fcf-protection=none" } */
 
 int func (int) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */
 int (*fptr) (int) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */
diff --git a/gcc/testsuite/c-c++-common/attr-nocf-check-3.c b/gcc/testsuite/c-c++-common/attr-nocf-check-3.c
index ad1ca7eec9b..02b56cb155e 100644
--- a/gcc/testsuite/c-c++-common/attr-nocf-check-3.c
+++ b/gcc/testsuite/c-c++-common/attr-nocf-check-3.c
@@ -1,4 +1,5 @@ 
 /* { dg-do compile } */
+/* { dg-additional-options "-fcf-protection=none" } */
 
 int  foo (void) __attribute__ ((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */
 void (*foo1) (void) __attribute__((nocf_check)); /* { dg-warning "'nocf_check' attribute ignored" } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-1.c b/gcc/testsuite/c-c++-common/fcf-protection-1.c
index 8e71f47dde0..f59a8fbdfdc 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-1.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-1.c
@@ -1,4 +1,3 @@ 
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection=full" } */
-/* { dg-error "'-fcf-protection=full' requires Intel CET.*-mcet.*-mibt and -mshstk option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
 /* { dg-error "'-fcf-protection=full' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-2.c b/gcc/testsuite/c-c++-common/fcf-protection-2.c
index d7d6db0e95d..61059725af6 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-2.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-2.c
@@ -1,4 +1,3 @@ 
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection=branch" } */
-/* { dg-error "'-fcf-protection=branch' requires Intel CET.*-mcet or -mibt option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
 /* { dg-error "'-fcf-protection=branch' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-3.c b/gcc/testsuite/c-c++-common/fcf-protection-3.c
index 5b903c5fa51..257e944c4a6 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-3.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-3.c
@@ -1,4 +1,3 @@ 
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection=return" } */
-/* { dg-error "'-fcf-protection=return' requires Intel CET.*-mcet or -mshstk option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
 /* { dg-error "'-fcf-protection=return' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-5.c b/gcc/testsuite/c-c++-common/fcf-protection-5.c
index d7a67801e2e..dc317f84b07 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-5.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-5.c
@@ -1,4 +1,3 @@ 
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection" } */
-/* { dg-error "'-fcf-protection=full' requires Intel CET.*-mcet.*-mibt and -mshstk option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
 /* { dg-error "'-fcf-protection=full' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-6.c b/gcc/testsuite/c-c++-common/fcf-protection-6.c
index 532e76e6915..a1e919a2f63 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-6.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-6.c
@@ -1,5 +1,4 @@ 
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection=branch" } */
-/* { dg-additional-options "-mshstk" { target { i?86-*-* x86_64-*-* } } } */
-/* { dg-error "'-fcf-protection=branch' requires Intel CET.*-mcet or -mibt option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
+/* { dg-additional-options "-mshstk -mno-ibt" { target { i?86-*-* x86_64-*-* } } } */
 /* { dg-error "'-fcf-protection=branch' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/c-c++-common/fcf-protection-7.c b/gcc/testsuite/c-c++-common/fcf-protection-7.c
index 4c879692708..9e89becdaad 100644
--- a/gcc/testsuite/c-c++-common/fcf-protection-7.c
+++ b/gcc/testsuite/c-c++-common/fcf-protection-7.c
@@ -1,5 +1,4 @@ 
 /* { dg-do compile } */
 /* { dg-options "-fcf-protection=return" } */
-/* { dg-additional-options "-mibt" { target { i?86-*-* x86_64-*-* } } } */
-/* { dg-error "'-fcf-protection=return' requires Intel CET.*-mcet or -mshstk option" "" { target { "i?86-*-* x86_64-*-*" } } 0 } */
+/* { dg-additional-options "-mibt -mno-shstk" { target { i?86-*-* x86_64-*-* } } } */
 /* { dg-error "'-fcf-protection=return' is not supported for this target" "" { target { ! "i?86-*-* x86_64-*-*" } } 0 } */
diff --git a/gcc/testsuite/gcc.dg/march-generic.c b/gcc/testsuite/gcc.dg/march-generic.c
index fb5b83c7d74..f9c00e4a1c1 100644
--- a/gcc/testsuite/gcc.dg/march-generic.c
+++ b/gcc/testsuite/gcc.dg/march-generic.c
@@ -1,6 +1,6 @@ 
 /* { dg-do compile { target i?86-*-* x86_64-*-* } } */
 /* { dg-skip-if "" { *-*-* } { "-march=*" } { "" } } */
-/* { dg-options "-march=generic" } */
+/* { dg-options "-march=generic -fcf-protection=none" } */
 /* { dg-error "'generic' CPU can be used only for '-mtune=' switch" "" { target *-*-* } 0 } */
 /* { dg-bogus "march" "" { target *-*-* } 0 } */
 int i;
diff --git a/gcc/testsuite/gcc.target/i386/align-limit.c b/gcc/testsuite/gcc.target/i386/align-limit.c
index d3d8dc5656e..849d741189c 100644
--- a/gcc/testsuite/gcc.target/i386/align-limit.c
+++ b/gcc/testsuite/gcc.target/i386/align-limit.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O2 -falign-functions=64 -flimit-function-alignment -march=amdfam10" } */
+/* { dg-options "-O2 -falign-functions=64 -flimit-function-alignment -march=amdfam10 -fcf-protection=none" } */
 /* { dg-final { scan-assembler ".p2align 6,,1" } } */
 /* { dg-final { scan-assembler-not ".p2align 6,,63" } } */
 
diff --git a/gcc/testsuite/gcc.target/i386/cet-label-3.c b/gcc/testsuite/gcc.target/i386/cet-label-3.c
new file mode 100644
index 00000000000..ae3ea632a27
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cet-label-3.c
@@ -0,0 +1,16 @@ 
+/* Verify that CET works.  */
+/* { dg-do compile } */
+/* { dg-options "-O -fcf-protection" } */
+/* { dg-final { scan-assembler-times "endbr32" 3 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "endbr64" 3 { target { ! ia32 } } } } */
+
+int func (int arg)
+{
+  static void *array[] = { &&foo, &&bar };
+
+  goto *array[arg];
+foo:
+  return arg*111;
+bar:
+  return arg*777;
+}
diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c
index 7987d53d305..00a3f3e5d5f 100644
--- a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c
+++ b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-1.c
@@ -1,6 +1,6 @@ 
 /* Verify nocf_check functions are not ICF optimized.  */
 /* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -fcf-protection=none -mno-cet" } */
 /* { dg-final { scan-assembler-not "endbr" } } */
 /* { dg-final { scan-assembler-not "fn3:" } } */
 /* { dg-final { scan-assembler "set\[ \t]+fn2,fn1" } } */
diff --git a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c
index 07c4a6b61ef..c8b26f947d3 100644
--- a/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c
+++ b/gcc/testsuite/gcc.target/i386/cet-notrack-icf-3.c
@@ -1,6 +1,6 @@ 
 /* Verify nocf_check function calls are not ICF optimized.  */
 /* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -fcf-protection=none -mno-cet" } */
 /* { dg-final { scan-assembler-not "endbr" } } */
 /* { dg-final { scan-assembler-not "fn2:" } } */
 /* { dg-final { scan-assembler "set\[ \t]+fn2,fn1" } } */
diff --git a/gcc/testsuite/gcc.target/i386/cet-property-2.c b/gcc/testsuite/gcc.target/i386/cet-property-2.c
index 5a87dab92f1..bca6f6cdeb7 100644
--- a/gcc/testsuite/gcc.target/i386/cet-property-2.c
+++ b/gcc/testsuite/gcc.target/i386/cet-property-2.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-mcet" } */
+/* { dg-options "-mcet -fcf-protection=none" } */
 /* { dg-final { scan-assembler-not ".note.gnu.property" } } */
 
 extern void foo (void);
diff --git a/gcc/testsuite/gcc.target/i386/cet-property-3.c b/gcc/testsuite/gcc.target/i386/cet-property-3.c
new file mode 100644
index 00000000000..3e211c970aa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cet-property-3.c
@@ -0,0 +1,11 @@ 
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-fcf-protection" } */
+/* { dg-final { scan-assembler ".note.gnu.property" } } */
+
+extern void foo (void);
+
+void
+bar (void)
+{
+  foo ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/cet-sjlj-7.c b/gcc/testsuite/gcc.target/i386/cet-sjlj-7.c
new file mode 100644
index 00000000000..1b624327d0f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cet-sjlj-7.c
@@ -0,0 +1,48 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O -fcf-protection" } */
+/* { dg-final { scan-assembler-times "endbr32" 2 { target ia32 } } } */
+/* { dg-final { scan-assembler-times "endbr64" 2 { target { ! ia32 } } } } */
+/* { dg-final { scan-assembler-times "call	_?setjmp" 1 } } */
+/* { dg-final { scan-assembler-times "call	longjmp" 1 } } */
+
+#include <stdio.h>
+#include <setjmp.h>
+
+jmp_buf buf;
+static int bar (int);
+
+__attribute__ ((noinline, noclone))
+static int
+foo (int i)
+{
+  int j = i * 11;
+
+  if (!setjmp (buf))
+    {
+      j += 33;
+      printf ("After setjmp: j = %d\n", j);
+      bar (j);
+    }
+
+  return j + i;
+}
+
+__attribute__ ((noinline, noclone))
+static int
+bar (int i)
+{
+ int j = i;
+
+  j -= 111;
+  printf ("In longjmp: j = %d\n", j);
+  longjmp (buf, 1);
+
+  return j;
+}
+
+int
+main ()
+{
+  foo (10);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
index d53fc887dcc..5c120519ad9 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-attr-7.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -fno-pic -fcf-protection=none" } */
 
 void func0 (void);
 void func1 (void);
diff --git a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
index 2b9a33e93dc..74af6198bf4 100644
--- a/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
+++ b/gcc/testsuite/gcc.target/i386/indirect-thunk-extern-7.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic" } */
+/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -fno-pic -fcf-protection=none" } */
 
 void func0 (void);
 void func1 (void);
diff --git a/gcc/testsuite/gcc.target/i386/pr85417-1.c b/gcc/testsuite/gcc.target/i386/pr85417-1.c
new file mode 100644
index 00000000000..ee345961b73
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr85417-1.c
@@ -0,0 +1,4 @@ 
+/* { dg-do compile } */
+/* { dg-options "-march=native -fcf-protection" } */
+
+int foo;
diff --git a/gcc/testsuite/gcc.target/i386/pr85417-2.c b/gcc/testsuite/gcc.target/i386/pr85417-2.c
new file mode 100644
index 00000000000..17d52403744
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr85417-2.c
@@ -0,0 +1,17 @@ 
+/* { dg-do compile } */
+/* { dg-require-ifunc "" } */
+/* { dg-options "-O3 -fcf-protection" } */
+/* { dg-final { scan-assembler "vpshufb" } } */
+/* { dg-final { scan-assembler "punpcklbw" } } */
+
+__attribute__((target_clones("arch=core-avx2","arch=slm","default")))
+void
+foo(char *in, char *out, int size)
+{
+  int i;
+  for(i = 0; i < size; i++)
+    {
+	out[2 * i] = in[i];
+	out[2 * i + 1] = in[i];
+    }
+}
diff --git a/gcc/testsuite/gcc.target/i386/ret-thunk-26.c b/gcc/testsuite/gcc.target/i386/ret-thunk-26.c
index 9144e988735..dc722c2f5f9 100644
--- a/gcc/testsuite/gcc.target/i386/ret-thunk-26.c
+++ b/gcc/testsuite/gcc.target/i386/ret-thunk-26.c
@@ -1,6 +1,6 @@ 
 /* PR target/r84530 */
 /* { dg-do run } */
-/* { dg-options "-Os -mfunction-return=thunk" } */
+/* { dg-options "-Os -mfunction-return=thunk -fcf-protection=none" } */
 
 struct S { int i; };
 __attribute__((const, noinline, noclone))