Reimplement CET intrinsics for rdssp/incssp insn.
Introduce a couple of new CET intrinsics for reading and updating a shadow stack pointer (_get_ssp and _inc_ssp). They replace the existing _rdssp[d|q] and _incssp[d|q] instrinsics. PR target/84239 * gcc/config/i386/cetintrin.h: Remove _rdssp[d|q] and add _get_ssp intrinsics. Remove argument from __builtin_ia32_rdssp[d|q]. * gcc/config/i386/i386-builtin-types.def: Add UINT_FTYPE_VOID. * gcc/config/i386/i386-builtin.def: Remove argument from __builtin_ia32_rdssp[d|q]. * gcc/config/i386/i386.c: Use UINT_FTYPE_VOID. Use ix86_expand_special_args_builtin for _rdssp[d|q]. * gcc/config/i386/i386.md: Remove argument from rdssp[si|di] insn. Clear register before usage. * doc/extend.texi: Remove argument from __builtin_ia32_rdssp[d|q]. Add documentation for new _get_ssp and _inc_ssp intrinsics. * testsuite/gcc.target/i386/cet-intrin-3.c: Use new _get_ssp and _inc_ssp intrinsics. * testsuite/gcc.target/i386/cet-intrin-4.c: Likewise. * testsuite/gcc.target/i386/cet-rdssp-1.c: Remove argument from __builtin_ia32_rdssp[d|q]. * libgcc/config/i386/shadow-stack-unwind.hi (_Unwind_Frames_Extra): Use new _get_ssp and _inc_ssp intrinsics. From-SVN: r257660
This commit is contained in:
parent
87ca401516
commit
f8de876d8c
|
@ -1,3 +1,19 @@
|
||||||
|
2018-02-14 Igor Tsimbalist <igor.v.tsimbalist@intel.com>
|
||||||
|
|
||||||
|
PR target/84239
|
||||||
|
* config/i386/cetintrin.h: Remove _rdssp[d|q] and
|
||||||
|
add _get_ssp intrinsics. Remove argument from
|
||||||
|
__builtin_ia32_rdssp[d|q].
|
||||||
|
* config/i386/i386-builtin-types.def: Add UINT_FTYPE_VOID.
|
||||||
|
* config/i386/i386-builtin.def: Remove argument from
|
||||||
|
__builtin_ia32_rdssp[d|q].
|
||||||
|
* config/i386/i386.c: Use UINT_FTYPE_VOID. Use
|
||||||
|
ix86_expand_special_args_builtin for _rdssp[d|q].
|
||||||
|
* config/i386/i386.md: Remove argument from rdssp[si|di] insn.
|
||||||
|
Clear register before usage.
|
||||||
|
* doc/extend.texi: Remove argument from __builtin_ia32_rdssp[d|q].
|
||||||
|
Add documentation for new _get_ssp and _inc_ssp intrinsics.
|
||||||
|
|
||||||
2018-02-14 Richard Sandiford <richard.sandiford@linaro.org>
|
2018-02-14 Richard Sandiford <richard.sandiford@linaro.org>
|
||||||
|
|
||||||
PR tree-optimization/84357
|
PR tree-optimization/84357
|
||||||
|
|
|
@ -34,37 +34,32 @@
|
||||||
#define __DISABLE_SHSTK__
|
#define __DISABLE_SHSTK__
|
||||||
#endif /* __SHSTK__ */
|
#endif /* __SHSTK__ */
|
||||||
|
|
||||||
extern __inline unsigned int
|
|
||||||
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
|
||||||
_rdsspd (unsigned int __B)
|
|
||||||
{
|
|
||||||
return __builtin_ia32_rdsspd (__B);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
extern __inline unsigned long long
|
extern __inline unsigned long long
|
||||||
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||||
_rdsspq (unsigned long long __B)
|
_get_ssp (void)
|
||||||
{
|
{
|
||||||
return __builtin_ia32_rdsspq (__B);
|
return __builtin_ia32_rdsspq ();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
extern __inline unsigned int
|
||||||
|
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||||
|
_get_ssp (void)
|
||||||
|
{
|
||||||
|
return __builtin_ia32_rdsspd ();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern __inline void
|
extern __inline void
|
||||||
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||||
_incsspd (unsigned int __B)
|
_inc_ssp (unsigned int __B)
|
||||||
{
|
{
|
||||||
__builtin_ia32_incsspd (__B);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
extern __inline void
|
__builtin_ia32_incsspq ((unsigned long long) __B);
|
||||||
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
#else
|
||||||
_incsspq (unsigned long long __B)
|
__builtin_ia32_incsspd (__B);
|
||||||
{
|
|
||||||
__builtin_ia32_incsspq (__B);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
extern __inline void
|
extern __inline void
|
||||||
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
__attribute__((__gnu_inline__, __always_inline__, __artificial__))
|
||||||
|
|
|
@ -192,6 +192,7 @@ DEF_POINTER_TYPE (PCV64QI, V64QI, CONST)
|
||||||
DEF_FUNCTION_TYPE (FLOAT128)
|
DEF_FUNCTION_TYPE (FLOAT128)
|
||||||
DEF_FUNCTION_TYPE (UINT64)
|
DEF_FUNCTION_TYPE (UINT64)
|
||||||
DEF_FUNCTION_TYPE (UNSIGNED)
|
DEF_FUNCTION_TYPE (UNSIGNED)
|
||||||
|
DEF_FUNCTION_TYPE (UINT)
|
||||||
DEF_FUNCTION_TYPE (USHORT)
|
DEF_FUNCTION_TYPE (USHORT)
|
||||||
DEF_FUNCTION_TYPE (INT)
|
DEF_FUNCTION_TYPE (INT)
|
||||||
DEF_FUNCTION_TYPE (VOID)
|
DEF_FUNCTION_TYPE (VOID)
|
||||||
|
|
|
@ -3043,7 +3043,7 @@ BDESC (OPTION_MASK_ISA_SHSTK, CODE_FOR_clrssbsy, "__builtin_ia32_clrssbsy", IX86
|
||||||
BDESC_END (CET, CET_NORMAL)
|
BDESC_END (CET, CET_NORMAL)
|
||||||
|
|
||||||
BDESC_FIRST (cet_rdssp, CET_NORMAL,
|
BDESC_FIRST (cet_rdssp, CET_NORMAL,
|
||||||
OPTION_MASK_ISA_SHSTK, CODE_FOR_rdsspsi, "__builtin_ia32_rdsspd", IX86_BUILTIN_RDSSPD, UNKNOWN, (int) UINT_FTYPE_UINT)
|
OPTION_MASK_ISA_SHSTK, CODE_FOR_rdsspsi, "__builtin_ia32_rdsspd", IX86_BUILTIN_RDSSPD, UNKNOWN, (int) UINT_FTYPE_VOID)
|
||||||
BDESC (OPTION_MASK_ISA_SHSTK | OPTION_MASK_ISA_64BIT, CODE_FOR_rdsspdi, "__builtin_ia32_rdsspq", IX86_BUILTIN_RDSSPQ, UNKNOWN, (int) UINT64_FTYPE_UINT64)
|
BDESC (OPTION_MASK_ISA_SHSTK | OPTION_MASK_ISA_64BIT, CODE_FOR_rdsspdi, "__builtin_ia32_rdsspq", IX86_BUILTIN_RDSSPQ, UNKNOWN, (int) UINT64_FTYPE_VOID)
|
||||||
|
|
||||||
BDESC_END (CET_NORMAL, MAX)
|
BDESC_END (CET_NORMAL, MAX)
|
||||||
|
|
|
@ -35708,6 +35708,7 @@ ix86_expand_special_args_builtin (const struct builtin_description *d,
|
||||||
case INT_FTYPE_VOID:
|
case INT_FTYPE_VOID:
|
||||||
case USHORT_FTYPE_VOID:
|
case USHORT_FTYPE_VOID:
|
||||||
case UINT64_FTYPE_VOID:
|
case UINT64_FTYPE_VOID:
|
||||||
|
case UINT_FTYPE_VOID:
|
||||||
case UNSIGNED_FTYPE_VOID:
|
case UNSIGNED_FTYPE_VOID:
|
||||||
nargs = 0;
|
nargs = 0;
|
||||||
klass = load;
|
klass = load;
|
||||||
|
@ -38497,7 +38498,7 @@ s4fma_expand:
|
||||||
&& fcode <= IX86_BUILTIN__BDESC_CET_NORMAL_LAST)
|
&& fcode <= IX86_BUILTIN__BDESC_CET_NORMAL_LAST)
|
||||||
{
|
{
|
||||||
i = fcode - IX86_BUILTIN__BDESC_CET_NORMAL_FIRST;
|
i = fcode - IX86_BUILTIN__BDESC_CET_NORMAL_FIRST;
|
||||||
return ix86_expand_args_builtin (bdesc_cet_rdssp + i, exp,
|
return ix86_expand_special_args_builtin (bdesc_cet_rdssp + i, exp,
|
||||||
target);
|
target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18391,8 +18391,8 @@
|
||||||
reg_ssp = gen_reg_rtx (word_mode);
|
reg_ssp = gen_reg_rtx (word_mode);
|
||||||
emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
|
emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
|
||||||
emit_insn ((word_mode == SImode)
|
emit_insn ((word_mode == SImode)
|
||||||
? gen_rdsspsi (reg_ssp, reg_ssp)
|
? gen_rdsspsi (reg_ssp)
|
||||||
: gen_rdsspdi (reg_ssp, reg_ssp));
|
: gen_rdsspdi (reg_ssp));
|
||||||
emit_move_insn (mem, reg_ssp);
|
emit_move_insn (mem, reg_ssp);
|
||||||
}
|
}
|
||||||
DONE;
|
DONE;
|
||||||
|
@ -18437,8 +18437,8 @@
|
||||||
reg_ssp = gen_reg_rtx (word_mode);
|
reg_ssp = gen_reg_rtx (word_mode);
|
||||||
emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
|
emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
|
||||||
emit_insn ((word_mode == SImode)
|
emit_insn ((word_mode == SImode)
|
||||||
? gen_rdsspsi (reg_ssp, reg_ssp)
|
? gen_rdsspsi (reg_ssp)
|
||||||
: gen_rdsspdi (reg_ssp, reg_ssp));
|
: gen_rdsspdi (reg_ssp));
|
||||||
mem_buf = gen_rtx_MEM (word_mode,
|
mem_buf = gen_rtx_MEM (word_mode,
|
||||||
plus_constant (Pmode, operands[0],
|
plus_constant (Pmode, operands[0],
|
||||||
3 * GET_MODE_SIZE (ptr_mode)));
|
3 * GET_MODE_SIZE (ptr_mode)));
|
||||||
|
@ -20167,12 +20167,10 @@
|
||||||
;; CET instructions
|
;; CET instructions
|
||||||
(define_insn "rdssp<mode>"
|
(define_insn "rdssp<mode>"
|
||||||
[(set (match_operand:SWI48x 0 "register_operand" "=r")
|
[(set (match_operand:SWI48x 0 "register_operand" "=r")
|
||||||
(unspec_volatile:SWI48x
|
(unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
|
||||||
[(match_operand:SWI48x 1 "register_operand" "0")]
|
|
||||||
UNSPECV_NOP_RDSSP))]
|
|
||||||
"TARGET_SHSTK"
|
"TARGET_SHSTK"
|
||||||
"rdssp<mskmodesuffix>\t%0"
|
"xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
|
||||||
[(set_attr "length" "4")
|
[(set_attr "length" "6")
|
||||||
(set_attr "type" "other")])
|
(set_attr "type" "other")])
|
||||||
|
|
||||||
(define_insn "incssp<mode>"
|
(define_insn "incssp<mode>"
|
||||||
|
|
|
@ -12461,6 +12461,7 @@ instructions, but allow the compiler to schedule those calls.
|
||||||
* TILEPro Built-in Functions::
|
* TILEPro Built-in Functions::
|
||||||
* x86 Built-in Functions::
|
* x86 Built-in Functions::
|
||||||
* x86 transactional memory intrinsics::
|
* x86 transactional memory intrinsics::
|
||||||
|
* x86 control-flow protection intrinsics::
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node AArch64 Built-in Functions
|
@node AArch64 Built-in Functions
|
||||||
|
@ -21772,13 +21773,17 @@ void __builtin_ia32_wrpkru (unsigned int)
|
||||||
unsigned int __builtin_ia32_rdpkru ()
|
unsigned int __builtin_ia32_rdpkru ()
|
||||||
@end smallexample
|
@end smallexample
|
||||||
|
|
||||||
The following built-in functions are available when @option{-mcet} is used.
|
The following built-in functions are available when @option{-mcet} or
|
||||||
They are used to support Intel Control-flow Enforcment Technology (CET).
|
@option{-mshstk} option is used. They support shadow stack
|
||||||
Each built-in function generates the machine instruction that is part of the
|
machine instructions from Intel Control-flow Enforcement Technology (CET).
|
||||||
function's name.
|
Each built-in function generates the machine instruction that is part
|
||||||
|
of the function's name. These are the internal low-level functions.
|
||||||
|
Normally the functions in @ref{x86 control-flow protection intrinsics}
|
||||||
|
should be used instead.
|
||||||
|
|
||||||
@smallexample
|
@smallexample
|
||||||
unsigned int __builtin_ia32_rdsspd (unsigned int)
|
unsigned int __builtin_ia32_rdsspd (void)
|
||||||
unsigned long long __builtin_ia32_rdsspq (unsigned long long)
|
unsigned long long __builtin_ia32_rdsspq (void)
|
||||||
void __builtin_ia32_incsspd (unsigned int)
|
void __builtin_ia32_incsspd (unsigned int)
|
||||||
void __builtin_ia32_incsspq (unsigned long long)
|
void __builtin_ia32_incsspq (unsigned long long)
|
||||||
void __builtin_ia32_saveprevssp(void);
|
void __builtin_ia32_saveprevssp(void);
|
||||||
|
@ -21885,6 +21890,51 @@ else
|
||||||
Note that, in most cases, the transactional and non-transactional code
|
Note that, in most cases, the transactional and non-transactional code
|
||||||
must synchronize together to ensure consistency.
|
must synchronize together to ensure consistency.
|
||||||
|
|
||||||
|
@node x86 control-flow protection intrinsics
|
||||||
|
@subsection x86 Control-Flow Protection Intrinsics
|
||||||
|
|
||||||
|
@deftypefn {CET Function} {ret_type} _get_ssp (void)
|
||||||
|
Get the current value of shadow stack pointer if shadow stack support
|
||||||
|
from Intel CET is enabled in the hardware or @code{0} otherwise.
|
||||||
|
The @code{ret_type} is @code{unsigned long long} for 64-bit targets
|
||||||
|
and @code{unsigned int} for 32-bit targets.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
@deftypefn {CET Function} void _inc_ssp (unsigned int)
|
||||||
|
Increment the current shadow stack pointer by the size specified by the
|
||||||
|
function argument. The argument is masked to a byte value for security
|
||||||
|
reasons, so to increment by more than 255 bytes you must call the function
|
||||||
|
multiple times.
|
||||||
|
@end deftypefn
|
||||||
|
|
||||||
|
The shadow stack unwind code looks like:
|
||||||
|
|
||||||
|
@smallexample
|
||||||
|
#include <immintrin.h>
|
||||||
|
|
||||||
|
/* Unwind the shadow stack for EH. */
|
||||||
|
#define _Unwind_Frames_Extra(x) \
|
||||||
|
do \
|
||||||
|
@{ \
|
||||||
|
_Unwind_Word ssp = _get_ssp (); \
|
||||||
|
if (ssp != 0) \
|
||||||
|
@{ \
|
||||||
|
_Unwind_Word tmp = (x); \
|
||||||
|
while (tmp > 255) \
|
||||||
|
@{ \
|
||||||
|
_inc_ssp (tmp); \
|
||||||
|
tmp -= 255; \
|
||||||
|
@} \
|
||||||
|
_inc_ssp (tmp); \
|
||||||
|
@} \
|
||||||
|
@} \
|
||||||
|
while (0)
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
This code runs unconditionally on all 64-bit processors. For 32-bit
|
||||||
|
processors the code runs on those that support multi-byte NOP instructions.
|
||||||
|
|
||||||
@node Target Format Checks
|
@node Target Format Checks
|
||||||
@section Format Checks Specific to Particular Target Machines
|
@section Format Checks Specific to Particular Target Machines
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
2018-02-14 Igor Tsimbalist <igor.v.tsimbalist@intel.com>
|
||||||
|
|
||||||
|
PR target/84239
|
||||||
|
* gcc.target/i386/cet-intrin-3.c: Use new _get_ssp and
|
||||||
|
_inc_ssp intrinsics.
|
||||||
|
* gcc.target/i386/cet-intrin-4.c: Likewise.
|
||||||
|
* gcc.target/i386/cet-rdssp-1.c: Remove argument from
|
||||||
|
__builtin_ia32_rdssp[d|q].
|
||||||
|
|
||||||
2018-02-14 Richard Sandiford <richard.sandiford@linaro.org>
|
2018-02-14 Richard Sandiford <richard.sandiford@linaro.org>
|
||||||
|
|
||||||
PR tree-optimization/84357
|
PR tree-optimization/84357
|
||||||
|
|
|
@ -10,24 +10,22 @@
|
||||||
|
|
||||||
unsigned int f1 ()
|
unsigned int f1 ()
|
||||||
{
|
{
|
||||||
unsigned int x = 0;
|
return _get_ssp ();
|
||||||
return _rdsspd (x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void f3 (unsigned int _a)
|
void f3 (unsigned int _a)
|
||||||
{
|
{
|
||||||
_incsspd (_a);
|
_inc_ssp (_a);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
unsigned long long f2 ()
|
unsigned long long f2 ()
|
||||||
{
|
{
|
||||||
unsigned long long x = 0;
|
return _get_ssp ();
|
||||||
return _rdsspq (x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void f4 (unsigned int _a)
|
void f4 (unsigned int _a)
|
||||||
{
|
{
|
||||||
_incsspq (_a);
|
_inc_ssp (_a);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,27 +5,4 @@
|
||||||
/* { dg-final { scan-assembler "incssp\[dq]\[ \t]+(%|)\[re]di" { target { ! ia32 } } } } */
|
/* { dg-final { scan-assembler "incssp\[dq]\[ \t]+(%|)\[re]di" { target { ! ia32 } } } } */
|
||||||
|
|
||||||
#include <immintrin.h>
|
#include <immintrin.h>
|
||||||
|
#include "cet-intrin-3.c"
|
||||||
unsigned int f1 ()
|
|
||||||
{
|
|
||||||
unsigned int x = 0;
|
|
||||||
return _rdsspd (x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void f3 (unsigned int _a)
|
|
||||||
{
|
|
||||||
_incsspd (_a);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __x86_64__
|
|
||||||
unsigned long long f2 ()
|
|
||||||
{
|
|
||||||
unsigned long long x = 0;
|
|
||||||
return _rdsspq (x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void f4 (unsigned int _a)
|
|
||||||
{
|
|
||||||
_incsspq (_a);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -5,18 +5,18 @@ void _exit(int status) __attribute__ ((__noreturn__));
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#ifdef __x86_64__
|
||||||
# define incssp(x) __builtin_ia32_incsspq (x)
|
# define incssp(x) __builtin_ia32_incsspq (x)
|
||||||
# define rdssp(x) __builtin_ia32_rdsspq (x)
|
# define rdssp() __builtin_ia32_rdsspq ()
|
||||||
#else
|
#else
|
||||||
# define incssp(x) __builtin_ia32_incsspd (x)
|
# define incssp(x) __builtin_ia32_incsspd (x)
|
||||||
# define rdssp(x) __builtin_ia32_rdsspd (x)
|
# define rdssp() __builtin_ia32_rdsspd ()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
__attribute__ ((noinline, noclone))
|
__attribute__ ((noinline, noclone))
|
||||||
test (unsigned long frames)
|
test (unsigned long frames)
|
||||||
{
|
{
|
||||||
unsigned long ssp = 0;
|
unsigned long ssp;
|
||||||
ssp = rdssp (ssp);
|
ssp = rdssp ();
|
||||||
if (ssp != 0)
|
if (ssp != 0)
|
||||||
{
|
{
|
||||||
unsigned long tmp = frames;
|
unsigned long tmp = frames;
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2018-02-08 Igor Tsimbalist <igor.v.tsimbalist@intel.com>
|
||||||
|
|
||||||
|
PR target/84239
|
||||||
|
* config/i386/shadow-stack-unwind.hi (_Unwind_Frames_Extra):
|
||||||
|
Use new _get_ssp and _inc_ssp intrinsics.
|
||||||
|
|
||||||
2018-02-02 Julia Koval <julia.koval@intel.com>
|
2018-02-02 Julia Koval <julia.koval@intel.com>
|
||||||
|
|
||||||
* config/i386/cpuinfo.h (processor_subtypes): Add INTEL_COREI7_ICELAKE.
|
* config/i386/cpuinfo.h (processor_subtypes): Add INTEL_COREI7_ICELAKE.
|
||||||
|
|
|
@ -22,30 +22,23 @@ a copy of the GCC Runtime Library Exception along with this program;
|
||||||
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
#ifdef __x86_64__
|
#include <x86intrin.h>
|
||||||
# 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. */
|
/* Unwind the shadow stack for EH. */
|
||||||
#undef _Unwind_Frames_Extra
|
#undef _Unwind_Frames_Extra
|
||||||
#define _Unwind_Frames_Extra(x) \
|
#define _Unwind_Frames_Extra(x) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
unsigned long ssp = 0; \
|
_Unwind_Word ssp = _get_ssp (); \
|
||||||
ssp = rdssp (ssp); \
|
|
||||||
if (ssp != 0) \
|
if (ssp != 0) \
|
||||||
{ \
|
{ \
|
||||||
unsigned long tmp = (x); \
|
_Unwind_Word tmp = (x); \
|
||||||
while (tmp > 255) \
|
while (tmp > 255) \
|
||||||
{ \
|
{ \
|
||||||
incssp (tmp); \
|
_inc_ssp (tmp); \
|
||||||
tmp -= 255; \
|
tmp -= 255; \
|
||||||
} \
|
} \
|
||||||
incssp (tmp); \
|
_inc_ssp (tmp); \
|
||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
while (0)
|
while (0)
|
||||||
|
|
Loading…
Reference in New Issue