> -----Original Message----- > From: Jeff Law [mailto:l...@redhat.com] > Sent: Tuesday, October 31, 2017 5:49 AM > To: Tsimbalist, Igor V <igor.v.tsimbal...@intel.com>; gcc- > patc...@gcc.gnu.org > Cc: i...@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.tsimbal...@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