Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251208174940.949856-12-bill.roberts@arm.com>
Date: Mon,  8 Dec 2025 11:44:54 -0600
From: Bill Roberts <bill.roberts@....com>
To: musl@...ts.openwall.com
Cc: Bill Roberts <bill.roberts@....com>
Subject: [RFC 11/14] aarch64: rewrite sigsetjmp routines in C using inline asm

Rewrite the AArch64 __sigsetjmp, and sigsetjmp routines from assembly into
implementations using inline assembly.

This change eliminates the need for handwritten function prologues and
epilogues in sigsetjmp.s, which simplifies maintenance and allows the compiler
to automatically insert architecture features such as BTI landing pads and
pointer authentication (PAC) sequences where applicable.

Moving to C also enables the compiler to manage register allocation,
stack usage, and ABI compliance automatically while keeping the low-level
behavior (bitmasks and register accesses) explicit and verifiable.

No functional changes intended.

Signed-off-by: Bill Roberts <bill.roberts@....com>
---
 src/signal/aarch64/sigsetjmp.c | 43 ++++++++++++++++++++++++++++++++++
 src/signal/aarch64/sigsetjmp.s | 21 -----------------
 2 files changed, 43 insertions(+), 21 deletions(-)
 create mode 100644 src/signal/aarch64/sigsetjmp.c
 delete mode 100644 src/signal/aarch64/sigsetjmp.s

diff --git a/src/signal/aarch64/sigsetjmp.c b/src/signal/aarch64/sigsetjmp.c
new file mode 100644
index 00000000..3f266bff
--- /dev/null
+++ b/src/signal/aarch64/sigsetjmp.c
@@ -0,0 +1,43 @@
+#include <setjmp.h>
+
+#define OFF_LR 176               /* stored x30 (LR) */
+#define OFF_X19 (OFF_LR + 8 + 8) /* stored x19 */
+
+__attribute__((visibility("hidden")))
+int __sigsetjmp_tail(jmp_buf env, int val);
+
+__attribute__((returns_twice))
+int sigsetjmp(jmp_buf env, int savemask)
+{
+	/* 
+	 * We could do this in a mix of C and asm, but gcc keeps inserting a PAC
+	 * instruction when saving the LR into jmp_buf. So just keep the whole thing
+	 * in asm.
+	 */
+	__asm__ __volatile__(
+		"cbz x1, setjmp\n\t"
+		/* Save x30 (LR) and x19 into the env at the exact offsets; set x19 = env. */
+		"str x30, [x0, #%c[off_lr]]\n\t"
+		"str x19, [x0, #%c[off_x19]]\n\t"
+		"mov x19, x0\n\t"
+		"bl setjmp\n\t"
+#if defined(__ARM_FEATURE_BTI_DEFAULT)        
+		"hint 36\n\t" // bti j
+#endif
+		"mov w1, w0\n\t"
+		"mov x0,x19\n\t"
+		"ldr x30, [x0, #%c[off_lr]]\n\t"
+		"ldr x19, [x0, #%c[off_x19]]\n\t"
+		"b __sigsetjmp_tail\n\t"
+		:
+		: [off_lr]"i"(OFF_LR),
+		  [off_x19]"i"(OFF_X19)
+		: "memory", "cc"
+	);
+	__builtin_unreachable();
+}
+
+/* Export __sigsetjmp as an alias to sigsetjmp (same TU requirement). */
+__attribute__((alias("sigsetjmp"), returns_twice))
+int __sigsetjmp(jmp_buf, int);
+
diff --git a/src/signal/aarch64/sigsetjmp.s b/src/signal/aarch64/sigsetjmp.s
deleted file mode 100644
index 75910c43..00000000
--- a/src/signal/aarch64/sigsetjmp.s
+++ /dev/null
@@ -1,21 +0,0 @@
-.global sigsetjmp
-.global __sigsetjmp
-.type sigsetjmp,%function
-.type __sigsetjmp,%function
-sigsetjmp:
-__sigsetjmp:
-	cbz x1,setjmp
-
-	str x30,[x0,#176]
-	str x19,[x0,#176+8+8]
-	mov x19,x0
-
-	bl setjmp
-
-	mov w1,w0
-	mov x0,x19
-	ldr x30,[x0,#176]
-	ldr x19,[x0,#176+8+8]
-
-.hidden __sigsetjmp_tail
-	b __sigsetjmp_tail
-- 
2.51.0

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.