public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Palmer Dabbelt <palmer@dabbelt.com>
To: libc-alpha@sourceware.org, joseph@codesourcery.com
Cc: patches@groups.riscv.org, Andrew Waterman <andrew@sifive.com>,
	dj@redhat.com, Darius Rad <darius@bluespec.com>,
	Palmer Dabbelt <palmer@dabbelt.com>
Subject: [PATCH v6 11/16] RISC-V: Linux Syscall Interface
Date: Fri, 26 Jan 2018 05:45:00 -0000	[thread overview]
Message-ID: <20180126054443.22702-12-palmer@dabbelt.com> (raw)
In-Reply-To: <20180126054443.22702-1-palmer@dabbelt.com>

Contains the Linux system call interface, as well as the definitions of
a handful of system calls.
---
 sysdeps/riscv/nptl/nptl-sysdep.S               |   2 +
 sysdeps/unix/sysv/linux/riscv/arch-fork.h      |  26 ++
 sysdeps/unix/sysv/linux/riscv/clone.S          |  86 +++++++
 sysdeps/unix/sysv/linux/riscv/profil-counter.h |  31 +++
 sysdeps/unix/sysv/linux/riscv/pt-vfork.S       |   1 +
 sysdeps/unix/sysv/linux/riscv/syscall.c        |  35 +++
 sysdeps/unix/sysv/linux/riscv/sysdep.S         |  51 ++++
 sysdeps/unix/sysv/linux/riscv/sysdep.h         | 322 +++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/vfork.S          |  44 ++++
 9 files changed, 598 insertions(+)
 create mode 100644 sysdeps/riscv/nptl/nptl-sysdep.S
 create mode 100644 sysdeps/unix/sysv/linux/riscv/arch-fork.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/clone.S
 create mode 100644 sysdeps/unix/sysv/linux/riscv/profil-counter.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/pt-vfork.S
 create mode 100644 sysdeps/unix/sysv/linux/riscv/syscall.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/sysdep.S
 create mode 100644 sysdeps/unix/sysv/linux/riscv/sysdep.h
 create mode 100644 sysdeps/unix/sysv/linux/riscv/vfork.S

