Skip to content

Commit 0c2cec7

Browse files
author
git apple-llvm automerger
committed
Merge commit '7e7e8125cfab' from llvm.org/release/19.x into stable/20240723
2 parents a5748b9 + 7e7e812 commit 0c2cec7

10 files changed

+75
-7
lines changed

libunwind/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ if (LIBUNWIND_BUILD_32_BITS)
3737
endif()
3838

3939
option(LIBUNWIND_ENABLE_CET "Build libunwind with CET enabled." OFF)
40+
option(LIBUNWIND_ENABLE_GCS "Build libunwind with GCS enabled." OFF)
4041
option(LIBUNWIND_ENABLE_ASSERTIONS "Enable assertions independent of build mode." ON)
4142
option(LIBUNWIND_ENABLE_PEDANTIC "Compile with pedantic enabled." ON)
4243
option(LIBUNWIND_ENABLE_WERROR "Fail and stop if a warning is triggered." OFF)
@@ -188,6 +189,13 @@ if (LIBUNWIND_ENABLE_CET)
188189
endif()
189190
endif()
190191

192+
if (LIBUNWIND_ENABLE_GCS)
193+
add_compile_flags_if_supported(-mbranch-protection=standard)
194+
if (NOT CXX_SUPPORTS_MBRANCH_PROTECTION_EQ_STANDARD_FLAG)
195+
message(SEND_ERROR "Compiler doesn't support GCS -mbranch-protection option!")
196+
endif()
197+
endif()
198+
191199
if (WIN32)
192200
# The headers lack matching dllexport attributes (_LIBUNWIND_EXPORT);
193201
# silence the warning instead of cluttering the headers (which aren't

