From d3c4f2673d9606c1e101c20ab42610b733c6ab4e Mon Sep 17 00:00:00 2001
From: Igor Tsimbalist <igor.v.tsimbalist@intel.com>
Date: Fri, 7 Jul 2017 18:33:15 +0300
Subject: [PATCH 07/22] Enable building libgcc with CET options.

Enable building libgcc with CET options by default on Linux/x86 if
binutils supports CET v2.0.
It can be disabled with --disable-cet.  It is an error to configure
GCC with --enable-cet if bintuiils doesn't support CET v2.0.

config/
	* cet.m4: New file

gcc/
	* config.gcc (extra_headers): Add cet.h for Linux/x86 targets.
	* config/i386/cet.h: New file.
	* doc/install.texi: Add --enable-cet/--disable-cet.

libgcc/
	* Makefile.in (configure_deps): Add $(srcdir)/../config/cet.m4.
	(CET_FLAGS): New.
	* config/i386/t-linux
	(HOST_LIBGCC2_CFLAGS): Add $(CET_FLAGS).
	(CRTSTUFF_T_CFLAGS): Add $(CET_FLAGS).
	* configure.ac: Include ../config/cet.m4.
	Set and substitute CET_FLAGS.
	* configure: Regenerated.
---
 config/cet.m4              | 38 ++++++++++++++++++++++++
 gcc/config.gcc             |  1 +
 gcc/config/i386/cet.h      | 74 ++++++++++++++++++++++++++++++++++++++++++++++
 gcc/doc/install.texi       | 13 ++++++++
 libgcc/Makefile.in         |  5 +++-
 libgcc/config/i386/t-linux |  3 +-
 libgcc/configure           | 72 ++++++++++++++++++++++++++++++++++++++++++++
 libgcc/configure.ac        |  4 +++
 8 files changed, 208 insertions(+), 2 deletions(-)
 create mode 100644 config/cet.m4
 create mode 100644 gcc/config/i386/cet.h
 mode change 100644 => 100755 libgcc/configure

diff --git a/config/cet.m4 b/config/cet.m4
new file mode 100644
index 0000000..ca457ee
--- /dev/null
+++ b/config/cet.m4
@@ -0,0 +1,38 @@
+dnl
+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)
+case "$host" in
+  i[34567]86-*-linux* | x86_64-*-linux*)
+    case "$enable_cet" in
+      default)
+	# Check if assembler supports CET.
+	AC_COMPILE_IFELSE(
+	 [AC_LANG_PROGRAM(
+	  [],
+	  [asm ("setssbsy");])],
+	 [enable_cet=yes],
+	 [enable_cet=no])
+	;;
+      yes)
+	# Check if assembler supports CET.
+	AC_COMPILE_IFELSE(
+	 [AC_LANG_PROGRAM(
+	  [],
+	  [asm ("setssbsy");])],
+	 [],
+	 [AC_MSG_ERROR([assembler with CET support is required for --enable-cet])])
+	;;
+    esac
+    ;;
+  *)
+    enable_cet=no
+    ;;
+esac
+if test x$enable_cet = xyes; then
+  $1="-fcf-protection -mcet -include cet.h"
+fi
+])
diff --git a/gcc/config.gcc b/gcc/config.gcc
index cdda262..d2bee8e 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -4548,6 +4548,7 @@ case ${target} in
 		;;
 	i[34567]86-*-linux* | x86_64-*-linux*)
 		extra_objs="${extra_objs} cet.o"
+		extra_headers="${extra_headers} cet.h"
 		tmake_file="$tmake_file i386/t-linux i386/t-cet"
 		;;
 	i[34567]86-*-kfreebsd*-gnu | x86_64-*-kfreebsd*-gnu)
