This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v2 10/15] RISC-V: Linux Syscall Interface


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       |   1 +
 sysdeps/unix/sysv/linux/riscv/clone.S           |  85 +++++++
 sysdeps/unix/sysv/linux/riscv/getmsg.c          |   1 +
 sysdeps/unix/sysv/linux/riscv/kernel-features.h |  23 ++
 sysdeps/unix/sysv/linux/riscv/profil-counter.h  |   2 +
 sysdeps/unix/sysv/linux/riscv/pt-vfork.S        |   1 +
 sysdeps/unix/sysv/linux/riscv/putmsg.c          |   1 +
 sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c    |   1 +
 sysdeps/unix/sysv/linux/riscv/rv32/readahead.c  |   1 +
 sysdeps/unix/sysv/linux/riscv/syscall.c         |  38 +++
 sysdeps/unix/sysv/linux/riscv/sysdep.S          |  51 ++++
 sysdeps/unix/sysv/linux/riscv/sysdep.h          | 316 ++++++++++++++++++++++++
 sysdeps/unix/sysv/linux/riscv/vfork.S           |  44 ++++
 14 files changed, 567 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/getmsg.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/kernel-features.h
 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/putmsg.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c
 create mode 100644 sysdeps/unix/sysv/linux/riscv/rv32/readahead.c
 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..5f945378eec0
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/arch-fork.h
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/arch-fork.h>
diff --git a/sysdeps/unix/sysv/linux/riscv/clone.S b/sysdeps/unix/sysv/linux/riscv/clone.S
new file mode 100644
index 000000000000..4bfdc90702aa
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/clone.S
@@ -0,0 +1,85 @@
+/* Wrapper around clone system call.  RISC-V version.
+   Copyright (C) 1996-2017 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.  */
+	j		_exit
+
+	END(__thread_start)
+
+libc_hidden_def(__clone)
+weak_alias (__clone, clone)
diff --git a/sysdeps/unix/sysv/linux/riscv/getmsg.c b/sysdeps/unix/sysv/linux/riscv/getmsg.c
new file mode 100644
index 000000000000..3a1fa0852504
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/getmsg.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/getmsg.c>
diff --git a/sysdeps/unix/sysv/linux/riscv/kernel-features.h b/sysdeps/unix/sysv/linux/riscv/kernel-features.h
new file mode 100644
index 000000000000..21f9600eda73
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/kernel-features.h
@@ -0,0 +1,23 @@
+/* RISC-V kernel features
+   Copyright (C) 2014-2017 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/>.  */
+
+#define __ASSUME_ACCEPT4_SYSCALL	1
+#define __ASSUME_RECVMMSG_SYSCALL	1
+#define __ASSUME_SENDMMSG_SYSCALL	1
+
+#include_next <kernel-features.h>
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..8a6a0bcf3d59
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/profil-counter.h
@@ -0,0 +1,2 @@
+/* We can use the ix86 version.  */
+#include <sysdeps/unix/sysv/linux/i386/profil-counter.h>
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..65cc3823ac87
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/pt-vfork.S
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/alpha/pt-vfork.S>
diff --git a/sysdeps/unix/sysv/linux/riscv/putmsg.c b/sysdeps/unix/sysv/linux/riscv/putmsg.c
new file mode 100644
index 000000000000..ebc1680ca7d1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/putmsg.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/putmsg.c>
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c b/sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c
new file mode 100644
index 000000000000..a88f5a784a54
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/i386/lockf64.c>
diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/readahead.c b/sysdeps/unix/sysv/linux/riscv/rv32/readahead.c
new file mode 100644
index 000000000000..80170c3e8a4d
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/rv32/readahead.c
@@ -0,0 +1 @@
+#include <sysdeps/unix/sysv/linux/arm/readahead.c>
diff --git a/sysdeps/unix/sysv/linux/riscv/syscall.c b/sysdeps/unix/sysv/linux/riscv/syscall.c
new file mode 100644
index 000000000000..bce62ca06df7
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/syscall.c
@@ -0,0 +1,38 @@
+/* system call interface.  Linux/RISC-V version.
+   Copyright (C) 2001-2017 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
+syscall (long syscall_number, long arg1, long arg2, long arg3, long arg4,
+	 long arg5, long arg6, long arg7)
+{
+  long 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))
+    {
+      extern long __syscall_error (long neg_errno);
+      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..90da2daf7655
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sysdep.S
@@ -0,0 +1,51 @@
+/* syscall error handlers
+   Copyright (C) 2011-2017 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..56a6053d82a6
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/sysdep.h
@@ -0,0 +1,316 @@
+/* Assembly macros for RISC-V.
+   Copyright (C) 2011-2017
+   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 __sys_result = INTERNAL_SYSCALL (name, err, nr, args);	\
+     if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P(__sys_result, ), 0)) \
+       {								\
+         __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) (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 _sys_result;						\
+									\
+	{								\
+	register long __a7 asm("a7") = number;				\
+	register long __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 _sys_result;						\
+									\
+	{								\
+	register long __a7 asm("a7") = number;				\
+	register long __a0 asm("a0") = (long) (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 _sys_result;						\
+									\
+	{								\
+	register long __a7 asm("a7") = number;				\
+	register long __a0 asm("a0") = (long) (arg0);			\
+	register long __a1 asm("a1") = (long) (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 _sys_result;						\
+									\
+	{								\
+	register long __a7 asm("a7") = number;				\
+	register long __a0 asm("a0") = (long) (arg0);			\
+	register long __a1 asm("a1") = (long) (arg1);			\
+	register long __a2 asm("a2") = (long) (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 _sys_result;						\
+									\
+	{								\
+	register long __a7 asm("a7") = number;				\
+	register long __a0 asm("a0") = (long) (arg0);			\
+	register long __a1 asm("a1") = (long) (arg1);			\
+	register long __a2 asm("a2") = (long) (arg2);			\
+	register long __a3 asm("a3") = (long) (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 _sys_result;						\
+									\
+	{								\
+	register long __a7 asm("a7") = number;				\
+	register long __a0 asm("a0") = (long) (arg0);			\
+	register long __a1 asm("a1") = (long) (arg1);			\
+	register long __a2 asm("a2") = (long) (arg2);			\
+	register long __a3 asm("a3") = (long) (arg3);			\
+	register long __a4 asm("a4") = (long) (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 _sys_result;						\
+									\
+	{								\
+	register long __a7 asm("a7") = number;				\
+	register long __a0 asm("a0") = (long) (arg0);			\
+	register long __a1 asm("a1") = (long) (arg1);			\
+	register long __a2 asm("a2") = (long) (arg2);			\
+	register long __a3 asm("a3") = (long) (arg3);			\
+	register long __a4 asm("a4") = (long) (arg4);			\
+	register long __a5 asm("a5") = (long) (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 _sys_result;						\
+									\
+	{								\
+	register long __a7 asm("a7") = number;				\
+	register long __a0 asm("a0") = (long) (arg0);			\
+	register long __a1 asm("a1") = (long) (arg1);			\
+	register long __a2 asm("a2") = (long) (arg2);			\
+	register long __a3 asm("a3") = (long) (arg3);			\
+	register long __a4 asm("a4") = (long) (arg4);			\
+	register long __a5 asm("a5") = (long) (arg5);			\
+	register long __a6 asm("a6") = (long) (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"
+#endif /* ! __ASSEMBLER__ */
+
+/* Pointer mangling is not supported.  */
+#define PTR_MANGLE(var) (void) (var)
+#define PTR_DEMANGLE(var) (void) (var)
+
+#endif /* linux/mips/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..9bddd8d1f4f9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/riscv/vfork.S
@@ -0,0 +1,44 @@
+/* vfork for Linux, RISC-V version.
+   Copyright (C) 2005-2017 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]