Skip to content

Commit f7ae58c

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 4678f16 commit f7ae58c

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
@@ -202,6 +202,10 @@ unwind_phase1(unw_context_t *uc, unw_cursor_t *cursor, _Unwind_Exception *except
202202
}
203203
extern int __unw_step_stage2(unw_cursor_t *);
204204

205+
#if defined(__aarch64__)
206+
extern void __attribute__((weak)) __arm_za_disable(void);
207+
#endif
208+
205209
#if defined(_LIBUNWIND_USE_GCS)
206210
// Enable the GCS target feature to permit gcspop instructions to be used.
207211
__attribute__((target("+gcs")))
@@ -214,6 +218,29 @@ unwind_phase2(unw_context_t *uc, unw_cursor_t *cursor,
214218
_LIBUNWIND_TRACE_UNWINDING("unwind_phase2(ex_obj=%p)",
215219
(void *)exception_object);
216220

221+
#if defined(__aarch64__)
222+
// The platform must ensure that all the following conditions are true on
223+
// entry to EH:
224+
//
225+
// - PSTATE.SM is 0.
226+
// - PSTATE.ZA is 0.
227+
// - TPIDR2_EL0 is null.
228+
//
229+
// The first point is ensured by routines for throwing exceptions having a
230+
// non-streaming interface. TPIDR2_EL0 is set to null and ZA disabled by
231+
// calling __arm_za_disable.
232+
//
233+
// See:
234+
// https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#exceptions
235+
if (__arm_za_disable) {
236+
// FIXME: Is SME is available and `__arm_za_disable` is not, this should
237+
// abort.
238+
__arm_za_disable();
239+
} else {
240+
_LIBUNWIND_DEBUG_LOG("failed to call __arm_za_disable in %s", __FUNCTION__);
241+
}
242+
#endif
243+
217244
// uc is initialized by __unw_getcontext in the parent frame. The first stack
218245
// frame walked is unwind_phase2.
219246
unsigned framesWalked = 1;

0 commit comments

Comments
 (0)