public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 08/22] Add Intel CET support for EH in libgcc.
@ 2017-10-12 20:01 Tsimbalist, Igor V
  2017-10-12 23:59 ` Hans-Peter Nilsson
  2017-10-31  5:09 ` Jeff Law
  0 siblings, 2 replies; 13+ messages in thread
From: Tsimbalist, Igor V @ 2017-10-12 20:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: Jeff Law, ian, Tsimbalist, Igor V

[-- Attachment #1: Type: text/plain, Size: 1856 bytes --]

Control-flow Enforcement Technology (CET), published by Intel, Introduces
the Shadow Stack feature, which ensures a return from a function is done
to exactly the same location from where the function was called. When EH
is present the control-flow transfer may skip some stack frames and the
shadow stack has to be adjusted not to signal a violation of a
control-flow transfer. It's done by counting a number of skipping frames
and adjusting shadow stack pointer by this number.

gcc/
	* config/i386/i386.c (ix86_expand_epilogue): Change simple
	return to indirect jump for EH return. Change explicit 'false'
	argument in pro_epilogue_adjust_stack with a value of
	flag_cf_protection.
	* config/i386/i386.md (simple_return_indirect_internal): Remove
	SImode restriction to support 64-bit.

libgcc/
	* config/i386/linux-unwind.h: Include
	config/i386/shadow-stack-unwind.h.
	* config/i386/shadow-stack-unwind.h: New file.
	* unwind-dw2.c: (uw_install_context): Add a FRAMES argument and
	pass it to _Unwind_Frames_Extra.
	* unwind-generic.h (FRAMES_P_DECL): New.
	(FRAMES_VAR): Likewise.
	(FRAMES_VAR_P): Likewise.
	(FRAMES_VAR_DECL): Likewise.
	(FRAMES_VAR_DECL_1): Likewise.
	(FRAMES_VAR_INC): Likewise.
	(FRAMES_P_UPDATE): Likewise.
	(_Unwind_Frames_Extra): Likewise.
	* unwind.inc (_Unwind_RaiseException_Phase2): Use FRAMES_P_DECL,
	FRAMES_VAR_DECL_1, FRAMES_VAR_INC and FRAMES_P_UPDATE.
	(_Unwind_RaiseException): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
	FRAMES_VAR.
	(_Unwind_ForcedUnwind_Phase2): Use FRAMES_P_DECL,
	FRAMES_VAR_DECL_1, FRAMES_VAR_INC, FRAMES_P_UPDATE.
	(_Unwind_ForcedUnwind): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
	FRAMES_VAR.
	(_Unwind_Resume): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
	FRAMES_VAR.
	(_Unwind_Resume_or_Rethrow): Use FRAMES_VAR_DECL, FRAMES_VAR_P
	and FRAMES_VAR. 

Igor



[-- Attachment #2: 0008-Add-Intel-CET-support-for-EH-in-libgcc.patch --]
[-- Type: application/octet-stream, Size: 15430 bytes --]

From 16eb1d0d9239e039fba28f1ae71762f19061b157 Mon Sep 17 00:00:00 2001
From: Igor Tsimbalist <igor.v.tsimbalist@intel.com>
Date: Wed, 19 Jul 2017 03:04:46 +0300
Subject: [PATCH 08/22] Add Intel CET support for EH in libgcc.

Control-flow Enforcement Technology (CET), published by Intel,
introduces
the Shadow Stack feature, which ensures a return from a function is done
to exactly the same location from where the function was called. When EH
is present the control-flow transfer may skip some stack frames and the
shadow stack has to be adjusted not to signal a violation of a
control-flow transfer. It's done by counting a number of skiping frames
and adjasting shadow stack pointer by this number.

Having new semantic of the 'ret' instruction if CET is supported in HW
the 'ret' instruction cannot be generated in ix86_expand_epilogue when
we are returning after EH is processed. Added a code in
ix86_expand_epilogue to adjust Shadow Stack pointer and to generate an
indirect jump instead of 'ret'. As sp register is used during this
adjustment thus the argument in pro_epilogue_adjust_stack is changed
to update cfa_reg based on whether control-flow instrumentation is set.
Without updating the cfa_reg field there is an assert later in dwarf2
pass related to mismatch the stack register and cfa_reg value.

gcc/
	* config/i386/i386.c (ix86_expand_epilogue): Change simple
	return to indirect jump for EH return. Change explicit 'false'
	argument in pro_epilogue_adjust_stack with a value of
	flag_cf_protection.
	* config/i386/i386.md (simple_return_indirect_internal): Remove
	SImode restriction to support 64-bit.

libgcc/
	* config/i386/linux-unwind.h: Include
	config/i386/shadow-stack-unwind.h.
	* config/i386/shadow-stack-unwind.h: New file.
	* unwind-dw2.c: (uw_install_context): Add a FRAMES argument and
	pass it to _Unwind_Frames_Extra.
	* unwind-generic.h (FRAMES_P_DECL): New.
	(FRAMES_VAR): Likewise.
	(FRAMES_VAR_P): Likewise.
	(FRAMES_VAR_DECL): Likewise.
	(FRAMES_VAR_DECL_1): Likewise.
	(FRAMES_VAR_INC): Likewise.
	(FRAMES_P_UPDATE): Likewise.
	(_Unwind_Frames_Extra): Likewise.
	* unwind.inc (_Unwind_RaiseException_Phase2): Use FRAMES_P_DECL,
	FRAMES_VAR_DECL_1, FRAMES_VAR_INC and FRAMES_P_UPDATE.
	(_Unwind_RaiseException): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
	FRAMES_VAR.
	(_Unwind_ForcedUnwind_Phase2): Use FRAMES_P_DECL,
	FRAMES_VAR_DECL_1, FRAMES_VAR_INC, FRAMES_P_UPDATE.
	(_Unwind_ForcedUnwind): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
	FRAMES_VAR.
	(_Unwind_Resume): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
	FRAMES_VAR.
	(_Unwind_Resume_or_Rethrow): Use FRAMES_VAR_DECL, FRAMES_VAR_P
	and FRAMES_VAR.

---
 gcc/config/i386/i386.c                   | 34 ++++++++++++++--
 gcc/config/i386/i386.md                  |  2 +-
 libgcc/config/i386/linux-unwind.h        |  5 +++
 libgcc/config/i386/shadow-stack-unwind.h | 66 ++++++++++++++++++++++++++++++++
 libgcc/unwind-dw2.c                      |  3 +-
 libgcc/unwind-generic.h                  | 11 ++++++
 libgcc/unwind.inc                        | 34 ++++++++++------
 7 files changed, 139 insertions(+), 16 deletions(-)
 create mode 100644 libgcc/config/i386/shadow-stack-unwind.h
---
 gcc/config/i386/i386.c                   | 34 ++++++++++++++--
 gcc/config/i386/i386.md                  |  2 +-
 libgcc/config/i386/linux-unwind.h        |  5 +++
 libgcc/config/i386/shadow-stack-unwind.h | 66 ++++++++++++++++++++++++++++++++
 libgcc/unwind-dw2.c                      |  3 +-
 libgcc/unwind-generic.h                  | 11 ++++++
 libgcc/unwind.inc                        | 34 ++++++++++------
 7 files changed, 139 insertions(+), 16 deletions(-)
 create mode 100644 libgcc/config/i386/shadow-stack-unwind.h

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 384c429..1b5deb0 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -15759,7 +15759,9 @@ ix86_expand_epilogue (int style)
 		 offset relative to SA, and after this insn we have no
 		 other reasonable register to use for the CFA.  We don't
 		 bother resetting the CFA to the SP for the duration of
-		 the return insn.  */
+		 the return insn, unless we control flow instrumentation
+		 is done.  In this case the SP is used later and we have
+		 to reset CFA to SP.  */
 	      add_reg_note (insn, REG_CFA_DEF_CFA,
 			    plus_constant (Pmode, sa, UNITS_PER_WORD));
 	      ix86_add_queued_cfa_restore_notes (insn);
@@ -15771,7 +15773,8 @@ ix86_expand_epilogue (int style)
 	      m->fs.fp_valid = false;
 
 	      pro_epilogue_adjust_stack (stack_pointer_rtx, sa,
-					 const0_rtx, style, false);
+					 const0_rtx, style,
+					 flag_cf_protection);
 	    }
 	  else
 	    {
@@ -15955,7 +15958,32 @@ ix86_expand_epilogue (int style)
 	emit_jump_insn (gen_simple_return_pop_internal (popc));
     }
   else if (!m->call_ms2sysv || !restore_stub_is_tail)
