> -----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

Reply via email to