From patchwork Wed Jun 14 18:30:46 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Palmer Dabbelt X-Patchwork-Id: 21019 Received: (qmail 99049 invoked by alias); 14 Jun 2017 18:33:22 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 98862 invoked by uid 89); 14 Jun 2017 18:33:21 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-24.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS, UNSUBSCRIBE_BODY autolearn=ham version=3.3.2 spammy= X-HELO: mail-pf0-f176.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:cc:cc:cc:subject:date:message-id :in-reply-to:references; bh=B+j82Xttn+h+Gjx8jyVL25haPeq9Z59WcBHhRxHIaT8=; b=SqG1VjZ6kft079LAh5eyBP1r3bPkudavz7bXqwSES0fScjmG9DFXpUd6OpcJ4/ZNIZ wIeYdPKKsvS538o8yoRIlyLsIi3iAQOm5Fu8Ikn0vnm002XdbSKd5PYzXB8kveJnc7CR J2tEi7cK4am5shbmZORVRBQu98vTY5eo6+sTk9QcMIJMtYpnugHtaFCMvN0kbATd5AY4 XW85i7qlwWkBWnOd7F37hnnmgcy+810oSZPKPfeWvuqB2pSVNN7BKl4WVSHCGerxa3fc hBdthLMKCJFVi75yq9YaBwyP5O/wKVe5dEIe8CnafFjmjgnq/1qqJ2eYz/z7IEXJH5Ah Ipvw== X-Gm-Message-State: AKS2vOxawiIjJ0z0ciIt3IM6iDKhD9ODLUMuW0i6m/7Fg90+HBGZfl8R mopOnu4ID8QIi6C9plVhwA== X-Received: by 10.98.214.66 with SMTP id r63mr1327872pfg.156.1497465196896; Wed, 14 Jun 2017 11:33:16 -0700 (PDT) From: Palmer Dabbelt To: libc-alpha@sourceware.org Cc: Andrew Waterman Cc: patches@groups.riscv.org Cc: Darius Rad Cc: Palmer Dabbelt Subject: [PATCH 10/12] RISC-V: Linux Syscall Interface Date: Wed, 14 Jun 2017 11:30:46 -0700 Message-Id: <20170614183048.11040-11-palmer@dabbelt.com> In-Reply-To: <20170614183048.11040-1-palmer@dabbelt.com> References: <20170614183048.11040-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 | 1 + sysdeps/unix/sysv/linux/riscv/clone.S | 86 ++++++++ sysdeps/unix/sysv/linux/riscv/getmsg.c | 1 + sysdeps/unix/sysv/linux/riscv/kernel-features.h | 22 ++ sysdeps/unix/sysv/linux/riscv/profil-counter.h | 2 + sysdeps/unix/sysv/linux/riscv/pt-vfork.S | 0 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 | 262 ++++++++++++++++++++++++ sysdeps/unix/sysv/linux/riscv/vfork.S | 44 ++++ 14 files changed, 512 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 0000000000..3f5c2a364a --- /dev/null +++ b/sysdeps/riscv/nptl/nptl-sysdep.S @@ -0,0 +1,2 @@ +/* Pull in __syscall_error. */ +#include 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 0000000000..5f945378ee --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/arch-fork.h @@ -0,0 +1 @@ +#include diff --git a/sysdeps/unix/sysv/linux/riscv/clone.S b/sysdeps/unix/sysv/linux/riscv/clone.S new file mode 100644 index 0000000000..716ab877f5 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/clone.S @@ -0,0 +1,86 @@ +/* Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ralf Baechle , 1996. + + 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* 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 +#include +#define _ERRNO_H 1 +#include +#include +#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 0000000000..3a1fa08525 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/getmsg.c @@ -0,0 +1 @@ +#include 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 0000000000..2db504b53b --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/kernel-features.h @@ -0,0 +1,22 @@ +/* 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 + . */ + +#define __ASSUME_ACCEPT4_SYSCALL 1 +#define __ASSUME_RECVMMSG_SYSCALL 1 +#define __ASSUME_SENDMMSG_SYSCALL 1 + +#include_next 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 0000000000..8a6a0bcf3d --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/profil-counter.h @@ -0,0 +1,2 @@ +/* We can use the ix86 version. */ +#include 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 0000000000..e69de29bb2 diff --git a/sysdeps/unix/sysv/linux/riscv/putmsg.c b/sysdeps/unix/sysv/linux/riscv/putmsg.c new file mode 100644 index 0000000000..ebc1680ca7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/putmsg.c @@ -0,0 +1 @@ +#include 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 0000000000..a88f5a784a --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/rv32/lockf64.c @@ -0,0 +1 @@ +#include 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 0000000000..80170c3e8a --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/rv32/readahead.c @@ -0,0 +1 @@ +#include diff --git a/sysdeps/unix/sysv/linux/riscv/syscall.c b/sysdeps/unix/sysv/linux/riscv/syscall.c new file mode 100644 index 0000000000..f37a8b58aa --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/syscall.c @@ -0,0 +1,38 @@ +/* Copyright (C) 2001-2003, 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include + +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 0000000000..a32ac69088 --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/sysdep.S @@ -0,0 +1,51 @@ +/* Copyright (C) 2011-2017 Free Software Foundation, Inc. + Contributed by Andrew Waterman (andrew@sifive.com). + 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 + . */ + +#include + +#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 0000000000..eddb0a586e --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/sysdep.h @@ -0,0 +1,262 @@ +/* Copyright (C) 2011-2014, 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 + . */ + +#ifndef _LINUX_RISCV_SYSDEP_H +#define _LINUX_RISCV_SYSDEP_H 1 + +#include +#include + +#ifdef __ASSEMBLER__ + +#include + +#define ENTRY(name) LEAF(name) + +#undef PSEUDO_END +#define PSEUDO_END(sym) END(sym) + +#define PSEUDO_NOERRNO(name, syscall_name, args) \ + .align 2; \ + ENTRY(name) \ + li a7, SYS_ify(syscall_name); \ + scall + +#define ret_NOERRNO ret + +#define PSEUDO_ERRVAL(name, syscall_name, args) \ + PSEUDO_NOERRNO(name, syscall_name, args) + +#define ret_ERRVAL ret + +#define L(label) .L ## label + +#define PSEUDO(name, syscall_name, args) \ + .align 2; \ + 99: j __syscall_error; \ + ENTRY(name) \ + li a7, SYS_ify(syscall_name); \ + scall; \ + bltz a0, 99b; \ +L(syse1): + +#endif /* __ASSEMBLER__ */ + +#include + +#undef SYS_ify +#define SYS_ify(syscall_name) __NR_##syscall_name + +#ifndef __ASSEMBLER__ + +/* 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 result = INTERNAL_SYSCALL (name, err, nr, args); \ + register long __a0 asm ("a0") = result; \ + if (__a0 < 0) \ + __asm__ volatile ("call t0, __syscall_set_errno" \ + : "+r" (__a0) : : "t0", "t1", "t2"); \ + __a0; }) + +/* Set error number and return -1. Return the internal function, + __syscall_error, which sets errno from the negative error number + and returns -1. */ +#undef INLINE_SYSCALL_ERROR_RETURN_VALUE +#define INLINE_SYSCALL_ERROR_RETURN_VALUE(resultvar) \ + ({ extern int __syscall_error (long neg_errno); \ + __syscall_error (-(resultvar)); }) + +#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 0000000000..ff7176a40f --- /dev/null +++ b/sysdeps/unix/sysv/linux/riscv/vfork.S @@ -0,0 +1,44 @@ +/* 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, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* vfork() is just a special case of clone(). */ + +#include +#include +#define __ASSEMBLY__ +#include +#include + + .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)