-    emit_jump_insn (gen_simple_return_internal ());
+    {
+      /* In case of return from EH a simple return cannot be used
+	 as a return address will be compared with a shadow stack
+	 return address.  Use indirect jump instead.  */
+      if (style == 2 && flag_cf_protection)
+	{
+	  /* Register used in indirect jump must be in word_mode.  But
+	     Pmode may not be the same as word_mode for x32.  */
+	  rtx ecx = gen_rtx_REG (word_mode, CX_REG);
+	  rtx_insn *insn;
+
+	  insn = emit_insn (gen_pop (ecx));
+	  m->fs.cfa_offset -= UNITS_PER_WORD;
+	  m->fs.sp_offset -= UNITS_PER_WORD;
+
+	  rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
+	  x = gen_rtx_SET (stack_pointer_rtx, x);
+	  add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
+	  add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (ecx, pc_rtx));
+	  RTX_FRAME_RELATED_P (insn) = 1;
+
+	  emit_jump_insn (gen_simple_return_indirect_internal (ecx));
+	}
+      else
+	emit_jump_insn (gen_simple_return_internal ());
+    }
 
   /* Restore the state back to the state from the prologue,
      so that it's correct for the next epilogue.  */
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 076a48e..9c77a2b 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -12573,7 +12573,7 @@
 
 (define_insn "simple_return_indirect_internal"
   [(simple_return)
-   (use (match_operand:SI 0 "register_operand" "r"))]
+   (use (match_operand 0 "register_operand" "r"))]
   "reload_completed"
   "%!jmp\t%A0"
   [(set_attr "type" "ibr")
diff --git a/libgcc/config/i386/linux-unwind.h b/libgcc/config/i386/linux-unwind.h
index 2009ad7..c51b4d9 100644
--- a/libgcc/config/i386/linux-unwind.h
+++ b/libgcc/config/i386/linux-unwind.h
@@ -22,6 +22,11 @@ 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/>.  */
 
+/* Unwind shadow stack for -fcf-protection -mshstk.  */
+#if defined __SHSTK__ && defined __CET__
+# include "config/i386/shadow-stack-unwind.h"
+#endif
+
 /* Do code reading to identify a signal frame, and set the frame
    state data appropriately.  See unwind-dw2.c for the structs.
    Don't use this at all if inhibit_libc is used.  */
diff --git a/libgcc/config/i386/shadow-stack-unwind.h b/libgcc/config/i386/shadow-stack-unwind.h
new file mode 100644
index 0000000..c5d0d56
--- /dev/null
+++ b/libgcc/config/i386/shadow-stack-unwind.h
@@ -0,0 +1,66 @@
+/* _Unwind_Frames_Extra with shadow stack for x86-64 and x86.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+GCC 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/>.  */
+
+#ifdef __x86_64__
+# define incssp(x) __builtin_ia32_incsspq ((x))
+# define rdssp(x) __builtin_ia32_rdsspq (x)
+#else
+# define incssp(x) __builtin_ia32_incsspd ((x))
+# define rdssp(x) __builtin_ia32_rdsspd (x)
+#endif
+
+/* Unwind the shadow stack for EH.  */
+#undef _Unwind_Frames_Extra
+#define _Unwind_Frames_Extra(x)			\
+  do						\
+    {						\
+      unsigned long ssp = 0;			\
+      ssp = rdssp (ssp);			\
+      if (ssp != 0)				\
+	{					\
+	  unsigned long tmp = (x);		\
+	  while (tmp > 255)			\
+	    {					\
+	      incssp (tmp);			\
+	      tmp -= 255;			\
+	    }					\
+	  incssp (tmp);				\
+	}					\
+    }						\
+    while (0)
+
+#undef FRAMES_P_DECL
+#undef FRAMES_VAR
+#undef FRAMES_VAR_P
+#undef FRAMES_VAR_DECL
+#undef FRAMES_VAR_DECL_1
+#undef FRAMES_VAR_INC
+#undef FRAMES_P_UPDATE
+#define FRAMES_P_DECL		, unsigned long *frames_p
+#define FRAMES_VAR		frames
+#define FRAMES_VAR_P		, &frames
+#define FRAMES_VAR_DECL		unsigned long frames
+#define FRAMES_VAR_DECL_1	unsigned long frames = 1
+#define FRAMES_VAR_INC		frames++
+#define FRAMES_P_UPDATE		*frames_p = frames
diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
index 3f26eaf..7e9d26b 100644
--- a/libgcc/unwind-dw2.c
+++ b/libgcc/unwind-dw2.c
@@ -1646,12 +1646,13 @@ uw_frob_return_addr (struct _Unwind_Context *current
    macro because __builtin_eh_return must be invoked in the context of
    our caller.  */
 
-#define uw_install_context(CURRENT, TARGET)				\
+#define uw_install_context(CURRENT, TARGET, FRAMES)			\
   do									\
     {									\
       long offset = uw_install_context_1 ((CURRENT), (TARGET));		\
       void *handler = uw_frob_return_addr ((CURRENT), (TARGET));	\
       _Unwind_DebugHook ((TARGET)->cfa, handler);			\
+      _Unwind_Frames_Extra (FRAMES);					\
       __builtin_eh_return (offset, handler);				\
     }									\
   while (0)
diff --git a/libgcc/unwind-generic.h b/libgcc/unwind-generic.h
index 77dd5a9..cb27587 100644
--- a/libgcc/unwind-generic.h
+++ b/libgcc/unwind-generic.h
@@ -288,4 +288,15 @@ EXCEPTION_DISPOSITION _GCC_specific_handler (PEXCEPTION_RECORD, void *,
 #pragma GCC visibility pop
 #endif
 
+#define FRAMES_P_DECL
+#define FRAMES_VAR
+#define FRAMES_VAR_P
+#define FRAMES_VAR_DECL
+#define FRAMES_VAR_DECL_1
+#define FRAMES_VAR_INC
+#define FRAMES_P_UPDATE
+
+/* Additional actions to unwind number of stack frames.  */
+#define _Unwind_Frames_Extra(frames)
+
 #endif /* unwind.h */
diff --git a/libgcc/unwind.inc b/libgcc/unwind.inc
index 658bd94..94b2d4f 100644
--- a/libgcc/unwind.inc
+++ b/libgcc/unwind.inc
@@ -36,9 +36,11 @@
 
 static _Unwind_Reason_Code
 _Unwind_RaiseException_Phase2(struct _Unwind_Exception *exc,
-			      struct _Unwind_Context *context)
+			      struct _Unwind_Context *context
+			      FRAMES_P_DECL)
 {
   _Unwind_Reason_Code code;
+  FRAMES_VAR_DECL_1;
 
   while (1)
     {
@@ -71,8 +73,10 @@ _Unwind_RaiseException_Phase2(struct _Unwind_Exception *exc,
       gcc_assert (!match_handler);
 
       uw_update_context (context, &fs);
+      FRAMES_VAR_INC;
     }
 
+  FRAMES_P_UPDATE;
   return code;
 }
 
@@ -83,6 +87,7 @@ _Unwind_RaiseException(struct _Unwind_Exception *exc)
 {
   struct _Unwind_Context this_context, cur_context;
   _Unwind_Reason_Code code;
+  FRAMES_VAR_DECL;
 
   /* Set up this_context to describe the current stack frame.  */
   uw_init_context (&this_context);
@@ -128,11 +133,11 @@ _Unwind_RaiseException(struct _Unwind_Exception *exc)
   exc->private_2 = uw_identify_context (&cur_context);
 
   cur_context = this_context;
-  code = _Unwind_RaiseException_Phase2 (exc, &cur_context);
+  code = _Unwind_RaiseException_Phase2 (exc, &cur_context FRAMES_VAR_P);
   if (code != _URC_INSTALL_CONTEXT)
     return code;
 
-  uw_install_context (&this_context, &cur_context);
+  uw_install_context (&this_context, &cur_context, FRAMES_VAR);
 }
 
 
@@ -140,11 +145,13 @@ _Unwind_RaiseException(struct _Unwind_Exception *exc)
 
 static _Unwind_Reason_Code
 _Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc,
-			     struct _Unwind_Context *context)
+			     struct _Unwind_Context *context
+			     FRAMES_P_DECL)
 {
   _Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) (_Unwind_Ptr) exc->private_1;
   void *stop_argument = (void *) (_Unwind_Ptr) exc->private_2;
   _Unwind_Reason_Code code, stop_code;
+  FRAMES_VAR_DECL_1;
 
   while (1)
     {
@@ -183,8 +190,10 @@ _Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc,
       /* Update cur_context to describe the same frame as fs, and discard
 	 the previous context if necessary.  */
       uw_advance_context (context, &fs);
+      FRAMES_VAR_INC;
     }
 
+  FRAMES_P_UPDATE;
   return code;
 }
 
@@ -197,6 +206,7 @@ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
 {
   struct _Unwind_Context this_context, cur_context;
   _Unwind_Reason_Code code;
+  FRAMES_VAR_DECL;
 
   uw_init_context (&this_context);
   cur_context = this_context;
@@ -204,11 +214,11 @@ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
   exc->private_1 = (_Unwind_Ptr) stop;
   exc->private_2 = (_Unwind_Ptr) stop_argument;
 
-  code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
+  code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context FRAMES_VAR_P);
   if (code != _URC_INSTALL_CONTEXT)
     return code;
 
-  uw_install_context (&this_context, &cur_context);
+  uw_install_context (&this_context, &cur_context, FRAMES_VAR);
 }
 
 
@@ -220,6 +230,7 @@ _Unwind_Resume (struct _Unwind_Exception *exc)
 {
   struct _Unwind_Context this_context, cur_context;
   _Unwind_Reason_Code code;
+  FRAMES_VAR_DECL;
 
   uw_init_context (&this_context);
   cur_context = this_context;
@@ -227,13 +238,13 @@ _Unwind_Resume (struct _Unwind_Exception *exc)
   /* Choose between continuing to process _Unwind_RaiseException
      or _Unwind_ForcedUnwind.  */
   if (exc->private_1 == 0)
-    code = _Unwind_RaiseException_Phase2 (exc, &cur_context);
+    code = _Unwind_RaiseException_Phase2 (exc, &cur_context FRAMES_VAR_P);
   else
-    code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
+    code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context FRAMES_VAR_P);
 
   gcc_assert (code == _URC_INSTALL_CONTEXT);
 
-  uw_install_context (&this_context, &cur_context);
+  uw_install_context (&this_context, &cur_context, FRAMES_VAR);
 }
 
 
@@ -245,6 +256,7 @@ _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
 {
   struct _Unwind_Context this_context, cur_context;
   _Unwind_Reason_Code code;
+  FRAMES_VAR_DECL;
 
   /* Choose between continuing to process _Unwind_RaiseException
      or _Unwind_ForcedUnwind.  */
@@ -254,11 +266,11 @@ _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
   uw_init_context (&this_context);
   cur_context = this_context;
 
-  code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
+  code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context FRAMES_VAR_P);
 
   gcc_assert (code == _URC_INSTALL_CONTEXT);
 
-  uw_install_context (&this_context, &cur_context);
+  uw_install_context (&this_context, &cur_context, FRAMES_VAR);
 }
 
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 08/22] Add Intel CET support for EH in libgcc.
  2017-10-12 20:01 [PATCH 08/22] Add Intel CET support for EH in libgcc Tsimbalist, Igor V
@ 2017-10-12 23:59 ` Hans-Peter Nilsson
  2017-10-25 17:30   ` H.J. Lu
  2017-10-31  5:09 ` Jeff Law
  1 sibling, 1 reply; 13+ messages in thread
From: Hans-Peter Nilsson @ 2017-10-12 23:59 UTC (permalink / raw)
  To: Tsimbalist, Igor V; +Cc: gcc-patches, Jeff Law, ian

On Thu, 12 Oct 2017, Tsimbalist, Igor V wrote:
> 	* unwind.inc (_Unwind_RaiseException_Phase2): Use FRAMES_P_DECL,
> 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC and FRAMES_P_UPDATE.
> 	(_Unwind_RaiseException): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
> 	FRAMES_VAR.
> 	(_Unwind_ForcedUnwind_Phase2): Use FRAMES_P_DECL,
> 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC, FRAMES_P_UPDATE.
> 	(_Unwind_ForcedUnwind): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
> 	FRAMES_VAR.
> 	(_Unwind_Resume): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
> 	FRAMES_VAR.
> 	(_Unwind_Resume_or_Rethrow): Use FRAMES_VAR_DECL, FRAMES_VAR_P
> 	and FRAMES_VAR.

I think you'll have to test this on a non-CET target too,
because it looks like this won't fly:

-  uw_install_context (&this_context, &cur_context);
+  uw_install_context (&this_context, &cur_context, FRAMES_VAR);

You'll be introducing a naked comma for the default empty
FRAMES_VAR.  I like the basic approach though, FWIW.

brgds, H-P

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 08/22] Add Intel CET support for EH in libgcc.
  2017-10-12 23:59 ` Hans-Peter Nilsson
@ 2017-10-25 17:30   ` H.J. Lu
  0 siblings, 0 replies; 13+ messages in thread
From: H.J. Lu @ 2017-10-25 17:30 UTC (permalink / raw)
  To: Hans-Peter Nilsson; +Cc: Tsimbalist, Igor V, gcc-patches, Jeff Law, ian

On Thu, Oct 12, 2017 at 4:32 PM, Hans-Peter Nilsson <hp@bitrange.com> wrote:
> On Thu, 12 Oct 2017, Tsimbalist, Igor V wrote:
>>       * unwind.inc (_Unwind_RaiseException_Phase2): Use FRAMES_P_DECL,
>>       FRAMES_VAR_DECL_1, FRAMES_VAR_INC and FRAMES_P_UPDATE.
>>       (_Unwind_RaiseException): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
>>       FRAMES_VAR.
>>       (_Unwind_ForcedUnwind_Phase2): Use FRAMES_P_DECL,
>>       FRAMES_VAR_DECL_1, FRAMES_VAR_INC, FRAMES_P_UPDATE.
>>       (_Unwind_ForcedUnwind): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
>>       FRAMES_VAR.
>>       (_Unwind_Resume): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
>>       FRAMES_VAR.
>>       (_Unwind_Resume_or_Rethrow): Use FRAMES_VAR_DECL, FRAMES_VAR_P
>>       and FRAMES_VAR.
>
> I think you'll have to test this on a non-CET target too,
> because it looks like this won't fly:
>
> -  uw_install_context (&this_context, &cur_context);
> +  uw_install_context (&this_context, &cur_context, FRAMES_VAR);
>
> You'll be introducing a naked comma for the default empty

It is done on purpose.   There are

/* Install TARGET into CURRENT so that we can return to it.  This is a
   macro because __builtin_eh_return must be invoked in the context of
   our caller.  */

#define uw_install_context(CURRENT, TARGET, FRAMES)                     \
  do                                                                    \
    {                                                                   \
      long offset = uw_install_context_1 ((CURRENT), (TARGET));         \
      void *handler = uw_frob_return_addr ((CURRENT), (TARGET));        \
      _Unwind_DebugHook ((TARGET)->cfa, handler);                       \
      _Unwind_Frames_Extra (FRAMES);                                    \
      __builtin_eh_return (offset, handler);                            \
    }                                                                   \
  while (0)

For non-CET targets, we have

#define FRAMES_VAR

[hjl@gnu-6 tmp]$ cat bar.c
#define FRAMES_VAR

#define foo(x, FRAMES) _Unwind_Frames_Extra (FRAMES)

foo (xxx, FRAMES_VAR);
[hjl@gnu-6 tmp]$ gcc -E bar.c
# 1 "bar.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "bar.c"




_Unwind_Frames_Extra ();
[hjl@gnu-6 tmp]$


> FRAMES_VAR.  I like the basic approach though, FWIW.
>
> brgds, H-P

Thanks.

-- 
H.J.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 08/22] Add Intel CET support for EH in libgcc.
  2017-10-12 20:01 [PATCH 08/22] Add Intel CET support for EH in libgcc Tsimbalist, Igor V
  2017-10-12 23:59 ` Hans-Peter Nilsson
