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-6-bill.roberts@arm.com>
Date: Mon,  8 Dec 2025 11:44:48 -0600
From: Bill Roberts <bill.roberts@....com>
To: musl@...ts.openwall.com
Cc: Bill Roberts <bill.roberts@....com>
Subject: [RFC 05/14] aarch64: rewrite __syscall_cp_asm in C using inline asm

Rewrite the AArch64 __syscall_cp_asm routine from assembly into
C implementations using inline assembly.

This change eliminates the need for handwritten function prologues and
epilogues in syscall_cp.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/thread/aarch64/syscall_cp.c | 61 +++++++++++++++++++++++++++++++++
 src/thread/aarch64/syscall_cp.s | 32 -----------------
 2 files changed, 61 insertions(+), 32 deletions(-)
 create mode 100644 src/thread/aarch64/syscall_cp.c
 delete mode 100644 src/thread/aarch64/syscall_cp.s

diff --git a/src/thread/aarch64/syscall_cp.c b/src/thread/aarch64/syscall_cp.c
new file mode 100644
index 00000000..d350be8f
--- /dev/null
+++ b/src/thread/aarch64/syscall_cp.c
@@ -0,0 +1,61 @@
+// __syscall_cp_asm(&self->cancel, nr, u, v, w, x, y, z)
+//                  x0             x1  x2 x3 x4 x5 x6 x7
+
+// syscall(nr, u, v, w, x, y, z)
+//         x8  x0 x1 x2 x3 x4 x5
+
+__attribute__((visibility("hidden")))
+long __syscall_cp_asm(volatile int *cancel, long nr,
+					  long a0, long a1, long a2, long a3, long a4, long a5)
+{
+	long ret;
+
+	__asm__ volatile(
+		// BEGIN marker
+		".globl __cp_begin\n\t"
+		".hidden __cp_begin\n\t"
+		"__cp_begin:\n\t"
+
+		"ldr  w0, [x0]\n\t"              // if (*cancel) goto __cp_cancel
+		"cbnz w0, __cp_cancel\n\t"
+
+		// Pack syscall args:
+		//   syscall(nr, u, v, w, x, y, z)
+		//           x8  x0 x1 x2 x3 x4 x5
+		// currently:
+		//   x1 = nr
+		//   x2..x7 = a0..a5
+		"mov  x8, x1\n\t"
+		"mov  x0, x2\n\t"
+		"mov  x1, x3\n\t"
+		"mov  x2, x4\n\t"
+		"mov  x3, x5\n\t"
+		"mov  x4, x6\n\t"
+		"mov  x5, x7\n\t"
+		"svc  #0\n"
+
+		// END marker
+		".globl __cp_end\n\t"
+		".hidden __cp_end\n\t"
+		"__cp_end:\n\t"
+
+		// Save syscall result from x0 into a C variable.
+		"mov  %0, x0\n\t"
+		: "=r"(ret)
+		: /* all inputs are already in x0..x7 per the ABI */
+		: "x0","x1","x2","x3","x4","x5","x6","x7",
+		  "x8","memory","cc"
+	);
+
+	return ret;
+}
+
+
+__attribute__((visibility("hidden")))
+long __cancel(void);
+
+__attribute__((visibility("hidden")))
+long __cp_cancel(void)
+{
+	return __cancel();
+}
diff --git a/src/thread/aarch64/syscall_cp.s b/src/thread/aarch64/syscall_cp.s
deleted file mode 100644
index 41db68af..00000000
--- a/src/thread/aarch64/syscall_cp.s
+++ /dev/null
@@ -1,32 +0,0 @@
-// __syscall_cp_asm(&self->cancel, nr, u, v, w, x, y, z)
-//                  x0             x1  x2 x3 x4 x5 x6 x7
-
-// syscall(nr, u, v, w, x, y, z)
-//         x8  x0 x1 x2 x3 x4 x5
-
-.global __cp_begin
-.hidden __cp_begin
-.global __cp_end
-.hidden __cp_end
-.global __cp_cancel
-.hidden __cp_cancel
-.hidden __cancel
-.global __syscall_cp_asm
-.hidden __syscall_cp_asm
-.type __syscall_cp_asm,%function
-__syscall_cp_asm:
-__cp_begin:
-	ldr w0,[x0]
-	cbnz w0,__cp_cancel
-	mov x8,x1
-	mov x0,x2
-	mov x1,x3
-	mov x2,x4
-	mov x3,x5
-	mov x4,x6
-	mov x5,x7
-	svc 0
-__cp_end:
-	ret
-__cp_cancel:
-	b __cancel
-- 
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.