]> gcc.gnu.org Git - gcc.git/commitdiff
libgcc: aarch64: Add SME unwinder support
authorSzabolcs Nagy <szabolcs.nagy@arm.com>
Fri, 29 Sep 2023 12:55:51 +0000 (13:55 +0100)
committerSzabolcs Nagy <szabolcs.nagy@arm.com>
Fri, 8 Dec 2023 11:29:07 +0000 (11:29 +0000)
To support the ZA lazy save scheme, the PCS requires the unwinder to
reset the SME state to PSTATE.SM=0, PSTATE.ZA=0, TPIDR2_EL0=0 on entry
to an exception handler. We use the __arm_za_disable SME runtime call
unconditionally to achieve this.
https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#exceptions

The hidden alias is used to avoid a PLT and avoid inconsistent VPCS
marking (we don't rely on special PCS at the call site). In case of
static linking the SME runtime init code is linked in code that raises
exceptions.

libgcc/ChangeLog:

* config/aarch64/__arm_za_disable.S: Add hidden alias.
* config/aarch64/aarch64-unwind.h: Reset the SME state before
EH return via the _Unwind_Frames_Extra hook.

libgcc/config/aarch64/__arm_za_disable.S
libgcc/config/aarch64/aarch64-unwind.h

index cff5b9cec47e2c800ecc63f09a132852ef2a4195..03fc28a393177fda92249a24a6dc7ea8d6957690 100644 (file)
@@ -63,3 +63,8 @@ ENTRY (__arm_za_disable)
 L(end):
        ret
 END (__arm_za_disable)
+
+/* Hidden alias used by the unwinder.  */
+.global __libgcc_arm_za_disable
+.hidden __libgcc_arm_za_disable
+.set __libgcc_arm_za_disable, __arm_za_disable
index d669edd671b49c44b73dca412384596228d5e972..9fe6c8f61c35adf230daf7e6bd9fdcc9e3aa94f1 100644 (file)
@@ -78,4 +78,20 @@ aarch64_demangle_return_addr (struct _Unwind_Context *context,
   return addr;
 }
 
+/* SME runtime function local to libgcc, streaming compatible
+   and preserves more registers than the base PCS requires, but
+   we don't rely on that here.  */
+__attribute__ ((visibility ("hidden")))
+void __libgcc_arm_za_disable (void);
+
+/* Disable the SME ZA state in case an unwound frame used the ZA
+   lazy saving scheme.  */
+#undef _Unwind_Frames_Extra
+#define _Unwind_Frames_Extra(x)                                \
+  do                                                   \
+    {                                                  \
+      __libgcc_arm_za_disable ();                      \
+    }                                                  \
+  while (0)
+
 #endif /* defined AARCH64_UNWIND_H && defined __ILP32__ */
This page took 0.059916 seconds and 5 git commands to generate.