@ 2017-10-31  5:09 ` Jeff Law
  2017-11-04 12:44   ` Tsimbalist, Igor V
  1 sibling, 1 reply; 13+ messages in thread
From: Jeff Law @ 2017-10-31  5:09 UTC (permalink / raw)
  To: Tsimbalist, Igor V, gcc-patches; +Cc: ian

On 10/12/2017 01:56 PM, Tsimbalist, Igor V wrote:
> Control-flow Enforcement Technology (CET), published by Intel, Introduces
> the Shadow Stack feature, which ensures a return from a function is done
> to exactly the same location from where the function was called. When EH
> is present the control-flow transfer may skip some stack frames and the
> shadow stack has to be adjusted not to signal a violation of a
> control-flow transfer. It's done by counting a number of skipping frames
> and adjusting shadow stack pointer by this number.
> 
> gcc/
> 	* config/i386/i386.c (ix86_expand_epilogue): Change simple
> 	return to indirect jump for EH return. Change explicit 'false'
> 	argument in pro_epilogue_adjust_stack with a value of
> 	flag_cf_protection.
> 	* config/i386/i386.md (simple_return_indirect_internal): Remove
> 	SImode restriction to support 64-bit.
> 
> libgcc/
> 	* config/i386/linux-unwind.h: Include
> 	config/i386/shadow-stack-unwind.h.
> 	* config/i386/shadow-stack-unwind.h: New file.
> 	* unwind-dw2.c: (uw_install_context): Add a FRAMES argument and
> 	pass it to _Unwind_Frames_Extra.
> 	* unwind-generic.h (FRAMES_P_DECL): New.
> 	(FRAMES_VAR): Likewise.
> 	(FRAMES_VAR_P): Likewise.
> 	(FRAMES_VAR_DECL): Likewise.
> 	(FRAMES_VAR_DECL_1): Likewise.
> 	(FRAMES_VAR_INC): Likewise.
> 	(FRAMES_P_UPDATE): Likewise.
> 	(_Unwind_Frames_Extra): Likewise.
> 	* unwind.inc (_Unwind_RaiseException_Phase2): Use FRAMES_P_DECL,
> 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC and FRAMES_P_UPDATE.
> 	(_Unwind_RaiseException): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
> 	FRAMES_VAR.
> 	(_Unwind_ForcedUnwind_Phase2): Use FRAMES_P_DECL,
> 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC, FRAMES_P_UPDATE.
> 	(_Unwind_ForcedUnwind): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
> 	FRAMES_VAR.
> 	(_Unwind_Resume): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
> 	FRAMES_VAR.
> 	(_Unwind_Resume_or_Rethrow): Use FRAMES_VAR_DECL, FRAMES_VAR_P
> 	and FRAMES_VAR. 
> 
> Igor
> 
> 
> 
> 0008-Add-Intel-CET-support-for-EH-in-libgcc.patch
> 
> 
> From 16eb1d0d9239e039fba28f1ae71762f19061b157 Mon Sep 17 00:00:00 2001
> From: Igor Tsimbalist <igor.v.tsimbalist@intel.com>
> Date: Wed, 19 Jul 2017 03:04:46 +0300
> Subject: [PATCH 08/22] Add Intel CET support for EH in libgcc.
> 
> Control-flow Enforcement Technology (CET), published by Intel,
> introduces
> the Shadow Stack feature, which ensures a return from a function is done
> to exactly the same location from where the function was called. When EH
> is present the control-flow transfer may skip some stack frames and the
> shadow stack has to be adjusted not to signal a violation of a
> control-flow transfer. It's done by counting a number of skiping frames
> and adjasting shadow stack pointer by this number.
> 
> Having new semantic of the 'ret' instruction if CET is supported in HW
> the 'ret' instruction cannot be generated in ix86_expand_epilogue when
> we are returning after EH is processed. Added a code in
> ix86_expand_epilogue to adjust Shadow Stack pointer and to generate an
> indirect jump instead of 'ret'. As sp register is used during this
> adjustment thus the argument in pro_epilogue_adjust_stack is changed
> to update cfa_reg based on whether control-flow instrumentation is set.
> Without updating the cfa_reg field there is an assert later in dwarf2
> pass related to mismatch the stack register and cfa_reg value.
> 
> gcc/
> 	* config/i386/i386.c (ix86_expand_epilogue): Change simple
> 	return to indirect jump for EH return. Change explicit 'false'
> 	argument in pro_epilogue_adjust_stack with a value of
> 	flag_cf_protection.
> 	* config/i386/i386.md (simple_return_indirect_internal): Remove
> 	SImode restriction to support 64-bit.
> 
> libgcc/
> 	* config/i386/linux-unwind.h: Include
> 	config/i386/shadow-stack-unwind.h.
> 	* config/i386/shadow-stack-unwind.h: New file.
> 	* unwind-dw2.c: (uw_install_context): Add a FRAMES argument and
> 	pass it to _Unwind_Frames_Extra.
> 	* unwind-generic.h (FRAMES_P_DECL): New.
> 	(FRAMES_VAR): Likewise.
> 	(FRAMES_VAR_P): Likewise.
> 	(FRAMES_VAR_DECL): Likewise.
> 	(FRAMES_VAR_DECL_1): Likewise.
> 	(FRAMES_VAR_INC): Likewise.
> 	(FRAMES_P_UPDATE): Likewise.
> 	(_Unwind_Frames_Extra): Likewise.
> 	* unwind.inc (_Unwind_RaiseException_Phase2): Use FRAMES_P_DECL,
> 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC and FRAMES_P_UPDATE.
> 	(_Unwind_RaiseException): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
> 	FRAMES_VAR.
> 	(_Unwind_ForcedUnwind_Phase2): Use FRAMES_P_DECL,
> 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC, FRAMES_P_UPDATE.
> 	(_Unwind_ForcedUnwind): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
> 	FRAMES_VAR.
> 	(_Unwind_Resume): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
> 	FRAMES_VAR.
> 	(_Unwind_Resume_or_Rethrow): Use FRAMES_VAR_DECL, FRAMES_VAR_P
> 	and FRAMES_VAR.
> 
> 


