about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
authorCarlos Eduardo Seo <carlos.seo@arm.com>2021-04-08 12:49:27 -0300
committerSzabolcs Nagy <szabolcs.nagy@arm.com>2022-08-05 19:45:19 +0100
commitff371935db74c2d387b18a98e65181f615c69d62 (patch)
treeb0c67116a481388ff9fba65f51f3156be61e1d38 /sysdeps
parent9ef71c0be0d8b7f50f987d2d96198757e4356ad5 (diff)
downloadglibc-ff371935db74c2d387b18a98e65181f615c69d62.tar.gz
glibc-ff371935db74c2d387b18a98e65181f615c69d62.tar.xz
glibc-ff371935db74c2d387b18a98e65181f615c69d62.zip
aarch64: morello: add purecap syscall support
Support the Morello Linux purecap syscall ABI.  The macro definitions
are moved to a morello specific sysdep.h to avoid cluttering the
aarch64 one.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/clone.S68
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/ioctl.S5
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/morello/sysdep.h116
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/syscall.S12
4 files changed, 185 insertions, 16 deletions
diff --git a/sysdeps/unix/sysv/linux/aarch64/clone.S b/sysdeps/unix/sysv/linux/aarch64/clone.S
index ad80ac829c..663853ab4a 100644
--- a/sysdeps/unix/sysv/linux/aarch64/clone.S
+++ b/sysdeps/unix/sysv/linux/aarch64/clone.S
@@ -23,41 +23,77 @@
 #define _ERRNO_H	1
 #include <bits/errno.h>
 
-/* int clone(int (*fn)(void *arg),            x0
-	     void *child_stack,               x1
-	     int flags,                       x2
-	     void *arg,                       x3
-	     pid_t *ptid,                     x4
-	     struct user_desc *tls,           x5
-             pid_t *ctid);                    x6
+#ifdef __CHERI_PURE_CAPABILITY__
+# define arg0	c0
+# define arg1	c1
+# define arg2	c2
+# define arg3	c3
+# define arg4	c4
+# define arg5	c5
+# define arg6	c6
+# define tmp0	c10
+# define tmp1	c11
+# define tmp2	c12
+#else
+# define arg0	x0
+# define arg1	x1
+# define arg2	x2
+# define arg3	x3
+# define arg4	x4
+# define arg5	x5
+# define arg6	x6
+# define tmp0	x10
+# define tmp1	x11
+# define tmp2	x12
+#endif
+
+/* int clone(int (*fn)(void *arg),            arg0
+	     void *child_stack,               arg1
+	     int flags,                       arg2
+	     void *arg,                       arg3
+	     pid_t *ptid,                     arg4
+	     struct user_desc *tls,           arg5
+             pid_t *ctid);                    arg6
  */
         .text
 ENTRY(__clone)
+#ifndef __CHERI_PURE_CAPABILITY__
 	PTR_ARG (0)
 	PTR_ARG (1)
 	PTR_ARG (3)
 	PTR_ARG (4)
 	PTR_ARG (5)
 	PTR_ARG (6)
+#else
+	cbz	x9, L(skip_args)
+	ldr	c4, [c9]
+	ldr	c5, [c9,16]
+	ldr	c6, [c9,32]
+L(skip_args):
+#endif
 	/* Save args for the child.  */
-	mov	x10, x0
-	mov	x11, x2
-	mov	x12, x3
+	mov	tmp0, arg0
+	mov	tmp1, arg2
+	mov	tmp2, arg3
 
 	/* Sanity check args.  */
 	mov	x0, #-EINVAL
 	cbz	x10, .Lsyscall_error
 	/* Align sp.  */
+#ifndef __CHERI_PURE_CAPABILITY__
 	and	x1, x1, -16
+#else
+	alignd	c1, c1, 4
+#endif
 	cbz	x1, .Lsyscall_error
 
 	/* Do the system call.  */
 	/* X0:flags, x1:newsp, x2:parenttidptr, x3:newtls, x4:childtid.  */
