diff options
Diffstat (limited to 'libc')
-rw-r--r-- | libc/sysdeps/linux/nds32/Makefile.arch | 2 | ||||
-rw-r--r-- | libc/sysdeps/linux/nds32/bits/kernel_types.h | 22 | ||||
-rw-r--r-- | libc/sysdeps/linux/nds32/bits/syscalls.h | 3 | ||||
-rw-r--r-- | libc/sysdeps/linux/nds32/sys/ucontext.h | 6 | ||||
-rw-r--r-- | libc/sysdeps/linux/nds32/vfork.S | 129 |
5 files changed, 150 insertions, 12 deletions
diff --git a/libc/sysdeps/linux/nds32/Makefile.arch b/libc/sysdeps/linux/nds32/Makefile.arch index c7627b847..caf163844 100644 --- a/libc/sysdeps/linux/nds32/Makefile.arch +++ b/libc/sysdeps/linux/nds32/Makefile.arch @@ -2,6 +2,6 @@ # Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. CSRC-y := brk.c prctl.c mremap.c -SSRC-y := setjmp.S __longjmp.S bsd-setjmp.S bsd-_setjmp.S clone.S sysdep.S +SSRC-y := setjmp.S __longjmp.S bsd-setjmp.S bsd-_setjmp.S clone.S vfork.S sysdep.S CSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += makecontext.c swapcontext.c SSRC-$(UCLIBC_HAS_CONTEXT_FUNCS) += getcontext.S setcontext.S diff --git a/libc/sysdeps/linux/nds32/bits/kernel_types.h b/libc/sysdeps/linux/nds32/bits/kernel_types.h index 6b142d2e5..1b6ae4d1b 100644 --- a/libc/sysdeps/linux/nds32/bits/kernel_types.h +++ b/libc/sysdeps/linux/nds32/bits/kernel_types.h @@ -14,13 +14,13 @@ typedef unsigned short __kernel_dev_t; typedef unsigned long __kernel_ino_t; -typedef unsigned int __kernel_mode_t; +typedef unsigned short __kernel_mode_t; typedef unsigned short __kernel_nlink_t; typedef long __kernel_off_t; typedef int __kernel_pid_t; -typedef int __kernel_ipc_pid_t; -typedef unsigned int __kernel_uid_t; -typedef unsigned int __kernel_gid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; typedef unsigned int __kernel_size_t; typedef int __kernel_ssize_t; typedef int __kernel_ptrdiff_t; @@ -34,11 +34,19 @@ typedef unsigned short __kernel_gid16_t; typedef unsigned int __kernel_uid32_t; typedef unsigned int __kernel_gid32_t; -typedef __kernel_uid_t __kernel_old_uid_t; -typedef __kernel_gid_t __kernel_old_gid_t; -typedef unsigned int __kernel_old_dev_t; +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; +typedef __kernel_dev_t __kernel_old_dev_t; typedef long __kernel_long_t; typedef unsigned long __kernel_ulong_t; __extension__ typedef long long __kernel_loff_t; +typedef struct { +#ifdef __USE_ALL + int val[2]; +#else + int __val[2]; +#endif +} __kernel_fsid_t; + #endif /* __ARCH_NDS32_POSIX_TYPES_H */ diff --git a/libc/sysdeps/linux/nds32/bits/syscalls.h b/libc/sysdeps/linux/nds32/bits/syscalls.h index 50e30db7d..a5cdda18a 100644 --- a/libc/sysdeps/linux/nds32/bits/syscalls.h +++ b/libc/sysdeps/linux/nds32/bits/syscalls.h @@ -37,7 +37,8 @@ #define Y(x) X(x) #define LIB_SYSCALL __NR_syscall -#define __issue_syscall(syscall_name) "syscall 0x0;\n" +#define __issue_syscall(syscall_name) \ +" syscall " Y(syscall_name) "; \n" #undef INTERNAL_SYSCALL_ERROR_P #define INTERNAL_SYSCALL_ERROR_P(val, err) ((unsigned int) (val) >= 0xfffff001u) diff --git a/libc/sysdeps/linux/nds32/sys/ucontext.h b/libc/sysdeps/linux/nds32/sys/ucontext.h index ea86a3ad0..0d7422aab 100644 --- a/libc/sysdeps/linux/nds32/sys/ucontext.h +++ b/libc/sysdeps/linux/nds32/sys/ucontext.h @@ -36,10 +36,10 @@ typedef struct sigcontext mcontext_t; /* Userlevel context. */ -typedef struct ucontext_t +typedef struct ucontext { - unsigned long int __uc_flags; - struct ucontext_t *uc_link; + unsigned long int uc_flags; + struct ucontext *uc_link; stack_t uc_stack; mcontext_t uc_mcontext; __sigset_t uc_sigmask; diff --git a/libc/sysdeps/linux/nds32/vfork.S b/libc/sysdeps/linux/nds32/vfork.S new file mode 100644 index 000000000..ab32135fc --- /dev/null +++ b/libc/sysdeps/linux/nds32/vfork.S @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2016-2017 Andes Technology, Inc. + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +/* Copyright (C) 1999, 2002, 2003 Free Software Foundation, Inc. + Contributed by Philip Blundell <philb@gnu.org>. + + 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 <sysdep.h> +#define _ERRNO_H 1 +#include <bits/errno.h> + +/* Clone the calling process, but without copying the whole address space. + The calling process is suspended until the new process exits or is + replaced by a call to `execve'. Return -1 for errors, 0 to the new process, + and the process ID of the new process to the old process. */ + +ENTRY (__vfork) +#ifdef PIC +.pic +#endif + +#ifdef __NR_vfork + syscall __NR_vfork + bltz $r0, 2f +1: + ret +2: + sltsi $r1, $r0, -4096 + bnez $r1, 1b; + +# ifdef __ASSUME_VFORK_SYSCALL +# ifdef PIC + pushm $gp, $lp + cfi_adjust_cfa_offset(8) + cfi_rel_offset(gp, 0) + cfi_rel_offset(lp, 4) + mfusr $r15, $PC + sethi $gp, hi20(_GLOBAL_OFFSET_TABLE_+4) + ori $gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_+8) + add $gp, $gp, $r15 + + ! r15=C_SYMBOL_NAME(__syscall_error)@PLT + sethi $r15, hi20(C_SYMBOL_NAME(__syscall_error)@PLT) + ori $r15, $r15, lo12(C_SYMBOL_NAME(__syscall_error)@PLT) + add $r15, $r15, $gp + + ! jump to SYSCALL_ERROR + jral $r15 + popm $gp, $lp + cfi_adjust_cfa_offset(-8) + cfi_restore(lp) + cfi_restore(gp) + ret +# else + j C_SYMBOL_NAME(__syscall_error) +# endif +# else + /* Check if vfork syscall is known at all. */ + li $r1, -ENOSYS + beq $r0, $r1, 1f + +# ifdef PIC +3: + pushm $gp, $lp + cfi_adjust_cfa_offset(8) + cfi_rel_offset(gp, 0) + cfi_rel_offset(lp, 4) + mfusr $r15, $PC + sethi $gp, hi20(_GLOBAL_OFFSET_TABLE_+4) + ori $gp, $gp, lo12(_GLOBAL_OFFSET_TABLE_+8) + add $gp, $gp, $r15 + + ! r15=C_SYMBOL_NAME(__syscall_error)@PLT + sethi $r15, hi20(C_SYMBOL_NAME(__syscall_error)@PLT) + ori $r15, $r15, lo12(C_SYMBOL_NAME(__syscall_error)@PLT) + add $r15, $r15, $gp + + ! jump to SYSCALL_ERROR + jral $r15 + popm $gp, $lp + cfi_adjust_cfa_offset(-8) + cfi_restore(lp) + cfi_restore(gp) + ret +# else + j C_SYMBOL_NAME(__syscall_error) +# endif +1: +# endif +#endif + +#ifndef __ASSUME_VFORK_SYSCALL + /* If we don't have vfork, fork is close enough. */ + syscall __NR_fork + bgez $r0, 1f + sltsi $r1, $r0, -4096 + bnez $r1, 1f + +# ifdef PIC + b 3b +# else + j C_SYMBOL_NAME(__syscall_error) +# endif +1: + ret + +#elif !defined __NR_vfork +# error "__NR_vfork not available and __ASSUME_VFORK_SYSCALL defined" +#endif + +PSEUDO_END (__vfork) +weak_alias (__vfork, vfork) +libc_hidden_def (vfork) |