xref: /freebsd-src/contrib/llvm-project/libunwind/src/cet_unwind.h (revision 62987288060ff68c817b7056815aa9fb8ba8ecd7)
1349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric //
8349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
9349cc55cSDimitry Andric 
10349cc55cSDimitry Andric #ifndef LIBUNWIND_CET_UNWIND_H
11349cc55cSDimitry Andric #define LIBUNWIND_CET_UNWIND_H
12349cc55cSDimitry Andric 
13349cc55cSDimitry Andric #include "libunwind.h"
14349cc55cSDimitry Andric 
15349cc55cSDimitry Andric // Currently, CET is implemented on Linux x86 platforms.
16349cc55cSDimitry Andric #if defined(_LIBUNWIND_TARGET_LINUX) && defined(__CET__) && defined(__SHSTK__)
17349cc55cSDimitry Andric #define _LIBUNWIND_USE_CET 1
18349cc55cSDimitry Andric #endif
19349cc55cSDimitry Andric 
20349cc55cSDimitry Andric #if defined(_LIBUNWIND_USE_CET)
21349cc55cSDimitry Andric #include <cet.h>
22349cc55cSDimitry Andric #include <immintrin.h>
23349cc55cSDimitry Andric 
24349cc55cSDimitry Andric #define _LIBUNWIND_POP_CET_SSP(x)                                              \
25349cc55cSDimitry Andric   do {                                                                         \
26349cc55cSDimitry Andric     unsigned long ssp = _get_ssp();                                            \
27349cc55cSDimitry Andric     if (ssp != 0) {                                                            \
28349cc55cSDimitry Andric       unsigned int tmp = (x);                                                  \
29349cc55cSDimitry Andric       while (tmp > 255) {                                                      \
30349cc55cSDimitry Andric         _inc_ssp(255);                                                         \
31349cc55cSDimitry Andric         tmp -= 255;                                                            \
32349cc55cSDimitry Andric       }                                                                        \
33349cc55cSDimitry Andric       _inc_ssp(tmp);                                                           \
34349cc55cSDimitry Andric     }                                                                          \
35349cc55cSDimitry Andric   } while (0)
36349cc55cSDimitry Andric #endif
37349cc55cSDimitry Andric 
38*62987288SDimitry Andric // On AArch64 we use _LIBUNWIND_USE_GCS to indicate that GCS is supported. We
39*62987288SDimitry Andric // need to guard any use of GCS instructions with __chkfeat though, as GCS may
40*62987288SDimitry Andric // not be enabled.
41*62987288SDimitry Andric #if defined(_LIBUNWIND_TARGET_AARCH64) && defined(__ARM_FEATURE_GCS_DEFAULT)
42*62987288SDimitry Andric #include <arm_acle.h>
43*62987288SDimitry Andric 
44*62987288SDimitry Andric // We can only use GCS if arm_acle.h defines the GCS intrinsics.
45*62987288SDimitry Andric #ifdef _CHKFEAT_GCS
46*62987288SDimitry Andric #define _LIBUNWIND_USE_GCS 1
47*62987288SDimitry Andric #endif
48*62987288SDimitry Andric 
49*62987288SDimitry Andric #define _LIBUNWIND_POP_CET_SSP(x)                                              \
50*62987288SDimitry Andric   do {                                                                         \
51*62987288SDimitry Andric     if (__chkfeat(_CHKFEAT_GCS)) {                                             \
52*62987288SDimitry Andric       unsigned tmp = (x);                                                      \
53*62987288SDimitry Andric       while (tmp--)                                                            \
54*62987288SDimitry Andric         __gcspopm();                                                           \
55*62987288SDimitry Andric     }                                                                          \
56*62987288SDimitry Andric   } while (0)
57*62987288SDimitry Andric 
58*62987288SDimitry Andric #endif
59*62987288SDimitry Andric 
60349cc55cSDimitry Andric extern void *__libunwind_cet_get_registers(unw_cursor_t *);
6181ad6265SDimitry Andric extern void *__libunwind_cet_get_jump_target(void);
62349cc55cSDimitry Andric 
63349cc55cSDimitry Andric #endif
64