[libunwind] [libunwind] Call `__arm_za_disable` before entering EH (PR #160905)

Benjamin Maxwell via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 28 06:09:14 PDT 2025


https://github.com/MacDue updated https://github.com/llvm/llvm-project/pull/160905

>From f7ae58cc5704270d9faa9133a4dc805336e56740 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 1/2] [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 b0cd60dfb9141..69c274c504ffc 100644
--- a/libunwind/src/UnwindLevel1.c
+++ b/libunwind/src/UnwindLevel1.c
@@ -202,6 +202,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")))
@@ -214,6 +218,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;

>From 3984605aacff1a5daa9fd6761237df211f0d395e Mon Sep 17 00:00:00 2001
From: Benjamin Maxwell <benjamin.maxwell at arm.com>
Date: Fri, 26 Sep 2025 15:48:51 +0000
Subject: [PATCH 2/2] Fixups

---
 libunwind/src/UnwindLevel1.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libunwind/src/UnwindLevel1.c b/libunwind/src/UnwindLevel1.c
index 69c274c504ffc..ac733453beeb1 100644
--- a/libunwind/src/UnwindLevel1.c
+++ b/libunwind/src/UnwindLevel1.c
@@ -233,10 +233,10 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor,
   // 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 {
+    // FIXME: If SME is available and `__arm_za_disable` is not, this should
+    // abort.
     _LIBUNWIND_DEBUG_LOG("failed to call __arm_za_disable in %s", __FUNCTION__);
   }
 #endif



More information about the cfe-commits mailing list