[libunwind] [libunwind] Call `__arm_za_disable` before entering EH (PR #160905)
Benjamin Maxwell via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 26 08:24:05 PDT 2025
https://github.com/MacDue created https://github.com/llvm/llvm-project/pull/160905
This is done by defining ` __arm_za_disable` as a weak symbol with the assumption that if libunwind is being linked against SME-aware code, the ABI routines will be provided (by libgcc or compiler-rt).
>From 33dc84e9a4402b8fa19185654d946006561e534c Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Fri, 26 Sep 2025 14:06:56 +0000
Subject: [PATCH] [libunwind] Call `__arm_za_disable` before entering EH
This is done by defining ` __arm_za_disable` as a weak symbol with the
assumption that if libunwind is being linked against SME-aware code, the
ABI routines will be provided (by libgcc or compiler-rt).
---
libunwind/src/UnwindLevel1.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/libunwind/src/UnwindLevel1.c b/libunwind/src/UnwindLevel1.c
index f3b451ad9b730..0a1d4be976830 100644
--- a/libunwind/src/UnwindLevel1.c
+++ b/libunwind/src/UnwindLevel1.c
@@ -186,6 +186,10 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
}
extern int __unw_step_stage2(unw_cursor_t *);
+#if defined(__aarch64__)
+extern void __attribute__((weak)) __arm_za_disable(void);
+#endif
+
#if defined(_LIBUNWIND_USE_GCS)
// Enable the GCS target feature to permit gcspop instructions to be used.
__attribute__((target("+gcs")))
@@ -198,6 +202,29 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor,
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_obj=%p)",
(void *)exception_object);
+#if defined(__aarch64__)
+ // The platform must ensure that all the following conditions are true on
+ // entry to EH:
+ //
+ // - PSTATE.SM is 0.
+ // - PSTATE.ZA is 0.
+ // - TPIDR2_EL0 is null.
+ //
+ // The first point is ensured by routines for throwing exceptions having a
+ // non-streaming interface. TPIDR2_EL0 is set to null and ZA disabled by
+ // calling __arm_za_disable.
+ //
+ // See:
+ // https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#exceptions
+ if (__arm_za_disable) {
+ // FIXME: Is SME is available and `__arm_za_disable` is not, this should
+ // abort.
+ __arm_za_disable();
+ } else {
+ _LIBUNWIND_DEBUG_LOG("failed to call __arm_za_disable in %s", __FUNCTION__);
+ }
+#endif
+
// uc is initialized by __unw_getcontext in the parent frame. The first stack
// frame walked is unwind_phase2.
unsigned framesWalked = 1;
More information about the cfe-commits
mailing list