Skip to content

Commit 33dc84e

Browse files
committed
[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).
1 parent 03742c5 commit 33dc84e

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

libunwind/src/UnwindLevel1.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,10 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
186186
}
187187
extern int __unw_step_stage2(unw_cursor_t *);
188188

189+
#if defined(__aarch64__)
190+
extern void __attribute__((weak)) __arm_za_disable(void);
191+
#endif
192+
189193
#if defined(_LIBUNWIND_USE_GCS)
190194
// Enable the GCS target feature to permit gcspop instructions to be used.
191195
__attribute__((target("+gcs")))
@@ -198,6 +202,29 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor,
198202
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_obj=%p)",
199203
(void *)exception_object);
200204

205+
#if defined(__aarch64__)
206+
// The platform must ensure that all the following conditions are true on
207+
// entry to EH:
208+
//
209+
// - PSTATE.SM is 0.
210+
// - PSTATE.ZA is 0.
211+
// - TPIDR2_EL0 is null.
212+
//
213+
// The first point is ensured by routines for throwing exceptions having a
214+
// non-streaming interface. TPIDR2_EL0 is set to null and ZA disabled by
215+
// calling __arm_za_disable.
216+
//
217+
// See:
218+
// https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#exceptions
219+
if (__arm_za_disable) {
220+
// FIXME: Is SME is available and `__arm_za_disable` is not, this should
221+
// abort.
222+
__arm_za_disable();
223+
} else {
224+
_LIBUNWIND_DEBUG_LOG("failed to call __arm_za_disable in %s", __FUNCTION__);
225+
}
226+
#endif
227+
201228
// uc is initialized by __unw_getcontext in the parent frame. The first stack
202229
// frame walked is unwind_phase2.
203230
unsigned framesWalked = 1;

0 commit comments

Comments
 (0)