> diff --git a/libgcc/config/i386/shadow-stack-unwind.h b/libgcc/config/i386/shadow-stack-unwind.h
> new file mode 100644
> index 0000000..c5d0d56
> --- /dev/null
> +++ b/libgcc/config/i386/shadow-stack-unwind.h
> @@ -0,0 +1,66 @@
> +/* _Unwind_Frames_Extra with shadow stack for x86-64 and x86.
> +   Copyright (C) 2017 Free Software Foundation, Inc.
> +
> +This file is part of GCC.
> +
> +GCC 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.
> +
> +GCC 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/>.  */
> +
> +#ifdef __x86_64__
> +# define incssp(x) __builtin_ia32_incsspq ((x))
> +# define rdssp(x) __builtin_ia32_rdsspq (x)
> +#else
> +# define incssp(x) __builtin_ia32_incsspd ((x))
> +# define rdssp(x) __builtin_ia32_rdsspd (x)
> +#endif
> +
> +/* Unwind the shadow stack for EH.  */
> +#undef _Unwind_Frames_Extra
> +#define _Unwind_Frames_Extra(x)			\
> +  do						\
> +    {						\
> +      unsigned long ssp = 0;			\
> +      ssp = rdssp (ssp);			\
> +      if (ssp != 0)				\
> +	{					\
> +	  unsigned long tmp = (x);		\
> +	  while (tmp > 255)			\
> +	    {					\
> +	      incssp (tmp);			\
> +	      tmp -= 255;			\
> +	    }					\
> +	  incssp (tmp);				\
> +	}					\
> +    }						\
> +    while (0)
> +
> +#undef FRAMES_P_DECL
> +#undef FRAMES_VAR
> +#undef FRAMES_VAR_P
> +#undef FRAMES_VAR_DECL
> +#undef FRAMES_VAR_DECL_1
> +#undef FRAMES_VAR_INC
> +#undef FRAMES_P_UPDATE
> +#define FRAMES_P_DECL		, unsigned long *frames_p
> +#define FRAMES_VAR		frames
> +#define FRAMES_VAR_P		, &frames
> +#define FRAMES_VAR_DECL		unsigned long frames
> +#define FRAMES_VAR_DECL_1	unsigned long frames = 1
> +#define FRAMES_VAR_INC		frames++
> +#define FRAMES_P_UPDATE		*frames_p = frames
> diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
> index 3f26eaf..7e9d26b 100644
> --- a/libgcc/unwind-dw2.c
> +++ b/libgcc/unwind-dw2.c
> @@ -1646,12 +1646,13 @@ uw_frob_return_addr (struct _Unwind_Context *current
>     macro because __builtin_eh_return must be invoked in the context of
>     our caller.  */
>  
> -#define uw_install_context(CURRENT, TARGET)				\
> +#define uw_install_context(CURRENT, TARGET, FRAMES)			\
Comment likely needs updating to describe the new parameter.

I must say that I'm not happy with all the macro games we're playing in
this patch.   Is there no cleaner way to get the desired behavior?

Are there any ABI/API implications of this patch?  Ie, does the
signature of any exported function change?

Has this been tested anywhere other than x86/x86_64 linux?


Jeff

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [PATCH 08/22] Add Intel CET support for EH in libgcc.
  2017-10-31  5:09 ` Jeff Law
@ 2017-11-04 12:44   ` Tsimbalist, Igor V
  2017-11-08 19:09     ` Jeff Law
  0 siblings, 1 reply; 13+ messages in thread
From: Tsimbalist, Igor V @ 2017-11-04 12:44 UTC (permalink / raw)
  To: 'Jeff Law', gcc-patches; +Cc: ian, Tsimbalist, Igor V

> -----Original Message-----
> From: Jeff Law [mailto:law@redhat.com]
> Sent: Tuesday, October 31, 2017 5:49 AM
> To: Tsimbalist, Igor V <igor.v.tsimbalist@intel.com>; gcc-
> patches@gcc.gnu.org
> Cc: ian@airs.com
> Subject: Re: [PATCH 08/22] Add Intel CET support for EH in libgcc.
> 
> On 10/12/2017 01:56 PM, Tsimbalist, Igor V wrote:
> > Control-flow Enforcement Technology (CET), published by Intel, Introduces
> > the Shadow Stack feature, which ensures a return from a function is done
> > to exactly the same location from where the function was called. When EH
> > is present the control-flow transfer may skip some stack frames and the
> > shadow stack has to be adjusted not to signal a violation of a
> > control-flow transfer. It's done by counting a number of skipping frames
> > and adjusting shadow stack pointer by this number.
> >
> > gcc/
> > 	* config/i386/i386.c (ix86_expand_epilogue): Change simple
> > 	return to indirect jump for EH return. Change explicit 'false'
> > 	argument in pro_epilogue_adjust_stack with a value of
> > 	flag_cf_protection.
> > 	* config/i386/i386.md (simple_return_indirect_internal): Remove
> > 	SImode restriction to support 64-bit.
> >
> > libgcc/
> > 	* config/i386/linux-unwind.h: Include
> > 	config/i386/shadow-stack-unwind.h.
> > 	* config/i386/shadow-stack-unwind.h: New file.
> > 	* unwind-dw2.c: (uw_install_context): Add a FRAMES argument and
> > 	pass it to _Unwind_Frames_Extra.
> > 	* unwind-generic.h (FRAMES_P_DECL): New.
> > 	(FRAMES_VAR): Likewise.
> > 	(FRAMES_VAR_P): Likewise.
> > 	(FRAMES_VAR_DECL): Likewise.
> > 	(FRAMES_VAR_DECL_1): Likewise.
> > 	(FRAMES_VAR_INC): Likewise.
> > 	(FRAMES_P_UPDATE): Likewise.
> > 	(_Unwind_Frames_Extra): Likewise.
> > 	* unwind.inc (_Unwind_RaiseException_Phase2): Use
> FRAMES_P_DECL,
> > 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC and FRAMES_P_UPDATE.
> > 	(_Unwind_RaiseException): Use FRAMES_VAR_DECL,
> FRAMES_VAR_P and
> > 	FRAMES_VAR.
> > 	(_Unwind_ForcedUnwind_Phase2): Use FRAMES_P_DECL,
> > 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC, FRAMES_P_UPDATE.
> > 	(_Unwind_ForcedUnwind): Use FRAMES_VAR_DECL,
> FRAMES_VAR_P and
> > 	FRAMES_VAR.
> > 	(_Unwind_Resume): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
> > 	FRAMES_VAR.
> > 	(_Unwind_Resume_or_Rethrow): Use FRAMES_VAR_DECL,
> FRAMES_VAR_P
> > 	and FRAMES_VAR.
> >
> > Igor
> >
> >
> >
> > 0008-Add-Intel-CET-support-for-EH-in-libgcc.patch
> >
> >
> > From 16eb1d0d9239e039fba28f1ae71762f19061b157 Mon Sep 17 00:00:00
> 2001
> > From: Igor Tsimbalist <igor.v.tsimbalist@intel.com>
> > Date: Wed, 19 Jul 2017 03:04:46 +0300
> > Subject: [PATCH 08/22] Add Intel CET support for EH in libgcc.
> >
> > Control-flow Enforcement Technology (CET), published by Intel,
> > introduces
> > the Shadow Stack feature, which ensures a return from a function is done
> > to exactly the same location from where the function was called. When EH
> > is present the control-flow transfer may skip some stack frames and the
> > shadow stack has to be adjusted not to signal a violation of a
> > control-flow transfer. It's done by counting a number of skiping frames
> > and adjasting shadow stack pointer by this number.
> >
> > Having new semantic of the 'ret' instruction if CET is supported in HW
> > the 'ret' instruction cannot be generated in ix86_expand_epilogue when
> > we are returning after EH is processed. Added a code in
> > ix86_expand_epilogue to adjust Shadow Stack pointer and to generate an
> > indirect jump instead of 'ret'. As sp register is used during this
> > adjustment thus the argument in pro_epilogue_adjust_stack is changed
> > to update cfa_reg based on whether control-flow instrumentation is set.
> > Without updating the cfa_reg field there is an assert later in dwarf2
> > pass related to mismatch the stack register and cfa_reg value.
> >
> > gcc/
> > 	* config/i386/i386.c (ix86_expand_epilogue): Change simple
> > 	return to indirect jump for EH return. Change explicit 'false'
> > 	argument in pro_epilogue_adjust_stack with a value of
> > 	flag_cf_protection.
> > 	* config/i386/i386.md (simple_return_indirect_internal): Remove
> > 	SImode restriction to support 64-bit.
> >
> > libgcc/
> > 	* config/i386/linux-unwind.h: Include
> > 	config/i386/shadow-stack-unwind.h.
> > 	* config/i386/shadow-stack-unwind.h: New file.
> > 	* unwind-dw2.c: (uw_install_context): Add a FRAMES argument and
> > 	pass it to _Unwind_Frames_Extra.
> > 	* unwind-generic.h (FRAMES_P_DECL): New.
> > 	(FRAMES_VAR): Likewise.
> > 	(FRAMES_VAR_P): Likewise.
> > 	(FRAMES_VAR_DECL): Likewise.
> > 	(FRAMES_VAR_DECL_1): Likewise.
> > 	(FRAMES_VAR_INC): Likewise.
> > 	(FRAMES_P_UPDATE): Likewise.
> > 	(_Unwind_Frames_Extra): Likewise.
> > 	* unwind.inc (_Unwind_RaiseException_Phase2): Use
> FRAMES_P_DECL,
> > 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC and FRAMES_P_UPDATE.
> > 	(_Unwind_RaiseException): Use FRAMES_VAR_DECL,
> FRAMES_VAR_P and
> > 	FRAMES_VAR.
> > 	(_Unwind_ForcedUnwind_Phase2): Use FRAMES_P_DECL,
> > 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC, FRAMES_P_UPDATE.
> > 	(_Unwind_ForcedUnwind): Use FRAMES_VAR_DECL,
> FRAMES_VAR_P and
> > 	FRAMES_VAR.
> > 	(_Unwind_Resume): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
> > 	FRAMES_VAR.
> > 	(_Unwind_Resume_or_Rethrow): Use FRAMES_VAR_DECL,
> FRAMES_VAR_P
> > 	and FRAMES_VAR.
> >
> >
> 
> 
> > diff --git a/libgcc/config/i386/shadow-stack-unwind.h
> b/libgcc/config/i386/shadow-stack-unwind.h
> > new file mode 100644
> > index 0000000..c5d0d56
> > --- /dev/null
> > +++ b/libgcc/config/i386/shadow-stack-unwind.h
> > @@ -0,0 +1,66 @@
> > +/* _Unwind_Frames_Extra with shadow stack for x86-64 and x86.
> > +   Copyright (C) 2017 Free Software Foundation, Inc.
> > +
> > +This file is part of GCC.
> > +
> > +GCC 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.
> > +
> > +GCC 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/>.  */
> > +
> > +#ifdef __x86_64__
> > +# define incssp(x) __builtin_ia32_incsspq ((x))
> > +# define rdssp(x) __builtin_ia32_rdsspq (x)
> > +#else
> > +# define incssp(x) __builtin_ia32_incsspd ((x))
> > +# define rdssp(x) __builtin_ia32_rdsspd (x)
> > +#endif
> > +
> > +/* Unwind the shadow stack for EH.  */
> > +#undef _Unwind_Frames_Extra
> > +#define _Unwind_Frames_Extra(x)			\
> > +  do						\
> > +    {						\
> > +      unsigned long ssp = 0;			\
> > +      ssp = rdssp (ssp);			\
> > +      if (ssp != 0)				\
> > +	{					\
> > +	  unsigned long tmp = (x);		\
> > +	  while (tmp > 255)			\
> > +	    {					\
> > +	      incssp (tmp);			\
> > +	      tmp -= 255;			\
> > +	    }					\
> > +	  incssp (tmp);				\
> > +	}					\
> > +    }						\
> > +    while (0)
> > +
> > +#undef FRAMES_P_DECL
> > +#undef FRAMES_VAR
> > +#undef FRAMES_VAR_P
> > +#undef FRAMES_VAR_DECL
> > +#undef FRAMES_VAR_DECL_1
> > +#undef FRAMES_VAR_INC
> > +#undef FRAMES_P_UPDATE
> > +#define FRAMES_P_DECL		, unsigned long *frames_p
> > +#define FRAMES_VAR		frames
> > +#define FRAMES_VAR_P		, &frames
> > +#define FRAMES_VAR_DECL		unsigned long frames
> > +#define FRAMES_VAR_DECL_1	unsigned long frames = 1
> > +#define FRAMES_VAR_INC		frames++
> > +#define FRAMES_P_UPDATE		*frames_p = frames
> > diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
> > index 3f26eaf..7e9d26b 100644
> > --- a/libgcc/unwind-dw2.c
> > +++ b/libgcc/unwind-dw2.c
> > @@ -1646,12 +1646,13 @@ uw_frob_return_addr (struct
> _Unwind_Context *current
> >     macro because __builtin_eh_return must be invoked in the context of
> >     our caller.  */
> >
> > -#define uw_install_context(CURRENT, TARGET)
> 	\
> > +#define uw_install_context(CURRENT, TARGET, FRAMES)
> 	\
> Comment likely needs updating to describe the new parameter.

Updated.

-   our caller.  */
+   our caller.  FRAMES is a number of frames to be unwind.
+   _Unwind_Frames_Extra is a macro to do additional work during unwinding
+   if needed, for example shadow stack pointer adjustment for Intel CET
+   technology.  */

> I must say that I'm not happy with all the macro games we're playing in
> this patch.   Is there no cleaner way to get the desired behavior?
> 
> Are there any ABI/API implications of this patch?  Ie, does the
> signature of any exported function change?

There is no ABI/API implications. It's done through macro to keep existing infrastructure
and functions. Otherwise a copy of unwind functions have to be introduced and modified
 for CET support.

> Has this been tested anywhere other than x86/x86_64 linux?

Yes, I tested it on arm64 system. I applied 2 patches, previous 07/22 and this one 08/22. Everything
was built successfully. Further to the building I did testing also. No new fails.


Igor

> 
> Jeff

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 08/22] Add Intel CET support for EH in libgcc.
  2017-11-04 12:44   ` Tsimbalist, Igor V
@ 2017-11-08 19:09     ` Jeff Law
  2017-11-08 19:11       ` H.J. Lu
  2017-11-08 22:06       ` Tsimbalist, Igor V
  0 siblings, 2 replies; 13+ messages in thread
From: Jeff Law @ 2017-11-08 19:09 UTC (permalink / raw)
  To: Tsimbalist, Igor V, gcc-patches; +Cc: ian

On 11/04/2017 06:43 AM, Tsimbalist, Igor V wrote:
>> -----Original Message-----
>> From: Jeff Law [mailto:law@redhat.com]
>> Sent: Tuesday, October 31, 2017 5:49 AM
>> To: Tsimbalist, Igor V <igor.v.tsimbalist@intel.com>; gcc-
>> patches@gcc.gnu.org
>> Cc: ian@airs.com
>> Subject: Re: [PATCH 08/22] Add Intel CET support for EH in libgcc.
>>
>> On 10/12/2017 01:56 PM, Tsimbalist, Igor V wrote:
>>> Control-flow Enforcement Technology (CET), published by Intel, Introduces
>>> the Shadow Stack feature, which ensures a return from a function is done
>>> to exactly the same location from where the function was called. When EH
>>> is present the control-flow transfer may skip some stack frames and the
>>> shadow stack has to be adjusted not to signal a violation of a
>>> control-flow transfer. It's done by counting a number of skipping frames
>>> and adjusting shadow stack pointer by this number.
>>>
>>> gcc/
>>> 	* config/i386/i386.c (ix86_expand_epilogue): Change simple
>>> 	return to indirect jump for EH return. Change explicit 'false'
>>> 	argument in pro_epilogue_adjust_stack with a value of
>>> 	flag_cf_protection.
>>> 	* config/i386/i386.md (simple_return_indirect_internal): Remove
>>> 	SImode restriction to support 64-bit.
>>>
>>> libgcc/
>>> 	* config/i386/linux-unwind.h: Include
>>> 	config/i386/shadow-stack-unwind.h.
>>> 	* config/i386/shadow-stack-unwind.h: New file.
>>> 	* unwind-dw2.c: (uw_install_context): Add a FRAMES argument and
>>> 	pass it to _Unwind_Frames_Extra.
>>> 	* unwind-generic.h (FRAMES_P_DECL): New.
>>> 	(FRAMES_VAR): Likewise.
>>> 	(FRAMES_VAR_P): Likewise.
>>> 	(FRAMES_VAR_DECL): Likewise.
>>> 	(FRAMES_VAR_DECL_1): Likewise.
>>> 	(FRAMES_VAR_INC): Likewise.
>>> 	(FRAMES_P_UPDATE): Likewise.
>>> 	(_Unwind_Frames_Extra): Likewise.
>>> 	* unwind.inc (_Unwind_RaiseException_Phase2): Use
>> FRAMES_P_DECL,
>>> 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC and FRAMES_P_UPDATE.
>>> 	(_Unwind_RaiseException): Use FRAMES_VAR_DECL,
>> FRAMES_VAR_P and
>>> 	FRAMES_VAR.
>>> 	(_Unwind_ForcedUnwind_Phase2): Use FRAMES_P_DECL,
>>> 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC, FRAMES_P_UPDATE.
>>> 	(_Unwind_ForcedUnwind): Use FRAMES_VAR_DECL,
>> FRAMES_VAR_P and
>>> 	FRAMES_VAR.
>>> 	(_Unwind_Resume): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
>>> 	FRAMES_VAR.
>>> 	(_Unwind_Resume_or_Rethrow): Use FRAMES_VAR_DECL,
>> FRAMES_VAR_P
>>> 	and FRAMES_VAR.
>>>
>>> Igor
>>>
>>>
>>>
>>> 0008-Add-Intel-CET-support-for-EH-in-libgcc.patch
>>>
>>>
>>> From 16eb1d0d9239e039fba28f1ae71762f19061b157 Mon Sep 17 00:00:00
>> 2001
>>> From: Igor Tsimbalist <igor.v.tsimbalist@intel.com>
>>> Date: Wed, 19 Jul 2017 03:04:46 +0300
>>> Subject: [PATCH 08/22] Add Intel CET support for EH in libgcc.
>>>
>>> Control-flow Enforcement Technology (CET), published by Intel,
>>> introduces
>>> the Shadow Stack feature, which ensures a return from a function is done
>>> to exactly the same location from where the function was called. When EH
>>> is present the control-flow transfer may skip some stack frames and the
>>> shadow stack has to be adjusted not to signal a violation of a
>>> control-flow transfer. It's done by counting a number of skiping frames
>>> and adjasting shadow stack pointer by this number.
>>>
>>> Having new semantic of the 'ret' instruction if CET is supported in HW
>>> the 'ret' instruction cannot be generated in ix86_expand_epilogue when
>>> we are returning after EH is processed. Added a code in
>>> ix86_expand_epilogue to adjust Shadow Stack pointer and to generate an
>>> indirect jump instead of 'ret'. As sp register is used during this
>>> adjustment thus the argument in pro_epilogue_adjust_stack is changed
>>> to update cfa_reg based on whether control-flow instrumentation is set.
>>> Without updating the cfa_reg field there is an assert later in dwarf2
>>> pass related to mismatch the stack register and cfa_reg value.
>>>
>>> gcc/
>>> 	* config/i386/i386.c (ix86_expand_epilogue): Change simple
>>> 	return to indirect jump for EH return. Change explicit 'false'
>>> 	argument in pro_epilogue_adjust_stack with a value of
>>> 	flag_cf_protection.
>>> 	* config/i386/i386.md (simple_return_indirect_internal): Remove
>>> 	SImode restriction to support 64-bit.
>>>
>>> libgcc/
>>> 	* config/i386/linux-unwind.h: Include
>>> 	config/i386/shadow-stack-unwind.h.
>>> 	* config/i386/shadow-stack-unwind.h: New file.
>>> 	* unwind-dw2.c: (uw_install_context): Add a FRAMES argument and
>>> 	pass it to _Unwind_Frames_Extra.
>>> 	* unwind-generic.h (FRAMES_P_DECL): New.
>>> 	(FRAMES_VAR): Likewise.
>>> 	(FRAMES_VAR_P): Likewise.
>>> 	(FRAMES_VAR_DECL): Likewise.
>>> 	(FRAMES_VAR_DECL_1): Likewise.
>>> 	(FRAMES_VAR_INC): Likewise.
>>> 	(FRAMES_P_UPDATE): Likewise.
>>> 	(_Unwind_Frames_Extra): Likewise.
>>> 	* unwind.inc (_Unwind_RaiseException_Phase2): Use
>> FRAMES_P_DECL,
>>> 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC and FRAMES_P_UPDATE.
>>> 	(_Unwind_RaiseException): Use FRAMES_VAR_DECL,
>> FRAMES_VAR_P and
>>> 	FRAMES_VAR.
>>> 	(_Unwind_ForcedUnwind_Phase2): Use FRAMES_P_DECL,
>>> 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC, FRAMES_P_UPDATE.
>>> 	(_Unwind_ForcedUnwind): Use FRAMES_VAR_DECL,
>> FRAMES_VAR_P and
>>> 	FRAMES_VAR.
>>> 	(_Unwind_Resume): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
>>> 	FRAMES_VAR.
>>> 	(_Unwind_Resume_or_Rethrow): Use FRAMES_VAR_DECL,
>> FRAMES_VAR_P
>>> 	and FRAMES_VAR.
>>>
>>>
>>

>> I must say that I'm not happy with all the macro games we're playing in
>> this patch.   Is there no cleaner way to get the desired behavior?
>>
>> Are there any ABI/API implications of this patch?  Ie, does the
>> signature of any exported function change?
> There is no ABI/API implications. It's done through macro to keep existing infrastructure
> and functions. Otherwise a copy of unwind functions have to be introduced and modified
>  for CET support.
It just seems to me there ought to be a way to handle this without
making a copy and without the macro games.

So for example, why can't we make the handling of FRAMES_VAR_*
unconditional.  Just go ahead and declare the local variable and compute
it.  Pass its address to Unwind_RaiseException_Phase2 unconditionally.
The parameter might need to be marked as ATTRIBUTE_UNUSED.

Then the only macro games we need is _Unwind_Frames_Extra.

We end up with some potentially dead code at the source level (for cases
where _Unwind_Frames_Extra does nothing).  Ideally the IPA bits would
realize the code is dead and specialize UnwindRaiseException_Phase2
removing the unnecessary overhead.  But even if IPA didn't do that I
think the result is just so  much cleaner that a bit of overhead on the
exception/unwinding path is warranted.

> 
>> Has this been tested anywhere other than x86/x86_64 linux?
> Yes, I tested it on arm64 system. I applied 2 patches, previous 07/22 and this one 08/22. Everything
> was built successfully. Further to the building I did testing also. No new fails.
So how does that reconcile with H-P's note about the calls to
uw_install_context when FRAMES_VAR is defined as nothinng?

+  uw_install_context (&this_context, &cur_context, FRAMES_VAR);

Doesn't that create a syntax error when FRAMES_VAR is defined, but with
no content?

Jeff

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 08/22] Add Intel CET support for EH in libgcc.
  2017-11-08 19:09     ` Jeff Law
@ 2017-11-08 19:11       ` H.J. Lu
  2017-11-08 22:06       ` Tsimbalist, Igor V
  1 sibling, 0 replies; 13+ messages in thread
From: H.J. Lu @ 2017-11-08 19:11 UTC (permalink / raw)
  To: Jeff Law; +Cc: Tsimbalist, Igor V, gcc-patches, ian

>>
>>> Has this been tested anywhere other than x86/x86_64 linux?
>> Yes, I tested it on arm64 system. I applied 2 patches, previous 07/22 and this one 08/22. Everything
>> was built successfully. Further to the building I did testing also. No new fails.
> So how does that reconcile with H-P's note about the calls to
> uw_install_context when FRAMES_VAR is defined as nothinng?
>
> +  uw_install_context (&this_context, &cur_context, FRAMES_VAR);
>
> Doesn't that create a syntax error when FRAMES_VAR is defined, but with
> no content?
>

From:

https://gcc.gnu.org/ml/gcc-patches/2017-10/msg01832.html



It is done on purpose.   There are

/* Install TARGET into CURRENT so that we can return to it.  This is a
   macro because __builtin_eh_return must be invoked in the context of
   our caller.  */

#define uw_install_context(CURRENT, TARGET, FRAMES)                     \
  do                                                                    \
    {                                                                   \
      long offset = uw_install_context_1 ((CURRENT), (TARGET));         \
      void *handler = uw_frob_return_addr ((CURRENT), (TARGET));        \
      _Unwind_DebugHook ((TARGET)->cfa, handler);                       \
      _Unwind_Frames_Extra (FRAMES);                                    \
      __builtin_eh_return (offset, handler);                            \
    }                                                                   \
  while (0)

For non-CET targets, we have

#define FRAMES_VAR

[hjl@gnu-6 tmp]$ cat bar.c
#define FRAMES_VAR

#define foo(x, FRAMES) _Unwind_Frames_Extra (FRAMES)

foo (xxx, FRAMES_VAR);
[hjl@gnu-6 tmp]$ gcc -E bar.c
# 1 "bar.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 31 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 32 "<command-line>" 2
# 1 "bar.c"




_Unwind_Frames_Extra ();
[hjl@gnu-6 tmp]$


-- 
H.J.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [PATCH 08/22] Add Intel CET support for EH in libgcc.
  2017-11-08 19:09     ` Jeff Law
  2017-11-08 19:11       ` H.J. Lu
@ 2017-11-08 22:06       ` Tsimbalist, Igor V
  2017-11-13 22:16         ` Tsimbalist, Igor V
  1 sibling, 1 reply; 13+ messages in thread
From: Tsimbalist, Igor V @ 2017-11-08 22:06 UTC (permalink / raw)
  To: Jeff Law, gcc-patches; +Cc: ian, Tsimbalist, Igor V

> -----Original Message-----
> From: Jeff Law [mailto:law@redhat.com]
> Sent: Wednesday, November 8, 2017 8:06 PM
> To: Tsimbalist, Igor V <igor.v.tsimbalist@intel.com>; gcc-
> patches@gcc.gnu.org
> Cc: ian@airs.com
> Subject: Re: [PATCH 08/22] Add Intel CET support for EH in libgcc.
> 
> On 11/04/2017 06:43 AM, Tsimbalist, Igor V wrote:
> >> -----Original Message-----
> >> From: Jeff Law [mailto:law@redhat.com]
> >> Sent: Tuesday, October 31, 2017 5:49 AM
> >> To: Tsimbalist, Igor V <igor.v.tsimbalist@intel.com>; gcc-
> >> patches@gcc.gnu.org
> >> Cc: ian@airs.com
> >> Subject: Re: [PATCH 08/22] Add Intel CET support for EH in libgcc.
> >>
> >> On 10/12/2017 01:56 PM, Tsimbalist, Igor V wrote:
> >>> Control-flow Enforcement Technology (CET), published by Intel,
> Introduces
> >>> the Shadow Stack feature, which ensures a return from a function is
> done
> >>> to exactly the same location from where the function was called. When
> EH
> >>> is present the control-flow transfer may skip some stack frames and the
> >>> shadow stack has to be adjusted not to signal a violation of a
> >>> control-flow transfer. It's done by counting a number of skipping frames
> >>> and adjusting shadow stack pointer by this number.
> >>>
> >>> gcc/
> >>> 	* config/i386/i386.c (ix86_expand_epilogue): Change simple
> >>> 	return to indirect jump for EH return. Change explicit 'false'
> >>> 	argument in pro_epilogue_adjust_stack with a value of
> >>> 	flag_cf_protection.
> >>> 	* config/i386/i386.md (simple_return_indirect_internal): Remove
> >>> 	SImode restriction to support 64-bit.
> >>>
> >>> libgcc/
> >>> 	* config/i386/linux-unwind.h: Include
> >>> 	config/i386/shadow-stack-unwind.h.
> >>> 	* config/i386/shadow-stack-unwind.h: New file.
> >>> 	* unwind-dw2.c: (uw_install_context): Add a FRAMES argument and
> >>> 	pass it to _Unwind_Frames_Extra.
> >>> 	* unwind-generic.h (FRAMES_P_DECL): New.
> >>> 	(FRAMES_VAR): Likewise.
> >>> 	(FRAMES_VAR_P): Likewise.
> >>> 	(FRAMES_VAR_DECL): Likewise.
> >>> 	(FRAMES_VAR_DECL_1): Likewise.
> >>> 	(FRAMES_VAR_INC): Likewise.
> >>> 	(FRAMES_P_UPDATE): Likewise.
> >>> 	(_Unwind_Frames_Extra): Likewise.
> >>> 	* unwind.inc (_Unwind_RaiseException_Phase2): Use
> >> FRAMES_P_DECL,
> >>> 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC and FRAMES_P_UPDATE.
> >>> 	(_Unwind_RaiseException): Use FRAMES_VAR_DECL,
> >> FRAMES_VAR_P and
> >>> 	FRAMES_VAR.
> >>> 	(_Unwind_ForcedUnwind_Phase2): Use FRAMES_P_DECL,
> >>> 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC, FRAMES_P_UPDATE.
> >>> 	(_Unwind_ForcedUnwind): Use FRAMES_VAR_DECL,
> >> FRAMES_VAR_P and
> >>> 	FRAMES_VAR.
> >>> 	(_Unwind_Resume): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
> >>> 	FRAMES_VAR.
> >>> 	(_Unwind_Resume_or_Rethrow): Use FRAMES_VAR_DECL,
> >> FRAMES_VAR_P
> >>> 	and FRAMES_VAR.
> >>>
> >>> Igor
> >>>
> >>>
> >>>
> >>> 0008-Add-Intel-CET-support-for-EH-in-libgcc.patch
> >>>
> >>>
> >>> From 16eb1d0d9239e039fba28f1ae71762f19061b157 Mon Sep 17
> 00:00:00
> >> 2001
> >>> From: Igor Tsimbalist <igor.v.tsimbalist@intel.com>
> >>> Date: Wed, 19 Jul 2017 03:04:46 +0300
> >>> Subject: [PATCH 08/22] Add Intel CET support for EH in libgcc.
> >>>
> >>> Control-flow Enforcement Technology (CET), published by Intel,
> >>> introduces
> >>> the Shadow Stack feature, which ensures a return from a function is
> done
> >>> to exactly the same location from where the function was called. When
> EH
> >>> is present the control-flow transfer may skip some stack frames and the
> >>> shadow stack has to be adjusted not to signal a violation of a
> >>> control-flow transfer. It's done by counting a number of skiping frames
> >>> and adjasting shadow stack pointer by this number.
> >>>
> >>> Having new semantic of the 'ret' instruction if CET is supported in HW
> >>> the 'ret' instruction cannot be generated in ix86_expand_epilogue when
> >>> we are returning after EH is processed. Added a code in
> >>> ix86_expand_epilogue to adjust Shadow Stack pointer and to generate
> an
> >>> indirect jump instead of 'ret'. As sp register is used during this
> >>> adjustment thus the argument in pro_epilogue_adjust_stack is changed
> >>> to update cfa_reg based on whether control-flow instrumentation is set.
> >>> Without updating the cfa_reg field there is an assert later in dwarf2
> >>> pass related to mismatch the stack register and cfa_reg value.
> >>>
> >>> gcc/
> >>> 	* config/i386/i386.c (ix86_expand_epilogue): Change simple
> >>> 	return to indirect jump for EH return. Change explicit 'false'
> >>> 	argument in pro_epilogue_adjust_stack with a value of
> >>> 	flag_cf_protection.
> >>> 	* config/i386/i386.md (simple_return_indirect_internal): Remove
> >>> 	SImode restriction to support 64-bit.
> >>>
> >>> libgcc/
> >>> 	* config/i386/linux-unwind.h: Include
> >>> 	config/i386/shadow-stack-unwind.h.
> >>> 	* config/i386/shadow-stack-unwind.h: New file.
> >>> 	* unwind-dw2.c: (uw_install_context): Add a FRAMES argument and
> >>> 	pass it to _Unwind_Frames_Extra.
> >>> 	* unwind-generic.h (FRAMES_P_DECL): New.
> >>> 	(FRAMES_VAR): Likewise.
> >>> 	(FRAMES_VAR_P): Likewise.
> >>> 	(FRAMES_VAR_DECL): Likewise.
> >>> 	(FRAMES_VAR_DECL_1): Likewise.
> >>> 	(FRAMES_VAR_INC): Likewise.
> >>> 	(FRAMES_P_UPDATE): Likewise.
> >>> 	(_Unwind_Frames_Extra): Likewise.
> >>> 	* unwind.inc (_Unwind_RaiseException_Phase2): Use
> >> FRAMES_P_DECL,
> >>> 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC and FRAMES_P_UPDATE.
> >>> 	(_Unwind_RaiseException): Use FRAMES_VAR_DECL,
> >> FRAMES_VAR_P and
> >>> 	FRAMES_VAR.
> >>> 	(_Unwind_ForcedUnwind_Phase2): Use FRAMES_P_DECL,
> >>> 	FRAMES_VAR_DECL_1, FRAMES_VAR_INC, FRAMES_P_UPDATE.
> >>> 	(_Unwind_ForcedUnwind): Use FRAMES_VAR_DECL,
> >> FRAMES_VAR_P and
> >>> 	FRAMES_VAR.
> >>> 	(_Unwind_Resume): Use FRAMES_VAR_DECL, FRAMES_VAR_P and
> >>> 	FRAMES_VAR.
> >>> 	(_Unwind_Resume_or_Rethrow): Use FRAMES_VAR_DECL,
> >> FRAMES_VAR_P
> >>> 	and FRAMES_VAR.
> >>>
> >>>
> >>
> 
> >> I must say that I'm not happy with all the macro games we're playing in
> >> this patch.   Is there no cleaner way to get the desired behavior?
> >>
> >> Are there any ABI/API implications of this patch?  Ie, does the
> >> signature of any exported function change?
> > There is no ABI/API implications. It's done through macro to keep existing
> infrastructure
> > and functions. Otherwise a copy of unwind functions have to be introduced
> and modified
> >  for CET support.
> It just seems to me there ought to be a way to handle this without
> making a copy and without the macro games.
> 
> So for example, why can't we make the handling of FRAMES_VAR_*
> unconditional.  Just go ahead and declare the local variable and compute
> it.  Pass its address to Unwind_RaiseException_Phase2 unconditionally.
> The parameter might need to be marked as ATTRIBUTE_UNUSED.
> 
> Then the only macro games we need is _Unwind_Frames_Extra.
> 
> We end up with some potentially dead code at the source level (for cases
> where _Unwind_Frames_Extra does nothing).  Ideally the IPA bits would
> realize the code is dead and specialize UnwindRaiseException_Phase2
> removing the unnecessary overhead.  But even if IPA didn't do that I
> think the result is just so  much cleaner that a bit of overhead on the
> exception/unwinding path is warranted.

Ok, I will implement your suggestion. I agree that is cleaner.

> >
> >> Has this been tested anywhere other than x86/x86_64 linux?
> > Yes, I tested it on arm64 system. I applied 2 patches, previous 07/22 and
> this one 08/22. Everything
> > was built successfully. Further to the building I did testing also. No new
> fails.
> So how does that reconcile with H-P's note about the calls to
> uw_install_context when FRAMES_VAR is defined as nothinng?
> 
> +  uw_install_context (&this_context, &cur_context, FRAMES_VAR);
> 
> Doesn't that create a syntax error when FRAMES_VAR is defined, but with
> no content?

It doesn't give a syntax error. HJ has given an example in this thread.

Igor

> Jeff

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [PATCH 08/22] Add Intel CET support for EH in libgcc.
  2017-11-08 22:06       ` Tsimbalist, Igor V
@ 2017-11-13 22:16         ` Tsimbalist, Igor V
  2017-11-16 19:33           ` Jeff Law
  2017-11-18 15:43           ` Andreas Schwab
  0 siblings, 2 replies; 13+ messages in thread
From: Tsimbalist, Igor V @ 2017-11-13 22:16 UTC (permalink / raw)
  To: Jeff Law, gcc-patches; +Cc: ian, Tsimbalist, Igor V

[-- Attachment #1: Type: text/plain, Size: 195 bytes --]

New patch is attached. The difference is that all newly introduced macro
are removed except of _Unwind_Frames_Extra macro. They are replaced
with new parameters and local variables.

Igor


[-- Attachment #2: 0008-Add-Intel-CET-support-for-EH-in-libgcc.patch --]
[-- Type: application/octet-stream, Size: 14291 bytes --]

From 47fe033b2a23397be50455b7661ad499c42209be Mon Sep 17 00:00:00 2001
From: Igor Tsimbalist <igor.v.tsimbalist@intel.com>
Date: Wed, 19 Jul 2017 03:04:46 +0300
Subject: [PATCH 08/22] Add Intel CET support for EH in libgcc.

Control-flow Enforcement Technology (CET), published by Intel,
introduces the Shadow Stack feature, which ensures a return from a
function is done to exactly the same location from where the function
was called. When EH is present the control-flow transfer may skip some
stack frames and the shadow stack has to be adjusted not to signal a
violation of a control-flow transfer. It's done by counting a number
of skiping frames and adjasting shadow stack pointer by this number.

Having new semantic of the 'ret' instruction if CET is supported in HW
the 'ret' instruction cannot be generated in ix86_expand_epilogue when
we are returning after EH is processed. Added a code in
ix86_expand_epilogue to adjust Shadow Stack pointer and to generate an
indirect jump instead of 'ret'. As sp register is used during this
adjustment thus the argument in pro_epilogue_adjust_stack is changed
to update cfa_reg based on whether control-flow instrumentation is set.
Without updating the cfa_reg field there is an assert later in dwarf2
pass related to mismatch the stack register and cfa_reg value.

gcc/
	* config/i386/i386.c (ix86_expand_epilogue): Change simple
	return to indirect jump for EH return. Change explicit 'false'
	argument in pro_epilogue_adjust_stack with a value of
	flag_cf_protection.
	* config/i386/i386.md (simple_return_indirect_internal): Remove
	SImode restriction to support 64-bit.

libgcc/
	* config/i386/linux-unwind.h: Include
	config/i386/shadow-stack-unwind.h.
	* config/i386/shadow-stack-unwind.h: New file.
	* unwind-dw2.c: (uw_install_context): Add a frame parameter and
	pass it to _Unwind_Frames_Extra.
	* unwind-generic.h (_Unwind_Frames_Extra): New.
	* unwind.inc (_Unwind_RaiseException_Phase2): Add frames_p
	parameter. Add local variable frames to count number of frames.
	(_Unwind_ForcedUnwind_Phase2): Likewise.
	(_Unwind_RaiseException): Add local variable frames to count
	number of frames, pass it to _Unwind_RaiseException_Phase2 and
	uw_install_context.
	(_Unwind_ForcedUnwind): Likewise.
	(_Unwind_Resume): Likewise.
	(_Unwind_Resume_or_Rethrow): Likewise.
---
 gcc/config/i386/i386.c                   | 34 +++++++++++++++++++--
 gcc/config/i386/i386.md                  |  2 +-
 libgcc/config/i386/linux-unwind.h        |  5 ++++
 libgcc/config/i386/shadow-stack-unwind.h | 51 ++++++++++++++++++++++++++++++++
 libgcc/unwind-dw2.c                      |  8 +++--
 libgcc/unwind-generic.h                  |  3 ++
 libgcc/unwind.inc                        | 34 ++++++++++++++-------
 7 files changed, 120 insertions(+), 17 deletions(-)
 create mode 100644 libgcc/config/i386/shadow-stack-unwind.h

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 769f189..3527a59 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -13952,7 +13952,9 @@ ix86_expand_epilogue (int style)
 		 offset relative to SA, and after this insn we have no
 		 other reasonable register to use for the CFA.  We don't
 		 bother resetting the CFA to the SP for the duration of
-		 the return insn.  */
+		 the return insn, unless we control flow instrumentation
+		 is done.  In this case the SP is used later and we have
+		 to reset CFA to SP.  */
 	      add_reg_note (insn, REG_CFA_DEF_CFA,
 			    plus_constant (Pmode, sa, UNITS_PER_WORD));
 	      ix86_add_queued_cfa_restore_notes (insn);
@@ -13964,7 +13966,8 @@ ix86_expand_epilogue (int style)
 	      m->fs.fp_valid = false;
 
 	      pro_epilogue_adjust_stack (stack_pointer_rtx, sa,
-					 const0_rtx, style, false);
+					 const0_rtx, style,
+					 flag_cf_protection);
 	    }
 	  else
 	    {
@@ -14148,7 +14151,32 @@ ix86_expand_epilogue (int style)
 	emit_jump_insn (gen_simple_return_pop_internal (popc));
     }
   else if (!m->call_ms2sysv || !restore_stub_is_tail)
-    emit_jump_insn (gen_simple_return_internal ());
+    {
+      /* In case of return from EH a simple return cannot be used
+	 as a return address will be compared with a shadow stack
+	 return address.  Use indirect jump instead.  */
+      if (style == 2 && flag_cf_protection)
+	{
+	  /* Register used in indirect jump must be in word_mode.  But
+	     Pmode may not be the same as word_mode for x32.  */
+	  rtx ecx = gen_rtx_REG (word_mode, CX_REG);
+	  rtx_insn *insn;
+
+	  insn = emit_insn (gen_pop (ecx));
+	  m->fs.cfa_offset -= UNITS_PER_WORD;
+	  m->fs.sp_offset -= UNITS_PER_WORD;
+
+	  rtx x = plus_constant (Pmode, stack_pointer_rtx, UNITS_PER_WORD);
+	  x = gen_rtx_SET (stack_pointer_rtx, x);
+	  add_reg_note (insn, REG_CFA_ADJUST_CFA, x);
+	  add_reg_note (insn, REG_CFA_REGISTER, gen_rtx_SET (ecx, pc_rtx));
+	  RTX_FRAME_RELATED_P (insn) = 1;
+
+	  emit_jump_insn (gen_simple_return_indirect_internal (ecx));
+	}
+      else
+	emit_jump_insn (gen_simple_return_internal ());
+    }
 
   /* Restore the state back to the state from the prologue,
      so that it's correct for the next epilogue.  */
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 90e622c..1e91823 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -13086,7 +13086,7 @@
 
 (define_insn "simple_return_indirect_internal"
   [(simple_return)
-   (use (match_operand:SI 0 "register_operand" "r"))]
+   (use (match_operand 0 "register_operand" "r"))]
   "reload_completed"
   "%!jmp\t%A0"
   [(set_attr "type" "ibr")
diff --git a/libgcc/config/i386/linux-unwind.h b/libgcc/config/i386/linux-unwind.h
index 2009ad7..c51b4d9 100644
--- a/libgcc/config/i386/linux-unwind.h
+++ b/libgcc/config/i386/linux-unwind.h
@@ -22,6 +22,11 @@ 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/>.  */
 
+/* Unwind shadow stack for -fcf-protection -mshstk.  */
+#if defined __SHSTK__ && defined __CET__
+# include "config/i386/shadow-stack-unwind.h"
+#endif
+
 /* Do code reading to identify a signal frame, and set the frame
    state data appropriately.  See unwind-dw2.c for the structs.
    Don't use this at all if inhibit_libc is used.  */
diff --git a/libgcc/config/i386/shadow-stack-unwind.h b/libgcc/config/i386/shadow-stack-unwind.h
new file mode 100644
index 0000000..2789e89
--- /dev/null
+++ b/libgcc/config/i386/shadow-stack-unwind.h
@@ -0,0 +1,51 @@
+/* _Unwind_Frames_Extra with shadow stack for x86-64 and x86.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC 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.
+
+GCC 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/>.  */
+
+#ifdef __x86_64__
+# define incssp(x) __builtin_ia32_incsspq ((x))
+# define rdssp(x) __builtin_ia32_rdsspq (x)
+#else
+# define incssp(x) __builtin_ia32_incsspd ((x))
+# define rdssp(x) __builtin_ia32_rdsspd (x)
+#endif
+
+/* Unwind the shadow stack for EH.  */
+#undef _Unwind_Frames_Extra
+#define _Unwind_Frames_Extra(x)			\
+  do						\
+    {						\
+      unsigned long ssp = 0;			\
+      ssp = rdssp (ssp);			\
+      if (ssp != 0)				\
+	{					\
+	  unsigned long tmp = (x);		\
+	  while (tmp > 255)			\
+	    {					\
+	      incssp (tmp);			\
+	      tmp -= 255;			\
+	    }					\
+	  incssp (tmp);				\
+	}					\
+    }						\
+    while (0)
diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
index 3f26eaf..e80ac74 100644
--- a/libgcc/unwind-dw2.c
+++ b/libgcc/unwind-dw2.c
@@ -1644,14 +1644,18 @@ uw_frob_return_addr (struct _Unwind_Context *current
 
 /* Install TARGET into CURRENT so that we can return to it.  This is a
    macro because __builtin_eh_return must be invoked in the context of
-   our caller.  */
+   our caller.  FRAMES is a number of frames to be unwind.
+   _Unwind_Frames_Extra is a macro to do additional work during unwinding
+   if needed, for example shadow stack pointer adjustment for Intel CET
+   technology.  */
 
-#define uw_install_context(CURRENT, TARGET)				\
+#define uw_install_context(CURRENT, TARGET, FRAMES)			\
   do									\
     {									\
       long offset = uw_install_context_1 ((CURRENT), (TARGET));		\
       void *handler = uw_frob_return_addr ((CURRENT), (TARGET));	\
       _Unwind_DebugHook ((TARGET)->cfa, handler);			\
+      _Unwind_Frames_Extra (FRAMES);					\
       __builtin_eh_return (offset, handler);				\
     }									\
   while (0)
diff --git a/libgcc/unwind-generic.h b/libgcc/unwind-generic.h
index 77dd5a9..570ea50 100644
--- a/libgcc/unwind-generic.h
+++ b/libgcc/unwind-generic.h
@@ -288,4 +288,7 @@ EXCEPTION_DISPOSITION _GCC_specific_handler (PEXCEPTION_RECORD, void *,
 #pragma GCC visibility pop
 #endif
 
+/* Additional actions to unwind number of stack frames.  */
+#define _Unwind_Frames_Extra(frames)
+
 #endif /* unwind.h */
diff --git a/libgcc/unwind.inc b/libgcc/unwind.inc
index 658bd94..a98154b 100644
--- a/libgcc/unwind.inc
+++ b/libgcc/unwind.inc
@@ -36,9 +36,11 @@
 
 static _Unwind_Reason_Code
 _Unwind_RaiseException_Phase2(struct _Unwind_Exception *exc,
-			      struct _Unwind_Context *context)
+			      struct _Unwind_Context *context,
+			      unsigned long *frames_p)
 {
   _Unwind_Reason_Code code;
+  unsigned long frames = 1;
 
   while (1)
     {
@@ -71,8 +73,10 @@ _Unwind_RaiseException_Phase2(struct _Unwind_Exception *exc,
       gcc_assert (!match_handler);
 
       uw_update_context (context, &fs);
+      frames++;
     }
 
+  *frames_p = frames;
   return code;
 }
 
@@ -83,6 +87,7 @@ _Unwind_RaiseException(struct _Unwind_Exception *exc)
 {
   struct _Unwind_Context this_context, cur_context;
   _Unwind_Reason_Code code;
+  unsigned long frames;
 
   /* Set up this_context to describe the current stack frame.  */
   uw_init_context (&this_context);
@@ -128,11 +133,11 @@ _Unwind_RaiseException(struct _Unwind_Exception *exc)
   exc->private_2 = uw_identify_context (&cur_context);
 
   cur_context = this_context;
-  code = _Unwind_RaiseException_Phase2 (exc, &cur_context);
+  code = _Unwind_RaiseException_Phase2 (exc, &cur_context, &frames);
   if (code != _URC_INSTALL_CONTEXT)
     return code;
 
-  uw_install_context (&this_context, &cur_context);
+  uw_install_context (&this_context, &cur_context, frames);
 }
 
 
@@ -140,11 +145,13 @@ _Unwind_RaiseException(struct _Unwind_Exception *exc)
 
 static _Unwind_Reason_Code
 _Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc,
-			     struct _Unwind_Context *context)
+			     struct _Unwind_Context *context,
+			     unsigned long *frames_p)
 {
   _Unwind_Stop_Fn stop = (_Unwind_Stop_Fn) (_Unwind_Ptr) exc->private_1;
   void *stop_argument = (void *) (_Unwind_Ptr) exc->private_2;
   _Unwind_Reason_Code code, stop_code;
+  unsigned long frames = 1;
 
   while (1)
     {
@@ -183,8 +190,10 @@ _Unwind_ForcedUnwind_Phase2 (struct _Unwind_Exception *exc,
       /* Update cur_context to describe the same frame as fs, and discard
 	 the previous context if necessary.  */
       uw_advance_context (context, &fs);
+      frames++;
     }
 
+  *frames_p = frames;
   return code;
 }
 
@@ -197,6 +206,7 @@ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
 {
   struct _Unwind_Context this_context, cur_context;
   _Unwind_Reason_Code code;
+  unsigned long frames;
 
   uw_init_context (&this_context);
   cur_context = this_context;
@@ -204,11 +214,11 @@ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
   exc->private_1 = (_Unwind_Ptr) stop;
   exc->private_2 = (_Unwind_Ptr) stop_argument;
 
-  code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
+  code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context, &frames);
   if (code != _URC_INSTALL_CONTEXT)
     return code;
 
-  uw_install_context (&this_context, &cur_context);
+  uw_install_context (&this_context, &cur_context, frames);
 }
 
 
@@ -220,6 +230,7 @@ _Unwind_Resume (struct _Unwind_Exception *exc)
 {
   struct _Unwind_Context this_context, cur_context;
   _Unwind_Reason_Code code;
+  unsigned long frames;
 
   uw_init_context (&this_context);
   cur_context = this_context;
@@ -227,13 +238,13 @@ _Unwind_Resume (struct _Unwind_Exception *exc)
   /* Choose between continuing to process _Unwind_RaiseException
      or _Unwind_ForcedUnwind.  */
   if (exc->private_1 == 0)
-    code = _Unwind_RaiseException_Phase2 (exc, &cur_context);
+    code = _Unwind_RaiseException_Phase2 (exc, &cur_context, &frames);
   else
-    code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
+    code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context, &frames);
 
   gcc_assert (code == _URC_INSTALL_CONTEXT);
 
-  uw_install_context (&this_context, &cur_context);
+  uw_install_context (&this_context, &cur_context, frames);
 }
 
 
@@ -245,6 +256,7 @@ _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
 {
   struct _Unwind_Context this_context, cur_context;
   _Unwind_Reason_Code code;
+  unsigned long frames;
 
   /* Choose between continuing to process _Unwind_RaiseException
      or _Unwind_ForcedUnwind.  */
@@ -254,11 +266,11 @@ _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
   uw_init_context (&this_context);
   cur_context = this_context;
 
-  code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context);
+  code = _Unwind_ForcedUnwind_Phase2 (exc, &cur_context, &frames);
 
   gcc_assert (code == _URC_INSTALL_CONTEXT);
 
-  uw_install_context (&this_context, &cur_context);
+  uw_install_context (&this_context, &cur_context, frames);
 }
 
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 08/22] Add Intel CET support for EH in libgcc.
  2017-11-13 22:16         ` Tsimbalist, Igor V
@ 2017-11-16 19:33           ` Jeff Law
  2017-11-18 15:43           ` Andreas Schwab
  1 sibling, 0 replies; 13+ messages in thread
From: Jeff Law @ 2017-11-16 19:33 UTC (permalink / raw)
  To: Tsimbalist, Igor V, gcc-patches; +Cc: ian

On 11/13/2017 02:44 PM, Tsimbalist, Igor V wrote:
> New patch is attached. The difference is that all newly introduced macro
> are removed except of _Unwind_Frames_Extra macro. They are replaced
> with new parameters and local variables.
> 
> Igor
> 
> 
> 0008-Add-Intel-CET-support-for-EH-in-libgcc.patch
> 
> 
> From 47fe033b2a23397be50455b7661ad499c42209be Mon Sep 17 00:00:00 2001
> From: Igor Tsimbalist <igor.v.tsimbalist@intel.com>
> Date: Wed, 19 Jul 2017 03:04:46 +0300
> Subject: [PATCH 08/22] Add Intel CET support for EH in libgcc.
> 
> Control-flow Enforcement Technology (CET), published by Intel,
> introduces the Shadow Stack feature, which ensures a return from a
> function is done to exactly the same location from where the function
> was called. When EH is present the control-flow transfer may skip some
> stack frames and the shadow stack has to be adjusted not to signal a
> violation of a control-flow transfer. It's done by counting a number
> of skiping frames and adjasting shadow stack pointer by this number.
> 
> Having new semantic of the 'ret' instruction if CET is supported in HW
> the 'ret' instruction cannot be generated in ix86_expand_epilogue when
> we are returning after EH is processed. Added a code in
> ix86_expand_epilogue to adjust Shadow Stack pointer and to generate an
> indirect jump instead of 'ret'. As sp register is used during this
> adjustment thus the argument in pro_epilogue_adjust_stack is changed
> to update cfa_reg based on whether control-flow instrumentation is set.
> Without updating the cfa_reg field there is an assert later in dwarf2
> pass related to mismatch the stack register and cfa_reg value.
> 
> gcc/
> 	* config/i386/i386.c (ix86_expand_epilogue): Change simple
> 	return to indirect jump for EH return. Change explicit 'false'
> 	argument in pro_epilogue_adjust_stack with a value of
> 	flag_cf_protection.
> 	* config/i386/i386.md (simple_return_indirect_internal): Remove
> 	SImode restriction to support 64-bit.
> 
> libgcc/
> 	* config/i386/linux-unwind.h: Include
> 	config/i386/shadow-stack-unwind.h.
> 	* config/i386/shadow-stack-unwind.h: New file.
> 	* unwind-dw2.c: (uw_install_context): Add a frame parameter and
> 	pass it to _Unwind_Frames_Extra.
> 	* unwind-generic.h (_Unwind_Frames_Extra): New.
> 	* unwind.inc (_Unwind_RaiseException_Phase2): Add frames_p
> 	parameter. Add local variable frames to count number of frames.
> 	(_Unwind_ForcedUnwind_Phase2): Likewise.
> 	(_Unwind_RaiseException): Add local variable frames to count
> 	number of frames, pass it to _Unwind_RaiseException_Phase2 and
> 	uw_install_context.
> 	(_Unwind_ForcedUnwind): Likewise.
> 	(_Unwind_Resume): Likewise.
> 	(_Unwind_Resume_or_Rethrow): Likewise.
This version looks much better  :-)

OK.
jeff

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 08/22] Add Intel CET support for EH in libgcc.
  2017-11-13 22:16         ` Tsimbalist, Igor V
  2017-11-16 19:33           ` Jeff Law
@ 2017-11-18 15:43           ` Andreas Schwab
  2017-11-19  0:10             ` Tsimbalist, Igor V
  1 sibling, 1 reply; 13+ messages in thread
From: Andreas Schwab @ 2017-11-18 15:43 UTC (permalink / raw)
  To: Tsimbalist, Igor V; +Cc: Jeff Law, gcc-patches, ian

In file included from ../../../libgcc/config/ia64/unwind-ia64.c:2448:
../../../libgcc/unwind.inc: In function '_Unwind_RaiseException':
../../../libgcc/unwind.inc:140:3: error: too many arguments to function 'uw_install_context'
   uw_install_context (&this_context, &cur_context, frames);
   ^~~~~~~~~~~~~~~~~~
../../../libgcc/config/ia64/unwind-ia64.c:2167:1: note: declared here
 uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
 ^~~~~~~~~~~~~~~~~~

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 13+ messages in thread

* RE: [PATCH 08/22] Add Intel CET support for EH in libgcc.
  2017-11-18 15:43           ` Andreas Schwab