diff --git a/gcc/config/i386/cet.h b/gcc/config/i386/cet.h
new file mode 100644
index 0000000..759f360
--- /dev/null
+++ b/gcc/config/i386/cet.h
@@ -0,0 +1,74 @@
+/* ELF program property for Intel CET.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+   This file is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by the
+   Free Software Foundation; either version 3, or (at your option) any
+   later version.
+
+   This file is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   Under Section 7 of GPL version 3, you are granted additional
+   permissions described in the GCC Runtime Library Exception, version
+   3.1, as published by the Free Software Foundation.
+
+   You should have received a copy of the GNU General Public License and
+   a copy of the GCC Runtime Library Exception along with this program;
+   see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+   <http://www.gnu.org/licenses/>.
+ */
+
+/* Add x86 feature with IBT and/or SHSTK bits to ELF program property
+   if they are enabled.  Otherwise, contents in this header file are
+   unused.  */
+
+#ifdef __ASSEMBLER__
+
+# ifdef __CET__
+#  ifdef __IBT__
+/* GNU_PROPERTY_X86_FEATURE_1_IBT.  */
+#   define __PROPERTY_IBT 0x1
+#  else
+#   define __PROPERTY_IBT 0x0
+#  endif
+
+#  ifdef __SHSTK__
+/* GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */
+#   define __PROPERTY_SHSTK 0x2
+#  else
+#   define __PROPERTY_SHSTK 0x0
+#  endif
+
+#  define __PROPERTY_BITS (__PROPERTY_IBT | __PROPERTY_SHSTK)
+
+#  ifdef __LP64__
+#   define __PROPERTY_ALIGN 3
+#  else
+#   define __PROPERTY_ALIGN 2
+#  endif
+
+	.pushsection ".note.gnu.property", "a"
+	.p2align __PROPERTY_ALIGN
+	.long 1f - 0f		/* name length.  */
+	.long 4f - 1f		/* data length.  */
+	/* NT_GNU_PROPERTY_TYPE_0.   */
+	.long 5			/* note type.  */
+0:
+	.asciz "GNU"		/* vendor name.  */
+1:
+	.p2align __PROPERTY_ALIGN
+	/* GNU_PROPERTY_X86_FEATURE_1_AND.  */
+	.long 0xc0000002	/* pr_type.  */
+	.long 3f - 2f		/* pr_datasz.  */
+2:
+	/* GNU_PROPERTY_X86_FEATURE_1_XXX.  */
+	.long __PROPERTY_BITS
+3:
+	.p2align __PROPERTY_ALIGN
+4:
+	.popsection
+# endif
+#endif
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index da360da..6639eb2 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -2084,6 +2084,19 @@ explicitly specify the directory where they are installed.  The
 shorthand for
 @option{--with-hsa-runtime-lib=@/@var{hsainstalldir}/lib} and
 @option{--with-hsa-runtime-include=@/@var{hsainstalldir}/include}.
+
+@item --enable-cet
+@itemx --disable-cet
+Enable building target run-time libraries with control-flow
+instrumentation, see @option{-fcf-protection} option.  When
+@code{--enable-cet} is specified target libraries are configured
+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.
 @end table
 
 @subheading Cross-Compiler-Specific Options
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index a1a392d..eaa68b5 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -171,7 +171,8 @@ configure_deps = \
 	$(srcdir)/../config/dfp.m4 \
 	$(srcdir)/../config/unwind_ipinfo.m4 \
 	$(srcdir)/../config/gthr.m4 \
-	$(srcdir)/../config/sjlj.m4
+	$(srcdir)/../config/sjlj.m4 \
+	$(srcdir)/../config/cet.m4
 
 $(srcdir)/configure: @MAINT@ $(srcdir)/configure.ac $(configure_deps)
 	cd $(srcdir) && $(AUTOCONF)
@@ -254,6 +255,8 @@ HOST_LIBGCC2_CFLAGS =
 
 PICFLAG = @PICFLAG@
 
+CET_FLAGS = @CET_FLAGS@
+
 # Defined in libgcc2.c, included only in the static library.
 LIB2FUNCS_ST = _eprintf __gcc_bcmp
 
