From b9b58272c5d26d58e553db456a162a0203cf576c Mon Sep 17 00:00:00 2001
From: Igor Tsimbalist <igor.v.tsimbalist@intel.com>
Date: Fri, 15 Dec 2017 19:29:47 +0300
Subject: [PATCH] Add -mcheck-shstk-compat

-fcf-protection -mcet is incompatible with makecontext family functions
since they can't properly set up and destroy shadow stack pointer.  This
change provides a mechanism to help detection shadow stack compatibility.
The current proposal is to add -mcheck-shstk-compat option which will
predefine __CHECK_SHSTK_COMPAT__ macro.  The macro can be used to guard
a code which is not compatible with Intel shadow stack technology.  The
option will be set on by default.  Then we can add the code

 #if defined __SHSTK__ && defined __CHECK_SHSTK_COMPAT__
 # error This source is incompatible with -mshstk
 #endif

to <ucontext.h>.

gcc/
	* config/i386/i386-c.c: Add definition of __CHECK_SHSTK_COMPAT__
	macro.
	* config/i386/i386.opt: Add -mcheck-shstk-compat option.
	* doc/invoke.texi: Add -mcheck-shstk-compat option.
	* testsuite/gcc.target/i386/pr81842-1.c: New test.
	* testsuite/gcc.target/i386/pr81842-2.c: Likewise.
---
 gcc/ChangeLog                             | 8 ++++++++
 gcc/config/i386/i386-c.c                  | 2 ++
 gcc/config/i386/i386.opt                  | 4 ++++
 gcc/doc/invoke.texi                       | 9 +++++++++
 gcc/testsuite/ChangeLog                   | 6 ++++++
 gcc/testsuite/gcc.target/i386/pr81842-1.c | 7 +++++++
 gcc/testsuite/gcc.target/i386/pr81842-2.c | 6 ++++++
 7 files changed, 42 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/i386/pr81842-1.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr81842-2.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a00bff3..6640b95 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2017-12-18  Igor Tsimbalist  <igor.v.tsimbalist@intel.com>
+
+	PR target/81842
+        * config/i386/i386-c.c: Add definition of __CHECK_SHSTK_COMPAT__
+	macro.
+	* config/i386/i386.opt: Add -mcheck-shstk-compat option.
+	* doc/invoke.texi: Add -mcheck-shstk-compat option.
+
 2017-12-11  Bin Cheng  <bin.cheng@arm.com>
 
 	PR tree-optimization/83320
diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c
index fc667a7..c387dbb 100644
--- a/gcc/config/i386/i386-c.c
+++ b/gcc/config/i386/i386-c.c
@@ -479,6 +479,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
   if (isa_flag2 & OPTION_MASK_ISA_SHSTK)
     {
       def_or_undef (parse_in, "__SHSTK__");
+      if (ix86_check_shstk_compat)
+	def_or_undef (parse_in, "__CHECK_SHSTK_COMPAT__");
       if (flag_cf_protection != CF_NONE)
 	def_or_undef (parse_in, "__CET__");
     }
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 6632ba8..9ae3ad6 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -1001,6 +1001,10 @@ Target Report Mask(ISA_SHSTK) Var(ix86_isa_flags2) Save
 Specifically enables an shadow stack support feature from Control-flow
 Enforcment Technology (CET).
 
+mcheck-shstk-compat
+Target Report Var(ix86_check_shstk_compat) Init(1)
+Check shadow stack compatibility
+
 mcet-switch
 Target Report Undocumented Var(flag_cet_switch) Init(0)
 Turn on CET instrumentation for switch statements, which use jump table and
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 1413095..7b4223a 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -26225,6 +26225,15 @@ 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 -mcheck-shstk-compat
+@opindex mcheck-shstk-compat
+This option predefines __CHECK_SHSTK_COMPAT__ macro, which can be used
+to add a guard to the C/C++ sources which are incompatible with Intel
+shadow stack technology.  A typical case would be issuing an error when
+both __SHSTK__ and __CHECK_SHSTK_COMPAT__ macro are defined.  The option
+@option{-mcheck-shstk-compat} is on by default when the @code{-mshstk}
+option is specified.
+
 @item -mcrc32
 @opindex mcrc32
 This option enables built-in functions @code{__builtin_ia32_crc32qi},
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4795a1d..5c361d8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2017-12-18  Igor Tsimbalist  <igor.v.tsimbalist@intel.com>
+
+	PR target/81842
+	* gcc.target/i386/pr81842-1.c: New test.
+	* gcc.target/i386/pr81842-2.c: Likewise.
+
 2017-12-10  Dominique d'Humieres  <dominiq@lps.ens.fr>
 
 	PR fortran/53478
diff --git a/gcc/testsuite/gcc.target/i386/pr81842-1.c b/gcc/testsuite/gcc.target/i386/pr81842-1.c
new file mode 100644
index 0000000..face279
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr81842-1.c
@@ -0,0 +1,7 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-fcf-protection -mcet" } */
+
+#if defined __SHSTK__ && defined __CHECK_SHSTK_COMPAT__
+# error This source is incompatible with -mshstk
+#endif
+/* { dg-error "This source is incompatible with -mshstk" "" { target *-*-* } .-2 } */
diff --git a/gcc/testsuite/gcc.target/i386/pr81842-2.c b/gcc/testsuite/gcc.target/i386/pr81842-2.c
new file mode 100644
index 0000000..ddcf4ce
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr81842-2.c
@@ -0,0 +1,6 @@
+/* { dg-do compile { target *-*-linux* } } */
+/* { dg-options "-fcf-protection -mcet -mno-check-shstk-compat" } */
+
+#if defined __SHSTK__ && defined __CHECK_SHSTK_COMPAT__
+# error This source is incompatible with -mshstk
+#endif
-- 
1.8.3.1