-	mov	x0, x2                  /* flags  */
+	mov	arg0, arg2                  /* flags  */
 	/* New sp is already in x1.  */
-	mov	x2, x4			/* ptid  */
-	mov	x3, x5			/* tls  */
-	mov	x4, x6			/* ctid  */
+	mov	arg2, arg4			/* ptid  */
+	mov	arg3, arg5			/* tls  */
+	mov	arg4, arg6			/* ctid  */
 	mov	x8, #SYS_ify(clone)
 	svc	0x0
 
@@ -75,8 +111,8 @@ thread_start:
 	mov	x29, 0
 
 	/* Pick the function arg and execute.  */
-	mov	x0, x12
-	blr	x10
+	mov	arg0, tmp2
+	blr	tmp0
 
 	/* We are done, pass the return value through x0.  */
 	mov	x8, #SYS_ify(exit)
diff --git a/sysdeps/unix/sysv/linux/aarch64/ioctl.S b/sysdeps/unix/sysv/linux/aarch64/ioctl.S
index eb2f7211d7..88c8143452 100644
--- a/sysdeps/unix/sysv/linux/aarch64/ioctl.S
+++ b/sysdeps/unix/sysv/linux/aarch64/ioctl.S
@@ -22,6 +22,11 @@
 ENTRY(__ioctl)
 	mov	x8, #__NR_ioctl
 	sxtw	x0, w0
+#ifdef __CHERI_PURE_CAPABILITY__
+	cbz	x9, L(skip_arg3)
+	ldr	c2, [c9]
+L(skip_arg3):
+#endif
 	svc	#0x0
 	cmn	x0, #4095
 	b.cs	.Lsyscall_error