diff --git a/sysdeps/riscv/nptl/nptl-sysdep.S b/sysdeps/riscv/nptl/nptl-sysdep.S
new file mode 100644
index 000000000000..3f5c2a364afd
--- /dev/null
+++ b/sysdeps/riscv/nptl/nptl-sysdep.S
@@ -0,0 +1,2 @@
+/* Pull in __syscall_error.  */
+#include <sysdep.S>
diff --git a/sysdeps/unix/sysv/linux/riscv/arch-fork.h b/sysdeps/unix/sysv/linux/riscv/arch-fork.h
new file mode 100644
index 000000000000..f6f5d733439b
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/arch-fork.h
@@ -0,0 +1,26 @@
+/* Internal definitions for thread-friendly fork implementation.  Linux/RISC-V.
+   Copyright (C) 2002-2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sched.h>
+#include <sysdep.h>
+#include <tls.h>
+
+#define ARCH_FORK() \
+  INLINE_SYSCALL (clone, 5,						      \
+		  CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0,     \
+		  NULL, NULL, &THREAD_SELF->tid)
diff --git a/sysdeps/unix/sysv/linux/riscv/clone.S b/sysdeps/unix/sysv/linux/riscv/clone.S
new file mode 100644
index 000000000000..392af72b55da
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/clone.S
@@ -0,0 +1,86 @@
+/* Wrapper around clone system call.  RISC-V version.
+   Copyright (C) 1996-2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+/* clone() is even more special than fork() as it mucks with stacks
+   and invokes a function in the right context after its all over.  */
+
+#include <sys/asm.h>
+#include <sysdep.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+#include <tls.h>
+#include "tcb-offsets.h"
+
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+	     void *parent_tidptr, void *tls, void *child_tidptr) */
+
+	.text
+LEAF (__clone)
+
+	/* Sanity check arguments.  */
+	beqz		a0,L (invalid)	/* No NULL function pointers.  */
+	beqz		a1,L (invalid)	/* No NULL stack pointers.  */
+
+	addi		a1,a1,-16	/* Reserve argument save space.  */
+	REG_S		a0,0(a1)	/* Save function pointer.  */
+	REG_S		a3,SZREG(a1)	/* Save argument pointer.  */
+
+	/* The syscall expects the args to be in different slots.  */
+	mv		a0,a2
+	mv		a2,a4
+	mv		a3,a5
+	mv		a4,a6
+
+	/* Do the system call.  */
+	li		a7,__NR_clone
+	scall
+
+	bltz		a0,L (error)
+	beqz		a0,L (thread_start)
+
+	/* Successful return from the parent.  */
+	ret
+
+L (invalid):
+	li		a0, -EINVAL
+	/* Something bad happened -- no child created.  */
+L (error):
+	j		__syscall_error
+	END (__clone)
+
+/* Load up the arguments to the function.  Put this block of code in
+   its own function so that we can terminate the stack trace with our
+   debug info.  */
+
+ENTRY (__thread_start)
+L (thread_start):
+	/* Restore the arg for user's function.  */
+	REG_L		a1,0(sp)	/* Function pointer.  */
+	REG_L		a0,SZREG(sp)	/* Argument pointer.  */
+
+	/* Call the user's function.  */
+	jalr		a1
+
+	/* Call exit with the function's return value.  */
+	li		a7, __NR_exit
+	scall
+
+	END (__thread_start)
+
+libc_hidden_def (__clone)
+weak_alias (__clone, clone)
diff --git a/sysdeps/unix/sysv/linux/riscv/profil-counter.h b/sysdeps/unix/sysv/linux/riscv/profil-counter.h
new file mode 100644
index 000000000000..748019ee1b9d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/profil-counter.h
@@ -0,0 +1,31 @@
+/* Low-level statistical profiling support function.  Linux/RISC-V version.
+   Copyright (C) 1996-2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <signal.h>
+#include <sigcontextinfo.h>
+
+static void
+__profil_counter (int signo, const SIGCONTEXT scp)
+{
+  profil_count ((void *) GET_PC (scp));
+
+  /* This is a hack to prevent the compiler from implementing the
+     above function call as a sibcall.  The sibcall would overwrite
+     the signal context.  */
+  asm volatile ("");
+}
diff --git a/sysdeps/unix/sysv/linux/riscv/pt-vfork.S b/sysdeps/unix/sysv/linux/riscv/pt-vfork.S
new file mode 100644
index 000000000000..1cc893170070
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/pt-vfork.S
@@ -0,0 +1 @@
+/* Not needed.  */
diff --git a/sysdeps/unix/sysv/linux/riscv/syscall.c b/sysdeps/unix/sysv/linux/riscv/syscall.c
new file mode 100644
index 000000000000..6589dde385e0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/syscall.c
@@ -0,0 +1,35 @@
+/* system call interface.  Linux/RISC-V version.
+   Copyright (C) 2001-2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+long int
+syscall (long int syscall_number, long int arg1, long int arg2, long int arg3,
+	 long int arg4, long int arg5, long int arg6, long int arg7)
+{
+  long int ret;
+  INTERNAL_SYSCALL_DECL (err);
+
+  ret = INTERNAL_SYSCALL_NCS (syscall_number, err, 7, arg1, arg2, arg3, arg4,
+			      arg5, arg6, arg7);
+
+  if (INTERNAL_SYSCALL_ERROR_P (ret, err))
+    return __syscall_error (ret);
+
+  return ret;
+}
diff --git a/sysdeps/unix/sysv/linux/riscv/sysdep.S b/sysdeps/unix/sysv/linux/riscv/sysdep.S
new file mode 100644
index 000000000000..0d9c0b5bd907
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sysdep.S
@@ -0,0 +1,51 @@
+/* syscall error handlers
+   Copyright (C) 2011-2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdep.h>
+
+#if IS_IN (libc)
+# define errno __libc_errno
+#endif
+
+ENTRY (__syscall_error)
+	mv t0, ra
+	/* Fall through to __syscall_set_errno.  */
+END (__syscall_error)
+
+/* Non-standard calling convention: argument in a0, return address in t0,
+   and clobber only t1.  */
+ENTRY (__syscall_set_errno)
+	/* We got here because a0 < 0, but only codes in the range [-4095, -1]
+	  represent errors.  Otherwise, just return the result normally.  */
+	li t1, -4096
+	bleu a0, t1, 1f
+	neg a0, a0
+#if RTLD_PRIVATE_ERRNO
+	sw a0, rtld_errno, t1
+#elif defined(__PIC__)
+	la.tls.ie t1, errno
+	add t1, t1, tp
+	sw a0, 0(t1)
+#else
+	lui t1, %tprel_hi(errno)
+	add t1, t1, tp, %tprel_add(errno)
+	sw a0, %tprel_lo(errno)(t1)
+#endif
+	li a0, -1
+1:	jr t0
+END (__syscall_set_errno)
diff --git a/sysdeps/unix/sysv/linux/riscv/sysdep.h b/sysdeps/unix/sysv/linux/riscv/sysdep.h
new file mode 100644
index 000000000000..3fc19ebc5185
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sysdep.h
@@ -0,0 +1,322 @@
+/* Assembly macros for RISC-V.
+   Copyright (C) 2011-2018
+   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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _LINUX_RISCV_SYSDEP_H
+#define _LINUX_RISCV_SYSDEP_H 1
+
+#include <sysdeps/unix/sysv/linux/generic/sysdep.h>
+#include <tls.h>
+
+#ifdef __ASSEMBLER__
+
+# include <sys/asm.h>
+
+# define ENTRY(name) LEAF(name)
+
+# define L(label) .L ## label
+
+/* Performs a system call, handling errors by setting errno.  Linux indicates
+   errors by setting a0 to a value between -1 and -4095.  */
+# undef PSEUDO
+# define PSEUDO(name, syscall_name, args)			\
+  .text;							\
+  .align 2;							\
+  ENTRY (name);							\
+  li a7, SYS_ify (syscall_name);				\
+  scall;							\
+  li a7, -4096;							\
+  bgtu a0, a7, .Lsyscall_error ## name;
+
+# undef PSEUDO_END
+# define PSEUDO_END(sym) 					\
+  SYSCALL_ERROR_HANDLER (sym)					\
+  ret;								\
+  END (sym)
+
+# if !IS_IN (libc)
+#  if RTLD_PRIVATE_ERRNO
+#   define SYSCALL_ERROR_HANDLER(name)				\
+.Lsyscall_error ## name:					\
+	li t1, -4096;						\
+        sw a0, rtld_errno, t1;					\
+        li a0, -1;
+#  elif defined (__PIC__)
+#   define SYSCALL_ERROR_HANDLER(name)				\
+.Lsyscall_error ## name:					\
+        la.tls.ie t1, errno;					\
+	add t1, t1, tp;						\
+	sw a0, 0(t1);						\
+        li a0, -1;
+#  else
+#   define SYSCALL_ERROR_HANDLER(name)				\
+.Lsyscall_error ## name:					\
+        lui t1, %tprel_hi(errno);				\
+        add t1, t1, tp, %tprel_add(errno);			\
+        sw a0, %tprel_lo(errno)(t1);				\
+        li a0, -1;
+#  endif
+# else
+#  define SYSCALL_ERROR_HANDLER(name)				\
+.Lsyscall_error ## name:					\
+        j       __syscall_error;
+# endif
+
+/* Performs a system call, not setting errno.  */
+# undef PSEUDO_NEORRNO
+# define PSEUDO_NOERRNO(name, syscall_name, args)	\
+  .align 2;						\
+  ENTRY (name);						\
+  li a7, SYS_ify (syscall_name);			\
+  scall;
+
+# undef PSEUDO_END_NOERRNO
+# define PSEUDO_END_NOERRNO(name)			\
+  END (name)
+
+# undef ret_NOERRNO
+# define ret_NOERRNO ret
+
+/* Perfroms a system call, returning the error code.  */
+# undef PSEUDO_ERRVAL
+# define PSEUDO_ERRVAL(name, syscall_name, args) 	\
+  PSEUDO_NOERRNO (name, syscall_name, args)		\
+  neg a0, a0;
+
+# undef PSEUDO_END_ERRVAL
+# define PSEUDO_END_ERRVAL(name)			\
+  END (name)
+
+# undef ret_ERRVAL
+# define ret_ERRVAL ret
+
+#endif /* __ASSEMBLER__ */
+
+/* In order to get __set_errno() definition in INLINE_SYSCALL.  */
+#ifndef __ASSEMBLER__
+# include <errno.h>
+#endif
+
+#include <sysdeps/unix/sysdep.h>
+
+#undef SYS_ify
+#define SYS_ify(syscall_name)	__NR_##syscall_name
+
+#ifndef __ASSEMBLER__
+
+/* List of system calls which are supported as vsyscalls.  */
+# define HAVE_CLOCK_GETRES_VSYSCALL	1
+# define HAVE_CLOCK_GETTIME_VSYSCALL	1
+# define HAVE_GETTIMEOFDAY_VSYSCALL	1
+# define HAVE_GETCPU_VSYSCALL		1
+
+/* Define a macro which expands into the inline wrapper code for a system
+   call.  */
+# undef INLINE_SYSCALL
+# define INLINE_SYSCALL(name, nr, args...)				\
+  ({ INTERNAL_SYSCALL_DECL (err);					\
+     long int __sys_result = INTERNAL_SYSCALL (name, err, nr, args);	\
+     if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (__sys_result, )))  \
+       {								\
+         __set_errno (INTERNAL_SYSCALL_ERRNO (__sys_result, ));		\
+	 __sys_result = (unsigned long) -1;				\
+       }								\
+     __sys_result; })
+
+# define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+
+# define INTERNAL_SYSCALL_ERROR_P(val, err) \
+        ((unsigned long int) (val) > -4096UL)
+
+# define INTERNAL_SYSCALL_ERRNO(val, err)     (-val)
+
+# define INTERNAL_SYSCALL(name, err, nr, args...) \
+	internal_syscall##nr (SYS_ify (name), err, args)
+
+# define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
+	internal_syscall##nr (number, err, args)
+
+# define internal_syscall0(number, err, dummy...)			\
+({ 									\
+	long int _sys_result;						\
+									\
+	{								\
+	register long int __a7 asm ("a7") = number;			\
+	register long int __a0 asm ("a0");				\
+	__asm__ volatile ( 						\
+	"scall\n\t" 							\
+	: "=r" (__a0)							\
+	: "r" (__a7)							\
+	: __SYSCALL_CLOBBERS); 						\
+	_sys_result = __a0;						\
+	}								\
+	_sys_result;							\
+})
+
+# define internal_syscall1(number, err, arg0)				\
+({ 									\
+	long int _sys_result;						\
+									\
+	{								\
+	register long int __a7 asm ("a7") = number;			\
+	register long int __a0 asm ("a0") = (long int) (arg0);		\
+	__asm__ volatile ( 						\
+	"scall\n\t" 							\
+	: "+r" (__a0)							\
+	: "r" (__a7)							\
+	: __SYSCALL_CLOBBERS); 						\
+	_sys_result = __a0;						\
+	}								\
+	_sys_result;							\
+})
+
+# define internal_syscall2(number, err, arg0, arg1)	    		\
+({ 									\
+	long int _sys_result;						\
+									\
+	{								\
+	register long int __a7 asm ("a7") = number;			\
+	register long int __a0 asm ("a0") = (long int) (arg0);		\
+	register long int __a1 asm ("a1") = (long int) (arg1);		\
+	__asm__ volatile ( 						\
+	"scall\n\t" 							\
+	: "+r" (__a0)							\
+	: "r" (__a7), "r" (__a1)					\
+	: __SYSCALL_CLOBBERS); 						\
+	_sys_result = __a0;						\
+	}								\
+	_sys_result;							\
+})
+
+# define internal_syscall3(number, err, arg0, arg1, arg2)      		\
+({ 									\
+	long int _sys_result;						\
+									\
+	{								\
+	register long int __a7 asm ("a7") = number;			\
+	register long int __a0 asm ("a0") = (long int) (arg0);		\
+	register long int __a1 asm ("a1") = (long int) (arg1);		\
+	register long int __a2 asm ("a2") = (long int) (arg2);		\
+	__asm__ volatile ( 						\
+	"scall\n\t" 							\
+	: "+r" (__a0)							\
+	: "r" (__a7), "r" (__a1), "r" (__a2)				\
+	: __SYSCALL_CLOBBERS); 						\
+	_sys_result = __a0;						\
+	}								\
+	_sys_result;							\
+})
+
+# define internal_syscall4(number, err, arg0, arg1, arg2, arg3)	  \
+({ 									\
+	long int _sys_result;						\
+									\
+	{								\
+	register long int __a7 asm ("a7") = number;			\
+	register long int __a0 asm ("a0") = (long int) (arg0);		\
+	register long int __a1 asm ("a1") = (long int) (arg1);		\
+	register long int __a2 asm ("a2") = (long int) (arg2);		\
+	register long int __a3 asm ("a3") = (long int) (arg3);		\
+	__asm__ volatile ( 						\
+	"scall\n\t" 							\
+	: "+r" (__a0)							\
+	: "r" (__a7), "r" (__a1), "r" (__a2), "r" (__a3)		\
+	: __SYSCALL_CLOBBERS); 						\
+	_sys_result = __a0;						\
+	}								\
+	_sys_result;							\
+})
+
+# define internal_syscall5(number, err, arg0, arg1, arg2, arg3, arg4)   \
+({ 									\
+	long int _sys_result;						\
+									\
+	{								\
+	register long int __a7 asm ("a7") = number;			\
+	register long int __a0 asm ("a0") = (long int) (arg0);		\
+	register long int __a1 asm ("a1") = (long int) (arg1);		\
+	register long int __a2 asm ("a2") = (long int) (arg2);		\
+	register long int __a3 asm ("a3") = (long int) (arg3);		\
+	register long int __a4 asm ("a4") = (long int) (arg4);		\
+	__asm__ volatile ( 						\
+	"scall\n\t" 							\
+	: "+r" (__a0)							\
+	: "r" (__a7), "r"(__a1), "r"(__a2), "r"(__a3), "r" (__a4)	\
+	: __SYSCALL_CLOBBERS); 						\
+	_sys_result = __a0;						\
+	}								\
+	_sys_result;							\
+})
+
+# define internal_syscall6(number, err, arg0, arg1, arg2, arg3, arg4, arg5) \
+({ 									\
+	long int _sys_result;						\
+									\
+	{								\
+	register long int __a7 asm ("a7") = number;			\
+	register long int __a0 asm ("a0") = (long int) (arg0);		\
+	register long int __a1 asm ("a1") = (long int) (arg1);		\
+	register long int __a2 asm ("a2") = (long int) (arg2);		\
+	register long int __a3 asm ("a3") = (long int) (arg3);		\
+	register long int __a4 asm ("a4") = (long int) (arg4);		\
+	register long int __a5 asm ("a5") = (long int) (arg5);		\
+	__asm__ volatile ( 						\
+	"scall\n\t" 							\
+	: "+r" (__a0)							\
+	: "r" (__a7), "r" (__a1), "r" (__a2), "r" (__a3),		\
+	  "r" (__a4), "r" (__a5)					\
+	: __SYSCALL_CLOBBERS); 						\
+	_sys_result = __a0;						\
+	}								\
+	_sys_result;							\
+})
+
+# define internal_syscall7(number, err, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
+({ 									\
+	long int _sys_result;						\
+									\
+	{								\
+	register long int __a7 asm ("a7") = number;			\
+	register long int __a0 asm ("a0") = (long int) (arg0);		\
+	register long int __a1 asm ("a1") = (long int) (arg1);		\
+	register long int __a2 asm ("a2") = (long int) (arg2);		\
+	register long int __a3 asm ("a3") = (long int) (arg3);		\
+	register long int __a4 asm ("a4") = (long int) (arg4);		\
+	register long int __a5 asm ("a5") = (long int) (arg5);		\
+	register long int __a6 asm ("a6") = (long int) (arg6);		\
+	__asm__ volatile ( 						\
+	"scall\n\t" 							\
+	: "+r" (__a0)							\
+	: "r" (__a7), "r" (__a1), "r" (__a2), "r" (__a3),		\
+	  "r" (__a4), "r" (__a5), "r" (__a6)				\
+	: __SYSCALL_CLOBBERS); 						\
+	_sys_result = __a0;						\
+	}								\
+	_sys_result;							\
+})
+
+# define __SYSCALL_CLOBBERS "memory"
+
+extern long int __syscall_error (long int neg_errno);
+
+#endif /* ! __ASSEMBLER__ */
+
+/* Pointer mangling is not supported.  */
+#define PTR_MANGLE(var) (void) (var)
+#define PTR_DEMANGLE(var) (void) (var)
+
+#endif /* linux/riscv/sysdep.h */
diff --git a/sysdeps/unix/sysv/linux/riscv/vfork.S b/sysdeps/unix/sysv/linux/riscv/vfork.S
new file mode 100644
index 000000000000..6c53e93a928d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/vfork.S
@@ -0,0 +1,44 @@
+/* vfork for Linux, RISC-V version.
+   Copyright (C) 2005-2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+/* vfork() is just a special case of clone().  */
+
+#include <sys/asm.h>
+#include <sysdep.h>
+#define __ASSEMBLY__
+#include <linux/sched.h>
+#include <asm/signal.h>
+
+	.text
+LEAF (__libc_vfork)
+
+	li	a0, (CLONE_VFORK | CLONE_VM | SIGCHLD)
+	mv	a1, sp
+
+	li	a7, __NR_clone
+	scall
+
+	bltz	a0, 1f
+	ret
+
+1:	j		__syscall_error
+END (__libc_vfork)
+
+weak_alias (__libc_vfork, vfork)
+strong_alias (__libc_vfork, __vfork)
+libc_hidden_def (__vfork)
-- 
2.13.6

  parent reply	other threads:[~2018-01-26  5:45 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-26  5:44 RISC-V glibc port, v6 Palmer Dabbelt
2018-01-26  5:45 ` [PATCH v6 14/16] RISC-V: Add ABI Lists Palmer Dabbelt
2018-01-26  5:45 ` [PATCH v6 08/16] RISC-V: Generic <math.h> and soft-fp Routines Palmer Dabbelt
2018-01-26 13:10   ` Joseph Myers
2018-01-26 18:03     ` Palmer Dabbelt
2018-01-26  5:45 ` [PATCH v6 09/16] RISC-V: Hard Float Support Palmer Dabbelt
2018-01-26  5:45 ` [PATCH v6 07/16] RISC-V: Thread-Local Storage Support Palmer Dabbelt
2018-01-26  5:45 ` [PATCH v6 13/16] RISC-V: Linux Startup and Dynamic Loading Code Palmer Dabbelt
2018-01-26  5:45 ` [PATCH v6 10/16] RISC-V: Atomic and Locking Routines Palmer Dabbelt
2018-01-26  5:45 ` [PATCH v6 01/16] sysdeps/init_array: Add PREINIT_FUNCTION to crti.S Palmer Dabbelt
2018-01-26 12:56   ` Joseph Myers
2018-01-26 17:54     ` Palmer Dabbelt
2018-01-26  5:45 ` [PATCH v6 15/16] RISC-V: Build Infastructure Palmer Dabbelt
2018-01-26 13:15   ` Joseph Myers
2018-01-26 18:00     ` Palmer Dabbelt
2018-01-26  5:45 ` [PATCH v6 04/16] Add documentation for __riscv_flush_icache Palmer Dabbelt
2018-01-26  5:45 ` [PATCH v6 16/16] Add RISC-V to build-many-glibcs.py Palmer Dabbelt
2018-01-26  5:45 ` [PATCH v6 12/16] RISC-V: Linux ABI Palmer Dabbelt
2018-01-26 13:12   ` Joseph Myers
2018-01-26 18:05     ` Palmer Dabbelt
2018-01-26  5:45 ` [PATCH v6 06/16] RISC-V: Startup and Dynamic Loading Code Palmer Dabbelt
2018-01-26  5:45 ` [PATCH v6 02/16] Skeleton documentation for the RISC-V port Palmer Dabbelt
2018-01-26  5:45 ` [PATCH v6 03/16] Add RISC-V entries to config.h.in Palmer Dabbelt
2018-01-26  5:45 ` Palmer Dabbelt [this message]
2018-01-26  5:45 ` [PATCH v6 05/16] RISC-V: ABI Implementation Palmer Dabbelt
2018-01-26 12:49 ` RISC-V glibc port, v6 Joseph Myers
2018-01-26 17:51   ` Palmer Dabbelt
2018-01-26 15:05 ` Joseph Myers
2018-01-26 18:18   ` Palmer Dabbelt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180126054443.22702-12-palmer@dabbelt.com \
    --to=palmer@dabbelt.com \
    --cc=andrew@sifive.com \
    --cc=darius@bluespec.com \
    --cc=dj@redhat.com \
    --cc=joseph@codesourcery.com \
    --cc=libc-alpha@sourceware.org \
    --cc=patches@groups.riscv.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).