libunwind/src/Registers.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1815,6 +1815,13 @@ inline const char *Registers_ppc64::getRegisterName(int regNum) {
18151815
/// process.
18161816
class _LIBUNWIND_HIDDEN Registers_arm64;
18171817
extern "C" void __libunwind_Registers_arm64_jumpto(Registers_arm64 *);
1818+
1819+
#if defined(_LIBUNWIND_USE_GCS)
1820+
extern "C" void *__libunwind_cet_get_jump_target() {
1821+
return reinterpret_cast<void *>(&__libunwind_Registers_arm64_jumpto);
1822+
}
1823+
#endif
1824+
18181825
class _LIBUNWIND_HIDDEN Registers_arm64 {
18191826
public:
18201827
Registers_arm64();

libunwind/src/UnwindCursor.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ class _LIBUNWIND_HIDDEN AbstractUnwindCursor {
471471
}
472472
#endif
473473

474-
#if defined(_LIBUNWIND_USE_CET)
474+
#if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS)
475475
virtual void *get_registers() {
476476
_LIBUNWIND_ABORT("get_registers not implemented");
477477
}
@@ -954,7 +954,7 @@ class UnwindCursor : public AbstractUnwindCursor{
954954
virtual uintptr_t getDataRelBase();
955955
#endif
956956

957-
#if defined(_LIBUNWIND_USE_CET)
957+
#if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS)
958958
virtual void *get_registers() { return &_registers; }
959959
#endif
960960

@@ -3005,7 +3005,7 @@ bool UnwindCursor<A, R>::isReadableAddr(const pint_t addr) const {
30053005
}
30063006
#endif
30073007

3008-
#if defined(_LIBUNWIND_USE_CET)
3008+
#if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS)
30093009
extern "C" void *__libunwind_cet_get_registers(unw_cursor_t *cursor) {
30103010
AbstractUnwindCursor *co = (AbstractUnwindCursor *)cursor;
30113011
return co->get_registers();

libunwind/src/UnwindLevel1.c

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
// _LIBUNWIND_POP_CET_SSP is used to adjust CET shadow stack pointer and we
4545
// directly jump to __libunwind_Registers_x86/x86_64_jumpto instead of using
4646
// a regular function call to avoid pushing to CET shadow stack again.
47-
#if !defined(_LIBUNWIND_USE_CET)
47+
#if !defined(_LIBUNWIND_USE_CET) && !defined(_LIBUNWIND_USE_GCS)
4848
#define __unw_phase2_resume(cursor, fn) \
4949
do { \
5050
(void)fn; \
@@ -72,6 +72,19 @@
7272
__asm__ volatile("jmpq *%%rdx\n\t" :: "D"(cetRegContext), \
7373
"d"(cetJumpAddress)); \
7474
} while (0)
75+
#elif defined(_LIBUNWIND_TARGET_AARCH64)
76+
#define __cet_ss_step_size 8
77+
#define __unw_phase2_resume(cursor, fn) \
78+
do { \
79+
_LIBUNWIND_POP_CET_SSP((fn)); \
80+
void *cetRegContext = __libunwind_cet_get_registers((cursor)); \
81+
void *cetJumpAddress = __libunwind_cet_get_jump_target(); \
82+
__asm__ volatile("mov x0, %0\n\t" \
83+
"br %1\n\t" \
84+
: \
85+
: "r"(cetRegContext), "r"(cetJumpAddress) \
86+
: "x0"); \
87+
} while (0)
7588
#endif
7689

7790
static _Unwind_Reason_Code
@@ -170,6 +183,10 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
170183
}
171184
extern int __unw_step_stage2(unw_cursor_t *);
172185

186+
#if defined(_LIBUNWIND_USE_GCS)
187+
// Enable the GCS target feature to permit gcspop instructions to be used.
188+
__attribute__((target("gcs")))
189+
#endif
173190
static _Unwind_Reason_Code
174191
unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *exception_object) {
175192
__unw_init_local(cursor, uc);
@@ -180,8 +197,12 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
180197
// uc is initialized by __unw_getcontext in the parent frame. The first stack
181198
// frame walked is unwind_phase2.
182199
unsigned framesWalked = 1;
183-
#ifdef _LIBUNWIND_USE_CET
200+
#if defined(_LIBUNWIND_USE_CET)
184201
unsigned long shadowStackTop = _get_ssp();
202+
#elif defined(_LIBUNWIND_USE_GCS)
203+
unsigned long shadowStackTop = 0;
204+
if (__chkfeat(_CHKFEAT_GCS))
205+
shadowStackTop = (unsigned long)__gcspr();
185206
#endif
186207
// Walk each frame until we reach where search phase said to stop.
187208
while (true) {
@@ -238,7 +259,7 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
238259
// against return address stored in CET shadow stack, if the 2 addresses don't
239260
// match, it means return address in normal stack has been corrupted, we return
240261
// _URC_FATAL_PHASE2_ERROR.
241-
#ifdef _LIBUNWIND_USE_CET
262+
#if defined(_LIBUNWIND_USE_CET) || defined(_LIBUNWIND_USE_GCS)
242263
if (shadowStackTop != 0) {
243264
unw_word_t retInNormalStack;
244265
__unw_get_reg(cursor, UNW_REG_IP, &retInNormalStack);
@@ -306,6 +327,10 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
306327
return _URC_FATAL_PHASE2_ERROR;
307328
}
308329

330+
#if defined(_LIBUNWIND_USE_GCS)
331+
// Enable the GCS target feature to permit gcspop instructions to be used.
332+
__attribute__((target("gcs")))
333+
#endif
309334
static _Unwind_Reason_Code
310335
unwind_phase2_forced(unw_context_t *uc, unw_cursor_t *cursor,
311336
_Unwind_Exception *exception_object,

libunwind/src/UnwindRegistersRestore.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ DEFINE_LIBUNWIND_FUNCTION(__libunwind_Registers_arm64_jumpto)
680680
ldr x16, [x0, #0x0F8]
681681
ldp x0, x1, [x0, #0x000] // restore x0,x1
682682
mov sp,x16 // restore sp
683-
ret x30 // jump to pc
683+
br x30 // jump to pc
684684

685685
#elif defined(__arm__) && !defined(__APPLE__)
686686

libunwind/src/cet_unwind.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,24 @@
3535
} while (0)
3636
#endif
3737

38+
// On AArch64 we use _LIBUNWIND_USE_GCS to indicate that GCS is supported. We
39+
// need to guard any use of GCS instructions with __chkfeat though, as GCS may
40+
// not be enabled.
41+
#if defined(_LIBUNWIND_TARGET_AARCH64) && defined(__ARM_FEATURE_GCS_DEFAULT)
42+
#define _LIBUNWIND_USE_GCS 1
43+
#include <arm_acle.h>
44+
45+
#define _LIBUNWIND_POP_CET_SSP(x) \
46+
do { \
47+
if (__chkfeat(_CHKFEAT_GCS)) { \
48+
unsigned tmp = (x); \
49+
while (tmp--) \
50+
__gcspopm(); \
51+
} \
52+
} while (0)
53+
54+
#endif
55+
3856
extern void *__libunwind_cet_get_registers(unw_cursor_t *);
3957
extern void *__libunwind_cet_get_jump_target(void);
4058

libunwind/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ macro(pythonize_bool var)
99
endmacro()
1010

1111
pythonize_bool(LIBUNWIND_ENABLE_CET)
12+
pythonize_bool(LIBUNWIND_ENABLE_GCS)
1213
pythonize_bool(LIBUNWIND_ENABLE_THREADS)
1314
pythonize_bool(LIBUNWIND_USES_ARM_EHABI)
1415

libunwind/test/configs/llvm-libunwind-merged.cfg.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ link_flags = []
1111
if @LIBUNWIND_ENABLE_CET@:
1212
compile_flags.append('-fcf-protection=full')
1313

14+
if @LIBUNWIND_ENABLE_GCS@:
15+
compile_flags.append('-mbranch-protection=standard')
16+
1417
# On ELF platforms, link tests with -Wl,--export-dynamic if supported by the linker.
1518
if len('@CMAKE_EXE_EXPORTS_CXX_FLAG@'):
1619
link_flags.append('@CMAKE_EXE_EXPORTS_CXX_FLAG@')

libunwind/test/configs/llvm-libunwind-shared.cfg.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ link_flags = []
1010
if @LIBUNWIND_ENABLE_CET@:
1111
compile_flags.append('-fcf-protection=full')
1212

13+
if @LIBUNWIND_ENABLE_GCS@:
14+
compile_flags.append('-mbranch-protection=standard')
15+
1316
# On ELF platforms, link tests with -Wl,--export-dynamic if supported by the linker.
1417
if len('@CMAKE_EXE_EXPORTS_CXX_FLAG@'):
1518
link_flags.append('@CMAKE_EXE_EXPORTS_CXX_FLAG@')

libunwind/test/configs/llvm-libunwind-static.cfg.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ if @LIBUNWIND_ENABLE_THREADS@:
1313
if @LIBUNWIND_ENABLE_CET@:
1414
compile_flags.append('-fcf-protection=full')
1515

16+
if @LIBUNWIND_ENABLE_GCS@:
17+
compile_flags.append('-mbranch-protection=standard')
18+
1619
# On ELF platforms, link tests with -Wl,--export-dynamic if supported by the linker.
1720
if len('@CMAKE_EXE_EXPORTS_CXX_FLAG@'):
1821
link_flags.append('@CMAKE_EXE_EXPORTS_CXX_FLAG@')

0 commit comments

Comments
 (0)