diff --git a/libgcc/config/i386/t-linux b/libgcc/config/i386/t-linux
index 11bb46e..8506a63 100644
--- a/libgcc/config/i386/t-linux
+++ b/libgcc/config/i386/t-linux
@@ -3,4 +3,5 @@
 # t-slibgcc-elf-ver and t-linux
 SHLIB_MAPFILES = libgcc-std.ver $(srcdir)/config/i386/libgcc-glibc.ver
 
-HOST_LIBGCC2_CFLAGS += -mlong-double-80 -DUSE_ELF_SYMVER
+HOST_LIBGCC2_CFLAGS += -mlong-double-80 -DUSE_ELF_SYMVER $(CET_FLAGS)
+CRTSTUFF_T_CFLAGS += $(CET_FLAGS)
diff --git a/libgcc/configure b/libgcc/configure
old mode 100644
new mode 100755
index 15d34b2..078d0d5
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -573,6 +573,7 @@ vis_hide
 real_host_noncanonical
 accel_dir_suffix
 force_explicit_eh_registry
+CET_FLAGS
 fixed_point
 enable_decimal_float
 decimal_float
@@ -675,6 +676,7 @@ with_build_libsubdir
 enable_largefile
 enable_decimal_float
 with_system_libunwind
+enable_cet
 enable_explicit_exception_frame_registration
 with_glibc_version
 enable_tls
@@ -1314,6 +1316,8 @@ Optional Features:
 			enable decimal float extension to C.  Selecting 'bid'
 			or 'dpd' choses which decimal floating point format
 			to use
+  --enable-cet            enable Intel CET in target libraries
+                          [default=default]
   --enable-explicit-exception-frame-registration
                           register exception tables explicitly at module
                           start, for use e.g. for compatibility with
@@ -4773,6 +4777,74 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sjlj_exceptions" >&5
 $as_echo "$ac_cv_sjlj_exceptions" >&6; }
 
+ # Check whether --enable-cet was given.
+if test "${enable_cet+set}" = set; then :
+  enableval=$enable_cet;
+      case "$enableval" in
+       yes|no|default) ;;
+       *) as_fn_error "Unknown argument to enable/disable cet" "$LINENO" 5 ;;
+                          esac
+
+else
+  enable_cet=default
+fi
+
+
+case "$target" in
+  i3456786-*-linux* | x86_64-*-linux*)
+    case "$enable_cet" in
+      default)
+	# Check if assembler supports CET.
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+asm ("setssbsy");
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  enable_cet=yes
+else
+  enable_cet=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+	;;
+      yes)
+	# Check if assembler supports CET.
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+asm ("setssbsy");
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  as_fn_error "assembler with CET support is required for --enable-cet" "$LINENO" 5
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+	;;
+    esac
+    ;;
+  *)
+    enable_cet=no
+    ;;
+esac
+if test x$enable_cet = xyes; then
+  CET_FLAGS="-fcf-protection -mcet -include cet.h"
+fi
+
+
+
 # Check whether --enable-explicit-exception-frame-registration was given.
 if test "${enable_explicit_exception_frame_registration+set}" = set; then :
   enableval=$enable_explicit_exception_frame_registration;
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index da49971..f23661a 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -11,6 +11,7 @@ sinclude(../config/dfp.m4)
 sinclude(../config/unwind_ipinfo.m4)
 sinclude(../config/gthr.m4)
 sinclude(../config/sjlj.m4)
+sinclude(../config/cet.m4)
 
 AC_PREREQ(2.64)
 AC_INIT([GNU C Runtime Library], 1.0,,[libgcc])
@@ -236,6 +237,9 @@ GCC_CHECK_UNWIND_GETIPINFO
 # Check if the compiler is configured for setjmp/longjmp exceptions.
 GCC_CHECK_SJLJ_EXCEPTIONS
 
+GCC_CET_FLAGS(CET_FLAGS)
+AC_SUBST(CET_FLAGS)
+
 AC_ARG_ENABLE([explicit-exception-frame-registration],
   [AC_HELP_STRING([--enable-explicit-exception-frame-registration],
      [register exception tables explicitly at module start, for use
-- 
1.8.3.1