diff --git a/sysdeps/unix/sysv/linux/aarch64/morello/sysdep.h b/sysdeps/unix/sysv/linux/aarch64/morello/sysdep.h
new file mode 100644
index 0000000000..5db89b096d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/aarch64/morello/sysdep.h
@@ -0,0 +1,116 @@
+/* Copyright (C) 2022 Free Software Foundation, Inc.
+
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _LINUX_AARCH64_MORELLO_SYSDEP_H
+#define _LINUX_AARCH64_MORELLO_SYSDEP_H 1
+
+#include <sysdeps/unix/sysv/linux/aarch64/sysdep.h>
+
+#ifdef __ASSEMBLER__
+# if !IS_IN (libc)
+#  undef SYSCALL_ERROR_HANDLER
+#  if RTLD_PRIVATE_ERRNO
+#   define SYSCALL_ERROR_HANDLER				\
+.Lsyscall_error:						\
+	neg     w0, w0;						\
+	adrp    c1, :got:rtld_errno;				\
+	ldr     c1, [c1, :got_lo12:rtld_errno];			\
+	str     w0, [c1];					\
+	mov	x0, -1;						\
+	RET;
+#  else
+#   define SYSCALL_ERROR_HANDLER				\
+.Lsyscall_error:						\
+	neg	w4, w0;						\
+	adrp	c1, :gottprel:errno;				\
+	add	c1, c1, :gottprel_lo12:errno;			\
+	ldp	x1, x2, [c1];					\
+	mrs	c3, ctpidr_el0;					\
+	add	c1, c3, x1, uxtx;				\
+	scbnds	c1, c1, x2;					\
+	mov	x0, -1;						\
+	str	w4, [c1];					\
+	RET;
+#  endif
+# endif
+
+#else /* not __ASSEMBLER__ */
+
+typedef __intcap_t __sysarg_t;
+
+# undef INTERNAL_SYSCALL_RAW
+# define INTERNAL_SYSCALL_RAW(name, nr, args...)		\
+  ({ __sysarg_t _sys_result;						\
+     {								\
+       LOAD_ARGS_##nr (args)					\
+       register long _x8 asm ("x8") = (name);			\
+       asm volatile ("svc	0	// syscall " # name     \
+		     : "=r" (_x0) : "r"(_x8) ASM_ARGS_##nr : "memory");	\
+       _sys_result = _x0;					\
+     }								\
+     _sys_result; })
+
+# undef LOAD_ARGS_0
+# undef LOAD_ARGS_1
+# undef LOAD_ARGS_2
+# undef LOAD_ARGS_3
+# undef LOAD_ARGS_4
+# undef LOAD_ARGS_5
+# undef LOAD_ARGS_6
+# undef LOAD_ARGS_7
+
+# define LOAD_ARGS_0()				\
+  register __sysarg_t _x0 asm ("c0");
+# define LOAD_ARGS_1(c0)			\
+  __sysarg_t _x0tmp = (__sysarg_t) (c0);	\
+  LOAD_ARGS_0 ()				\
+  _x0 = _x0tmp;
+# define LOAD_ARGS_2(c0, c1)			\
+  __sysarg_t _x1tmp = (__sysarg_t) (c1);	\
+  LOAD_ARGS_1 (c0)				\
+  register __sysarg_t _x1 asm ("c1") = _x1tmp;
+# define LOAD_ARGS_3(c0, c1, c2)		\
+  __sysarg_t _x2tmp = (__sysarg_t) (c2);	\
+  LOAD_ARGS_2 (c0, c1)				\
+  register __sysarg_t _x2 asm ("c2") = _x2tmp;
+# define LOAD_ARGS_4(c0, c1, c2, c3)		\
+  __sysarg_t _x3tmp = (__sysarg_t) (c3);	\
+  LOAD_ARGS_3 (c0, c1, c2)			\
+  register __sysarg_t _x3 asm ("c3") = _x3tmp;
+# define LOAD_ARGS_5(c0, c1, c2, c3, c4)	\
+  __sysarg_t _x4tmp = (__sysarg_t) (c4);	\
+  LOAD_ARGS_4 (c0, c1, c2, c3)			\
+  register __sysarg_t _x4 asm ("c4") = _x4tmp;
+# define LOAD_ARGS_6(c0, c1, c2, c3, c4, c5)	\
+  __sysarg_t _x5tmp = (__sysarg_t) (c5);	\
+  LOAD_ARGS_5 (c0, c1, c2, c3, c4)		\
+  register __sysarg_t _x5 asm ("c5") = _x5tmp;
+# define LOAD_ARGS_7(c0, c1, c2, c3, c4, c5, c6)\
+  __sysarg_t _x6tmp = (__sysarg_t) (x6);	\
+  LOAD_ARGS_6 (c0, c1, c2, c3, c4, c5)		\
+  register __sysarg_t _x6 asm ("c6") = _x6tmp;
+
+#endif	/* __ASSEMBLER__ */
+
+/* Disable pointer mangling for purecap ABI.  */
+#undef PTR_MANGLE
+#undef PTR_MANGLE2
+#undef PTR_DEMANGLE
+#undef PTR_DEMANGLE2
+
+#endif /* linux/aarch64/morello/sysdep.h */
diff --git a/sysdeps/unix/sysv/linux/aarch64/syscall.S b/sysdeps/unix/sysv/linux/aarch64/syscall.S
index 9ddecb21c3..ec4688433d 100644
--- a/sysdeps/unix/sysv/linux/aarch64/syscall.S
+++ b/sysdeps/unix/sysv/linux/aarch64/syscall.S
@@ -28,6 +28,17 @@
 
 ENTRY (syscall)
 	uxtw	x8, w0
+#ifdef __CHERI_PURE_CAPABILITY__
+	cbz	x9, L(skip_args)
+	ldr	c0, [c9]
+	ldr	c1, [c9,16]
+	ldr	c2, [c9,32]
+	ldr	c3, [c9,48]
+	ldr	c4, [c9,64]
+	ldr	c5, [c9,80]
+	ldr	c6, [c9,96]
+L(skip_args):
+#else
 	mov	x0, x1
 	mov	x1, x2
 	mov	x2, x3
@@ -35,6 +46,7 @@ ENTRY (syscall)
 	mov	x4, x5
 	mov	x5, x6
 	mov	x6, x7
+#endif
 	svc	0x0
 	cmn	x0, #4095
 	b.cs	1f