@ 2017-11-19  0:10             ` Tsimbalist, Igor V
  2017-11-20 11:32               ` Richard Biener
  0 siblings, 1 reply; 13+ messages in thread
From: Tsimbalist, Igor V @ 2017-11-19  0:10 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Jeff Law, gcc-patches, ian, Tsimbalist, Igor V

I propose the following changes. I do not have ia64 to test. Ok for trunk?

bash-4.2$ svn diff
Index: libgcc/config/cr16/unwind-cr16.c
===================================================================
--- libgcc/config/cr16/unwind-cr16.c    (revision 254908)
+++ libgcc/config/cr16/unwind-cr16.c    (working copy)
@@ -1567,7 +1567,7 @@
    our caller.  */
 #if defined( __CR16C__ )

-#define uw_install_context(CURRENT, TARGET)                            \
+#define uw_install_context(CURRENT, TARGET, FRAMES)                    \
   do                                                                   \
     {                                                                  \
       long offset = uw_install_context_1 ((CURRENT), (TARGET));                \
@@ -1578,7 +1578,7 @@
     }                                                                  \
   while (0)
 #else
-#define uw_install_context(CURRENT, TARGET)                             \
+#define uw_install_context(CURRENT, TARGET, FRAMES)                     \
   do                                                                    \
     {                                                                   \
       long offset = uw_install_context_1 ((CURRENT), (TARGET));         \
Index: libgcc/config/ia64/unwind-ia64.c
===================================================================
--- libgcc/config/ia64/unwind-ia64.c    (revision 254908)
+++ libgcc/config/ia64/unwind-ia64.c    (working copy)
@@ -2165,7 +2165,8 @@

 static void __attribute__((noreturn))
 uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
-                   struct _Unwind_Context *target)
+                   struct _Unwind_Context *target,
+                   unsigned long frames __attribute__((unused)))
 {
   unw_word ireg_buf[4], ireg_nat = 0, ireg_pr = 0;
   unw_word saved_lc;
Index: libgcc/config/xtensa/unwind-dw2-xtensa.c
===================================================================
--- libgcc/config/xtensa/unwind-dw2-xtensa.c    (revision 254908)
+++ libgcc/config/xtensa/unwind-dw2-xtensa.c    (working copy)
@@ -483,7 +483,7 @@
    macro because __builtin_eh_return must be invoked in the context of
    our caller.  */

-#define uw_install_context(CURRENT, TARGET)                             \
+#define uw_install_context(CURRENT, TARGET, FRAMES)                             \
   do                                                                    \
     {                                                                   \
       long offset = uw_install_context_1 ((CURRENT), (TARGET));                 \
Index: libgcc/unwind-sjlj.c
===================================================================
--- libgcc/unwind-sjlj.c        (revision 254908)
+++ libgcc/unwind-sjlj.c        (working copy)
@@ -300,7 +300,8 @@

 static void __attribute__((noreturn))
 uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
-                    struct _Unwind_Context *target)
+                    struct _Unwind_Context *target,
+                   unsigned long frames __attribute__((unused)))
 {
   _Unwind_SjLj_SetContext (target->fc);
   longjmp (target->fc->jbuf, 1);


Igor

> -----Original Message-----
> From: Andreas Schwab [mailto:schwab@linux-m68k.org]
> Sent: Saturday, November 18, 2017 2:51 PM
> To: Tsimbalist, Igor V <igor.v.tsimbalist@intel.com>
> Cc: Jeff Law <law@redhat.com>; gcc-patches@gcc.gnu.org; ian@airs.com
> Subject: Re: [PATCH 08/22] Add Intel CET support for EH in libgcc.
> 
> In file included from ../../../libgcc/config/ia64/unwind-ia64.c:2448:
> ../../../libgcc/unwind.inc: In function '_Unwind_RaiseException':
> ../../../libgcc/unwind.inc:140:3: error: too many arguments to function
> 'uw_install_context'
>    uw_install_context (&this_context, &cur_context, frames);
>    ^~~~~~~~~~~~~~~~~~
> ../../../libgcc/config/ia64/unwind-ia64.c:2167:1: note: declared here
>  uw_install_context (struct _Unwind_Context *current
> __attribute__((unused)),
>  ^~~~~~~~~~~~~~~~~~
> 
> Andreas.
> 
> --
> Andreas Schwab, schwab@linux-m68k.org
> GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
> "And now for something completely different."

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 08/22] Add Intel CET support for EH in libgcc.
  2017-11-19  0:10             ` Tsimbalist, Igor V
@ 2017-11-20 11:32               ` Richard Biener
  0 siblings, 0 replies; 13+ messages in thread
From: Richard Biener @ 2017-11-20 11:32 UTC (permalink / raw)
  To: Tsimbalist, Igor V; +Cc: Andreas Schwab, Jeff Law, gcc-patches, ian

On Sat, Nov 18, 2017 at 9:11 PM, Tsimbalist, Igor V
<igor.v.tsimbalist@intel.com> wrote:
> I propose the following changes. I do not have ia64 to test. Ok for trunk?

Ok with a proper changelog.

Richard.

> bash-4.2$ svn diff
> Index: libgcc/config/cr16/unwind-cr16.c
> ===================================================================
> --- libgcc/config/cr16/unwind-cr16.c    (revision 254908)
> +++ libgcc/config/cr16/unwind-cr16.c    (working copy)
> @@ -1567,7 +1567,7 @@
>     our caller.  */
>  #if defined( __CR16C__ )
>
> -#define uw_install_context(CURRENT, TARGET)                            \
> +#define uw_install_context(CURRENT, TARGET, FRAMES)                    \
>    do                                                                   \
>      {                                                                  \
>        long offset = uw_install_context_1 ((CURRENT), (TARGET));                \
> @@ -1578,7 +1578,7 @@
>      }                                                                  \
>    while (0)
>  #else
> -#define uw_install_context(CURRENT, TARGET)                             \
> +#define uw_install_context(CURRENT, TARGET, FRAMES)                     \
>    do                                                                    \
>      {                                                                   \
>        long offset = uw_install_context_1 ((CURRENT), (TARGET));         \
> Index: libgcc/config/ia64/unwind-ia64.c
> ===================================================================
> --- libgcc/config/ia64/unwind-ia64.c    (revision 254908)
> +++ libgcc/config/ia64/unwind-ia64.c    (working copy)
> @@ -2165,7 +2165,8 @@
>
>  static void __attribute__((noreturn))
>  uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
> -                   struct _Unwind_Context *target)
> +                   struct _Unwind_Context *target,
> +                   unsigned long frames __attribute__((unused)))
>  {
>    unw_word ireg_buf[4], ireg_nat = 0, ireg_pr = 0;
>    unw_word saved_lc;
> Index: libgcc/config/xtensa/unwind-dw2-xtensa.c
> ===================================================================
> --- libgcc/config/xtensa/unwind-dw2-xtensa.c    (revision 254908)
> +++ libgcc/config/xtensa/unwind-dw2-xtensa.c    (working copy)
> @@ -483,7 +483,7 @@
>     macro because __builtin_eh_return must be invoked in the context of
>     our caller.  */
>
> -#define uw_install_context(CURRENT, TARGET)                             \
> +#define uw_install_context(CURRENT, TARGET, FRAMES)                             \
>    do                                                                    \
>      {                                                                   \
>        long offset = uw_install_context_1 ((CURRENT), (TARGET));                 \
> Index: libgcc/unwind-sjlj.c
> ===================================================================
> --- libgcc/unwind-sjlj.c        (revision 254908)
> +++ libgcc/unwind-sjlj.c        (working copy)
> @@ -300,7 +300,8 @@
>
>  static void __attribute__((noreturn))
>  uw_install_context (struct _Unwind_Context *current __attribute__((unused)),
> -                    struct _Unwind_Context *target)
> +                    struct _Unwind_Context *target,
> +                   unsigned long frames __attribute__((unused)))
>  {
>    _Unwind_SjLj_SetContext (target->fc);
>    longjmp (target->fc->jbuf, 1);
>
>
> Igor
>
>> -----Original Message-----
>> From: Andreas Schwab [mailto:schwab@linux-m68k.org]
>> Sent: Saturday, November 18, 2017 2:51 PM
>> To: Tsimbalist, Igor V <igor.v.tsimbalist@intel.com>
>> Cc: Jeff Law <law@redhat.com>; gcc-patches@gcc.gnu.org; ian@airs.com
>> Subject: Re: [PATCH 08/22] Add Intel CET support for EH in libgcc.
>>
>> In file included from ../../../libgcc/config/ia64/unwind-ia64.c:2448:
>> ../../../libgcc/unwind.inc: In function '_Unwind_RaiseException':
>> ../../../libgcc/unwind.inc:140:3: error: too many arguments to function
>> 'uw_install_context'
>>    uw_install_context (&this_context, &cur_context, frames);
>>    ^~~~~~~~~~~~~~~~~~
>> ../../../libgcc/config/ia64/unwind-ia64.c:2167:1: note: declared here
>>  uw_install_context (struct _Unwind_Context *current
>> __attribute__((unused)),
>>  ^~~~~~~~~~~~~~~~~~
>>
>> Andreas.
>>
>> --
>> Andreas Schwab, schwab@linux-m68k.org
>> GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
>> "And now for something completely different."

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2017-11-20 11:24 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-12 20:01 [PATCH 08/22] Add Intel CET support for EH in libgcc Tsimbalist, Igor V
2017-10-12 23:59 ` Hans-Peter Nilsson
2017-10-25 17:30   ` H.J. Lu
2017-10-31  5:09 ` Jeff Law
2017-11-04 12:44   ` Tsimbalist, Igor V
2017-11-08 19:09     ` Jeff Law
2017-11-08 19:11       ` H.J. Lu
2017-11-08 22:06       ` Tsimbalist, Igor V
2017-11-13 22:16         ` Tsimbalist, Igor V
2017-11-16 19:33           ` Jeff Law
2017-11-18 15:43           ` Andreas Schwab
2017-11-19  0:10             ` Tsimbalist, Igor V
2017-11-20 11:32               ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).