summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/nios2
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@openadk.org>2016-05-28 18:12:58 +0200
committerWaldemar Brodkorb <wbx@uclibc-ng.org>2016-11-04 00:03:07 +0100
commitb8fcdddcbb192fc367ff04bbd753b9deb69b09f3 (patch)
tree8febdb9d4e3d090e9273c29df9ff06116196c8e4 /libc/sysdeps/linux/nios2
parent191739597c6d380692885cfdd8dd8aa4f31f029d (diff)
nios2: sync support with glibc
Only static linking is supported for now. More debugging and analyzing for ld.so, TLS and NPTL is required. But at least you can bootup a static root fileystem in Qemu.
Diffstat (limited to 'libc/sysdeps/linux/nios2')
-rw-r--r--libc/sysdeps/linux/nios2/Makefile.arch11
-rw-r--r--libc/sysdeps/linux/nios2/__longjmp.S71
-rw-r--r--libc/sysdeps/linux/nios2/__syscall_error.c18
-rw-r--r--libc/sysdeps/linux/nios2/bits/fcntl.h6
-rw-r--r--libc/sysdeps/linux/nios2/bits/kernel_stat.h50
-rw-r--r--libc/sysdeps/linux/nios2/bits/kernel_types.h6
-rw-r--r--libc/sysdeps/linux/nios2/bits/setjmp.h30
-rw-r--r--libc/sysdeps/linux/nios2/bits/stat.h167
-rw-r--r--libc/sysdeps/linux/nios2/bits/syscalls.h173
-rw-r--r--libc/sysdeps/linux/nios2/bsd-_setjmp.S44
-rw-r--r--libc/sysdeps/linux/nios2/bsd-setjmp.S51
-rw-r--r--libc/sysdeps/linux/nios2/clone.S152
-rw-r--r--libc/sysdeps/linux/nios2/clone.c50
-rw-r--r--libc/sysdeps/linux/nios2/crt1.S147
-rw-r--r--libc/sysdeps/linux/nios2/fpu_control.h98
-rw-r--r--libc/sysdeps/linux/nios2/jmpbuf-offsets.h16
-rw-r--r--libc/sysdeps/linux/nios2/jmpbuf-unwind.h39
-rw-r--r--libc/sysdeps/linux/nios2/setjmp.S101
-rw-r--r--libc/sysdeps/linux/nios2/syscall.c47
-rw-r--r--libc/sysdeps/linux/nios2/sysdep.h34
-rw-r--r--libc/sysdeps/linux/nios2/vfork.S100
21 files changed, 510 insertions, 901 deletions
diff --git a/libc/sysdeps/linux/nios2/Makefile.arch b/libc/sysdeps/linux/nios2/Makefile.arch
index e36e06b52..887ce5aa4 100644
--- a/libc/sysdeps/linux/nios2/Makefile.arch
+++ b/libc/sysdeps/linux/nios2/Makefile.arch
@@ -1,12 +1,5 @@
# Makefile for uClibc
-#
-# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
-#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
-#
-CSRC-y := brk.c syscall.c
-
-SSRC-y := \
- __longjmp.S bsd-_setjmp.S bsd-setjmp.S setjmp.S \
- vfork.S clone.S
+CSRC-y := __syscall_error.c
+SSRC-y := __longjmp.S setjmp.S vfork.S clone.S
diff --git a/libc/sysdeps/linux/nios2/__longjmp.S b/libc/sysdeps/linux/nios2/__longjmp.S
index 7df599768..3f112f15f 100644
--- a/libc/sysdeps/linux/nios2/__longjmp.S
+++ b/libc/sysdeps/linux/nios2/__longjmp.S
@@ -1,48 +1,39 @@
-/*
- * libc/sysdeps/linux/nios2/__longjmp.S
- *
- * Copyright (C) 2004,05,06 Microtronix Datacom Ltd
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Wentao Xu <wentao@microtronix.com>
- *
- */
+/* longjmp for Nios II.
+ Copyright (C) 2015-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
-#include <features.h>
-#include <jmpbuf-offsets.h>
+ 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/>. */
-.globl __longjmp
-.type __longjmp,@function
-.balign 4
+#include <sysdep.h>
+#include <jmpbuf-offsets.h>
-__longjmp:
- /* return value is in r5*/
+ENTRY (__longjmp)
mov r2, r5
-
- /* jmp_buf in r4, restore regs. */
- ldw r16, (JB_REGS+ 0)(r4)
- ldw r17, (JB_REGS+ 4)(r4)
- ldw r18, (JB_REGS+ 8)(r4)
- ldw r19, (JB_REGS+12)(r4)
- ldw r20, (JB_REGS+16)(r4)
- ldw r21, (JB_REGS+20)(r4)
- ldw r22, (JB_REGS+24)(r4)
- ldw r23, (JB_REGS+28)(r4)
-
- ldw ra, JB_PC(r4)
- ldw fp, JB_FP(r4)
- ldw gp, JB_GP(r4)
- ldw sp, JB_SP(r4)
-
-#ifdef __UCLIBC_HAS_FPU__
- RESTORE_FPU r4 JB_FPREGS
-#endif
- /* return to saved RA */
+ ldw r16, (JB_R16*4)(r4)
+ ldw r17, (JB_R17*4)(r4)
+ ldw r18, (JB_R18*4)(r4)
+ ldw r19, (JB_R19*4)(r4)
+ ldw r20, (JB_R20*4)(r4)
+ ldw r21, (JB_R21*4)(r4)
+ ldw r22, (JB_R22*4)(r4)
+ ldw fp, (JB_FP*4)(r4)
+ ldw ra, (JB_RA*4)(r4)
+ ldw sp, (JB_SP*4)(r4)
+
ret
-.size __longjmp,.-__longjmp
+END (__longjmp)
libc_hidden_def(__longjmp)
diff --git a/libc/sysdeps/linux/nios2/__syscall_error.c b/libc/sysdeps/linux/nios2/__syscall_error.c
new file mode 100644
index 000000000..2b642e816
--- /dev/null
+++ b/libc/sysdeps/linux/nios2/__syscall_error.c
@@ -0,0 +1,18 @@
+/* Wrapper for setting errno.
+ *
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <errno.h>
+#include <features.h>
+
+/* This routine is jumped to by all the syscall handlers, to stash
+ * an error number into errno. */
+int __syscall_error(int err_no) attribute_hidden;
+int __syscall_error(int err_no)
+{
+ __set_errno(-err_no);
+ return -1;
+}
diff --git a/libc/sysdeps/linux/nios2/bits/fcntl.h b/libc/sysdeps/linux/nios2/bits/fcntl.h
index d8386d65c..4fe1ee396 100644
--- a/libc/sysdeps/linux/nios2/bits/fcntl.h
+++ b/libc/sysdeps/linux/nios2/bits/fcntl.h
@@ -44,9 +44,9 @@
#define O_ASYNC 020000
#ifdef __USE_GNU
-# define O_DIRECTORY 040000 /* Must be a directory. */
-# define O_NOFOLLOW 0100000 /* Do not follow links. */
-# define O_DIRECT 0200000 /* Direct disk access. */
+# define O_DIRECTORY 0200000 /* Must be a directory. */
+# define O_NOFOLLOW 0400000 /* Do not follow links. */
+# define O_DIRECT 040000 /* Direct disk access. */
# define O_NOATIME 01000000 /* Do not set atime. */
# define O_CLOEXEC 02000000 /* set close_on_exec */
# define O_PATH 010000000 /* Resolve pathname but do not open file. */
diff --git a/libc/sysdeps/linux/nios2/bits/kernel_stat.h b/libc/sysdeps/linux/nios2/bits/kernel_stat.h
deleted file mode 100644
index 99a6cba97..000000000
--- a/libc/sysdeps/linux/nios2/bits/kernel_stat.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef _BITS_STAT_STRUCT_H
-#define _BITS_STAT_STRUCT_H
-
-/* This file provides whatever this particular arch's kernel thinks
- * struct kernel_stat should look like... It turns out each arch has a
- * different opinion on the subject... */
-
-struct kernel_stat {
- unsigned short st_dev;
- unsigned short __pad1;
- unsigned long st_ino;
- unsigned short st_mode;
- unsigned short st_nlink;
- unsigned short st_uid;
- unsigned short st_gid;
- unsigned short st_rdev;
- unsigned short __pad2;
- unsigned long st_size;
- unsigned long st_blksize;
- unsigned long st_blocks;
- struct timespec st_atim;
- struct timespec st_mtim;
- struct timespec st_ctim;
- unsigned long __unused4;
- unsigned long __unused5;
-};
-
-struct kernel_stat64 {
- unsigned short st_dev;
- unsigned char __pad0[10];
-#define _HAVE_STAT64___ST_INO
- unsigned long __st_ino;
- unsigned int st_mode;
- unsigned int st_nlink;
- unsigned long st_uid;
- unsigned long st_gid;
- unsigned short st_rdev;
- unsigned char __pad3[10];
- long long st_size;
- unsigned long st_blksize;
- unsigned long st_blocks; /* Number 512-byte blocks allocated. */
- unsigned long __pad4; /* future possible st_blocks high bits */
- struct timespec st_atim;
- struct timespec st_mtim;
- struct timespec st_ctim;
- unsigned long long st_ino;
-};
-
-#endif /* _BITS_STAT_STRUCT_H */
-
diff --git a/libc/sysdeps/linux/nios2/bits/kernel_types.h b/libc/sysdeps/linux/nios2/bits/kernel_types.h
index 004f9c746..5c122b5b1 100644
--- a/libc/sysdeps/linux/nios2/bits/kernel_types.h
+++ b/libc/sysdeps/linux/nios2/bits/kernel_types.h
@@ -10,10 +10,10 @@
typedef unsigned long __kernel_dev_t;
typedef unsigned long __kernel_ino_t;
typedef unsigned short __kernel_mode_t;
-typedef unsigned short __kernel_nlink_t;
+typedef unsigned long __kernel_nlink_t;
typedef long __kernel_off_t;
typedef int __kernel_pid_t;
-typedef unsigned short __kernel_ipc_pid_t;
+typedef int __kernel_ipc_pid_t;
typedef unsigned int __kernel_uid_t;
typedef unsigned int __kernel_gid_t;
typedef unsigned int __kernel_size_t;
@@ -22,6 +22,8 @@ typedef int __kernel_ptrdiff_t;
typedef long __kernel_time_t;
typedef long __kernel_suseconds_t;
typedef long __kernel_clock_t;
+typedef int __kernel_timer_t;
+typedef int __kernel_clockid_t;
typedef int __kernel_daddr_t;
typedef char * __kernel_caddr_t;
typedef unsigned short __kernel_uid16_t;
diff --git a/libc/sysdeps/linux/nios2/bits/setjmp.h b/libc/sysdeps/linux/nios2/bits/setjmp.h
index bc6f30848..2fbb39562 100644
--- a/libc/sysdeps/linux/nios2/bits/setjmp.h
+++ b/libc/sysdeps/linux/nios2/bits/setjmp.h
@@ -1,5 +1,5 @@
-/* Define the machine-dependent type `jmp_buf'. Nios2 version.
- Copyright (C) 1992,93,95,97,2000 Free Software Foundation, Inc.
+/* Define the machine-dependent type `jmp_buf'. Nios II version.
+ Copyright (C) 1992-2016 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
@@ -13,7 +13,7 @@
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
+ License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _BITS_SETJMP_H
@@ -23,27 +23,9 @@
# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
#endif
-typedef struct
-{
- /* Callee-saved registers r16 through r23. */
- unsigned long __regs[8];
+/* Saves r16-r22 (callee-saved, including GOT pointer), fp (frame pointer),
+ ra (return address), and sp (stack pointer). */
- /* Program counter. */
- unsigned long __pc;
-
- /* Stack pointer. */
- unsigned long __sp;
-
- /* The frame pointer. */
- unsigned long __fp;
-
- /* The global pointer. */
- unsigned long __gp;
-
- /* floating point regs, if any */
-#ifdef __UCLIBC_HAS_FPU__
- unsigned long __fpregs[64];
-#endif
-} __jmp_buf[1];
+typedef int __jmp_buf[10];
#endif /* bits/setjmp.h */
diff --git a/libc/sysdeps/linux/nios2/bits/stat.h b/libc/sysdeps/linux/nios2/bits/stat.h
deleted file mode 100644
index 6e3b0198c..000000000
--- a/libc/sysdeps/linux/nios2/bits/stat.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/* Copyright (C) 1992,95,96,97,98,99,2000,2001 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/>. */
-
-#ifndef _SYS_STAT_H
-# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
-#endif
-
-/* Versions of the `struct stat' data structure. */
-#define _STAT_VER_LINUX_OLD 1
-#define _STAT_VER_KERNEL 1
-#define _STAT_VER_SVR4 2
-#define _STAT_VER_LINUX 3
-#define _STAT_VER _STAT_VER_LINUX /* The one defined below. */
-
-/* Versions of the `xmknod' interface. */
-#define _MKNOD_VER_LINUX 1
-#define _MKNOD_VER_SVR4 2
-#define _MKNOD_VER _MKNOD_VER_LINUX /* The bits defined below. */
-
-
-struct stat
- {
- __dev_t st_dev; /* Device. */
- unsigned short int __pad1;
-#ifndef __USE_FILE_OFFSET64
- __ino_t st_ino; /* File serial number. */
-#else
- __ino_t __st_ino; /* 32bit file serial number. */
-#endif
- __mode_t st_mode; /* File mode. */
- __nlink_t st_nlink; /* Link count. */
- __uid_t st_uid; /* User ID of the file's owner. */
- __gid_t st_gid; /* Group ID of the file's group.*/
- __dev_t st_rdev; /* Device number, if device. */
- unsigned short int __pad2;
-#ifndef __USE_FILE_OFFSET64
- __off_t st_size; /* Size of file, in bytes. */
-#else
- __off64_t st_size; /* Size of file, in bytes. */
-#endif
- __blksize_t st_blksize; /* Optimal block size for I/O. */
-
-#ifndef __USE_FILE_OFFSET64
- __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */
-#else
- __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-#endif
-#ifdef __USE_MISC
- /* Nanosecond resolution timestamps are stored in a format
- equivalent to 'struct timespec'. This is the type used
- whenever possible but the Unix namespace rules do not allow the
- identifier 'timespec' to appear in the <sys/stat.h> header.
- Therefore we have to handle the use of this header in strictly
- standard-compliant sources special. */
- struct timespec st_atim; /* Time of last access. */
- struct timespec st_mtim; /* Time of last modification. */
- struct timespec st_ctim; /* Time of last status change. */
-# define st_atime st_atim.tv_sec /* Backward compatibility. */
-# define st_mtime st_mtim.tv_sec
-# define st_ctime st_ctim.tv_sec
-#else
- __time_t st_atime; /* Time of last access. */
- unsigned long int st_atimensec; /* Nscecs of last access. */
- __time_t st_mtime; /* Time of last modification. */
- unsigned long int st_mtimensec; /* Nsecs of last modification. */
- __time_t st_ctime; /* Time of last status change. */
- unsigned long int st_ctimensec; /* Nsecs of last status change. */
-#endif
-#ifndef __USE_FILE_OFFSET64
- unsigned long int __unused4;
- unsigned long int __unused5;
-#else
- __ino64_t st_ino; /* File serial number. */
-#endif
- };
-
-#ifdef __USE_LARGEFILE64
-struct stat64
- {
- __dev_t st_dev; /* Device. */
- unsigned int __pad1;
-
- __ino_t __st_ino; /* 32bit file serial number. */
- __mode_t st_mode; /* File mode. */
- __nlink_t st_nlink; /* Link count. */
- __uid_t st_uid; /* User ID of the file's owner. */
- __gid_t st_gid; /* Group ID of the file's group.*/
- __dev_t st_rdev; /* Device number, if device. */
- unsigned int __pad2;
- __off64_t st_size; /* Size of file, in bytes. */
- __blksize_t st_blksize; /* Optimal block size for I/O. */
-
- __blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
-#ifdef __USE_MISC
- /* Nanosecond resolution timestamps are stored in a format
- equivalent to 'struct timespec'. This is the type used
- whenever possible but the Unix namespace rules do not allow the
- identifier 'timespec' to appear in the <sys/stat.h> header.
- Therefore we have to handle the use of this header in strictly
- standard-compliant sources special. */
- struct timespec st_atim; /* Time of last access. */
- struct timespec st_mtim; /* Time of last modification. */
- struct timespec st_ctim; /* Time of last status change. */
-#else
- __time_t st_atime; /* Time of last access. */
- unsigned long int st_atimensec; /* Nscecs of last access. */
- __time_t st_mtime; /* Time of last modification. */
- unsigned long int st_mtimensec; /* Nsecs of last modification. */
- __time_t st_ctime; /* Time of last status change. */
- unsigned long int st_ctimensec; /* Nsecs of last status change. */
-#endif
- __ino64_t st_ino; /* File serial number. */
- };
-#endif
-
-/* Tell code we have these members. */
-#define _STATBUF_ST_BLKSIZE
-#define _STATBUF_ST_RDEV
-/* Nanosecond resolution time values are supported. */
-#define _STATBUF_ST_NSEC
-
-/* Encoding of the file mode. */
-
-#define __S_IFMT 0170000 /* These bits determine file type. */
-
-/* File types. */
-#define __S_IFDIR 0040000 /* Directory. */
-#define __S_IFCHR 0020000 /* Character device. */
-#define __S_IFBLK 0060000 /* Block device. */
-#define __S_IFREG 0100000 /* Regular file. */
-#define __S_IFIFO 0010000 /* FIFO. */
-#define __S_IFLNK 0120000 /* Symbolic link. */
-#define __S_IFSOCK 0140000 /* Socket. */
-
-/* POSIX.1b objects. Note that these macros always evaluate to zero. But
- they do it by enforcing the correct use of the macros. */
-#define __S_TYPEISMQ(buf) ((buf)->st_mode - (buf)->st_mode)
-#define __S_TYPEISSEM(buf) ((buf)->st_mode - (buf)->st_mode)
-#define __S_TYPEISSHM(buf) ((buf)->st_mode - (buf)->st_mode)
-
-/* Protection bits. */
-
-#define __S_ISUID 04000 /* Set user ID on execution. */
-#define __S_ISGID 02000 /* Set group ID on execution. */
-#define __S_ISVTX 01000 /* Save swapped text after use (sticky). */
-#define __S_IREAD 0400 /* Read by owner. */
-#define __S_IWRITE 0200 /* Write by owner. */
-#define __S_IEXEC 0100 /* Execute by owner. */
-
-#ifdef __USE_ATFILE
-# define UTIME_NOW ((1l << 30) - 1l)
-# define UTIME_OMIT ((1l << 30) - 2l)
-#endif
diff --git a/libc/sysdeps/linux/nios2/bits/syscalls.h b/libc/sysdeps/linux/nios2/bits/syscalls.h
index 5be5d4d86..2b12343a6 100644
--- a/libc/sysdeps/linux/nios2/bits/syscalls.h
+++ b/libc/sysdeps/linux/nios2/bits/syscalls.h
@@ -4,106 +4,97 @@
# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
#endif
-#define TRAP_ID_SYSCALL 0
+#ifdef __ASSEMBLER__
-#ifndef __ASSEMBLER__
+#undef DO_CALL
+#define DO_CALL(syscall_name, args) \
+ DOARGS_##args \
+ movi r2, SYS_ify(syscall_name); \
+ trap;
-#include <errno.h>
-
-#define __syscall_return(type, res) \
- do { \
- if (unlikely(INTERNAL_SYSCALL_ERROR_P(res, ))) { \
- __set_errno(INTERNAL_SYSCALL_ERRNO(res, )); \
- res = (unsigned long) -1; \
- } \
- return (type) (res); \
- } while (0)
+#define DOARGS_0 /* nothing */
+#define DOARGS_1 /* nothing */
+#define DOARGS_2 /* nothing */
+#define DOARGS_3 /* nothing */
+#define DOARGS_4 /* nothing */
+#define DOARGS_5 ldw r8, 0(sp);
+#define DOARGS_6 ldw r9, 4(sp); ldw r8, 0(sp);
-#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
-(__extension__ \
- ({ \
- long __res; \
- __asm__ __volatile__ ( \
- "movi r2, %2\n\t" /* TRAP_ID_SYSCALL */ \
- "movi r3, %1\n\t" /* __NR_##name */ \
- ASM_ARGS_##nr \
- "trap\n\t" \
- "mov %0, r2\n\t" /* syscall return */ \
- : "=r" (__res) /* %0 */ \
- : "i" (name) /* %1 */ \
- , "i" (TRAP_ID_SYSCALL) /* %2 */ \
- MAP_ARGS_##nr (args) /* %3-%8 */ \
- : "r2" \
- , "r3" \
- CLOB_ARGS_##nr /* Clobbered */ \
- ); \
- __res; \
- }) \
-)
+#else
-#define INTERNAL_SYSCALL_ERROR_P(val, err) \
- ((unsigned long)(val) >= (unsigned long)(-125))
-
-#define ASM_ARGS_0
-#define MAP_ARGS_0()
-#define CLOB_ARGS_0
-
-#define ASM_ARGS_1 \
- "mov r4, %3\n\t"
-#define MAP_ARGS_1(a) \
- , "r" ((long) a)
-#define CLOB_ARGS_1 \
- , "r4"
+#include <errno.h>
-#define ASM_ARGS_2 \
- ASM_ARGS_1 \
- "mov r5, %4\n\t"
-#define MAP_ARGS_2(a, b) \
- MAP_ARGS_1(a) \
- , "r" ((long) b)
-#define CLOB_ARGS_2 \
- CLOB_ARGS_1 \
- , "r5"
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) unsigned int err __attribute__((unused))
-#define ASM_ARGS_3 \
- ASM_ARGS_2 \
- "mov r6, %5\n\t"
-#define MAP_ARGS_3(a, b, c) \
- MAP_ARGS_2(a, b) \
- , "r" ((long) c)
-#define CLOB_ARGS_3 \
- CLOB_ARGS_2 \
- , "r6"
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err) ((void) (val), (unsigned int) (err))
-#define ASM_ARGS_4 \
- ASM_ARGS_3 \
- "mov r7, %6\n\t"
-#define MAP_ARGS_4(a, b, c, d) \
- MAP_ARGS_3(a, b, c) \
- , "r" ((long) d)
-#define CLOB_ARGS_4 \
- CLOB_ARGS_3 \
- , "r7"
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val, err) ((void) (err), val)
-#define ASM_ARGS_5 \
- ASM_ARGS_4 \
- "mov r8, %7\n\t"
-#define MAP_ARGS_5(a, b, c, d, e) \
- MAP_ARGS_4(a, b, c, d) \
- , "r" ((long) e)
-#define CLOB_ARGS_5 \
- CLOB_ARGS_4 \
- , "r8"
+#undef INTERNAL_SYSCALL_NCS
+#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+ ({ unsigned int _sys_result; \
+ { \
+ LOAD_ARGS_##nr (args) \
+ LOAD_REGS_##nr \
+ register int _r2 __asm__ ("r2") = (int)(name); \
+ register int _sys_err __asm__ ("r7"); \
+ __asm__ volatile ("trap" \
+ : "+r" (_r2), "=r" (_sys_err) \
+ : ASM_ARGS_##nr \
+ : "memory"); \
+ _sys_result = _r2; \
+ err = _sys_err; \
+ } \
+ (int) _sys_result; })
-#define ASM_ARGS_6 \
- ASM_ARGS_5 \
- "mov r9, %8\n\t"
-#define MAP_ARGS_6(a, b, c, d, e, f) \
- MAP_ARGS_5(a, b, c, d, e) \
- , "r" ((long) f)
-#define CLOB_ARGS_6 \
- CLOB_ARGS_5 \
- , "r9"
+#define LOAD_ARGS_0()
+#define LOAD_REGS_0
+#define ASM_ARGS_0
+#define LOAD_ARGS_1(a1) \
+ LOAD_ARGS_0 () \
+ int __arg1 = (int) (a1);
+#define LOAD_REGS_1 \
+ register int _r4 __asm__ ("r4") = __arg1; \
+ LOAD_REGS_0
+#define ASM_ARGS_1 "r" (_r4)
+#define LOAD_ARGS_2(a1, a2) \
+ LOAD_ARGS_1 (a1) \
+ int __arg2 = (int) (a2);
+#define LOAD_REGS_2 \
+ register int _r5 __asm__ ("r5") = __arg2; \
+ LOAD_REGS_1
+#define ASM_ARGS_2 ASM_ARGS_1, "r" (_r5)
+#define LOAD_ARGS_3(a1, a2, a3) \
+ LOAD_ARGS_2 (a1, a2) \
+ int __arg3 = (int) (a3);
+#define LOAD_REGS_3 \
+ register int _r6 __asm__ ("r6") = __arg3; \
+ LOAD_REGS_2
+#define ASM_ARGS_3 ASM_ARGS_2, "r" (_r6)
+#define LOAD_ARGS_4(a1, a2, a3, a4) \
+ LOAD_ARGS_3 (a1, a2, a3) \
+ int __arg4 = (int) (a4);
+#define LOAD_REGS_4 \
+ register int _r7 __asm__ ("r7") = __arg4; \
+ LOAD_REGS_3
+#define ASM_ARGS_4 ASM_ARGS_3, "r" (_r7)
+#define LOAD_ARGS_5(a1, a2, a3, a4, a5) \
+ LOAD_ARGS_4 (a1, a2, a3, a4) \
+ int __arg5 = (int) (a5);
+#define LOAD_REGS_5 \
+ register int _r8 __asm__ ("r8") = __arg5; \
+ LOAD_REGS_4
+#define ASM_ARGS_5 ASM_ARGS_4, "r" (_r8)
+#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \
+ LOAD_ARGS_5 (a1, a2, a3, a4, a5) \
+ int __arg6 = (int) (a6);
+#define LOAD_REGS_6 \
+ register int _r9 __asm__ ("r9") = __arg6; \
+ LOAD_REGS_5
+#define ASM_ARGS_6 ASM_ARGS_5, "r" (_r9)
#endif /* __ASSEMBLER__ */
#endif /* _BITS_SYSCALLS_H */
diff --git a/libc/sysdeps/linux/nios2/bsd-_setjmp.S b/libc/sysdeps/linux/nios2/bsd-_setjmp.S
deleted file mode 100644
index e1350f55e..000000000
--- a/libc/sysdeps/linux/nios2/bsd-_setjmp.S
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * libc/sysdeps/linux/nios2/bsd-_setjmp.S
- *
- * Copyright (C) 2004,05,06 Microtronix Datacom Ltd
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Wentao Xu <wentao@microtronix.com>
- *
- */
-
-#include <features.h>
-#include <jmpbuf-offsets.h>
-
- .globl _setjmp
- .type _setjmp,@function
- .balign 4
-
-_setjmp:
- stw r16, (JB_REGS+ 0)(r4)
- stw r17, (JB_REGS+ 4)(r4)
- stw r18, (JB_REGS+ 8)(r4)
- stw r19, (JB_REGS+12)(r4)
- stw r20, (JB_REGS+16)(r4)
- stw r21, (JB_REGS+20)(r4)
- stw r22, (JB_REGS+24)(r4)
- stw r23, (JB_REGS+28)(r4)
-
- stw ra, JB_PC(r4)
- stw sp, JB_SP(r4)
- stw fp, JB_FP(r4)
- stw gp, JB_GP(r4)
-
-#ifdef __UCLIBC_HAS_FPU__
- SAVE_FPU r4 JB_FPREGS
-#endif
- stw r0, JB_SIZE(r4) /* signal mask is not saved */
- mov r2, zero
- ret
-
-
-
diff --git a/libc/sysdeps/linux/nios2/bsd-setjmp.S b/libc/sysdeps/linux/nios2/bsd-setjmp.S
deleted file mode 100644
index f533754dc..000000000
--- a/libc/sysdeps/linux/nios2/bsd-setjmp.S
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * libc/sysdeps/linux/nios2/bsd-setjmp.S
- *
- * Copyright (C) 2004,05,06 Microtronix Datacom Ltd
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Wentao Xu <wentao@microtronix.com>
- *
- */
-
-
-#include <features.h>
-#include <jmpbuf-offsets.h>
-
- .globl setjmp
- .type setjmp,@function
- .balign 4
-
-setjmp:
- stw r16, (JB_REGS+ 0)(r4)
- stw r17, (JB_REGS+ 4)(r4)
- stw r18, (JB_REGS+ 8)(r4)
- stw r19, (JB_REGS+12)(r4)
- stw r20, (JB_REGS+16)(r4)
- stw r21, (JB_REGS+20)(r4)
- stw r22, (JB_REGS+24)(r4)
- stw r23, (JB_REGS+28)(r4)
-
- stw ra, JB_PC(r4)
- stw sp, JB_SP(r4)
- stw fp, JB_FP(r4)
- stw gp, JB_GP(r4)
-
-#ifdef __UCLIBC_HAS_FPU__
- SAVE_FPU r4 JB_FPREGS
-#endif
-
- movui r5, 1
-#ifdef __PIC__
- /* just pray 16 bit offset is enough */
- br __sigjmp_save
-#else
- movhi r8, %hi(__sigjmp_save)
- ori r8, r8, %lo(__sigjmp_save)
- jmp r8
-#endif
-
-
diff --git a/libc/sysdeps/linux/nios2/clone.S b/libc/sysdeps/linux/nios2/clone.S
index 4afcb7d75..0626d8aa2 100644
--- a/libc/sysdeps/linux/nios2/clone.S
+++ b/libc/sysdeps/linux/nios2/clone.S
@@ -1,70 +1,94 @@
-/*
- * libc/sysdeps/linux/nios2/clone.S -- `clone' syscall for linux/nios2
- *
- * Copyright (C) 2004 Microtronix Datacom Ltd
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Wentao Xu <wentao@microtronix.com>
- */
-
-#define _ERRNO_H
+/* clone() implementation for Nios II.
+ Copyright (C) 2008-2016 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andrew Jenner <andrew@codesourcery.com>, 2008.
+
+ 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 <sysdep.h>
+#define _ERRNO_H 1
#include <bits/errno.h>
-#include <sys/syscall.h>
-
-#ifdef __NR_clone
-/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
-
-.text
-.global clone
-.type clone,%function
-.align 4
-clone:
- addi sp,sp,-8
- mov r8,r4
- stw ra,4(sp)
- stw r16,0(sp)
-
- mov r4,r6
- movi r2,-EINVAL
-
- /* sanity check */
- beq r8,zero,CLONE_ERROR_LABEL
- beq r5,zero,CLONE_ERROR_LABEL
-
- /* system call */
- movi r2,TRAP_ID_SYSCALL
- movi r3,__NR_clone
- trap
-
- /* child call the function */
- mov r4,r7
- bne r2,zero,CLONE_ERROR_LABEL
- callr r8
-
- /* exit if it returns */
- mov r4,r2
- movi r3,__NR_exit
+
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+#include <tcb-offsets.h>
+#endif
+
+#define CLONE_VM 0x00000100
+
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
+ void *parent_tidptr, void *tls, void *child_tidptr) */
+
+ .text
+ENTRY(__clone)
+ /* Sanity check arguments. */
+ movi r2, EINVAL
+
+ subi r5, r5, 8 /* Reserve argument save space. */
+ stw r4, 4(r5) /* Save function pointer. */
+ stw r7, 0(r5) /* Save argument pointer. */
+
+ /* Load arguments. */
+ mov r4, r6
+ ldw r6, 0(sp)
+ ldw r7, 8(sp)
+ ldw r8, 4(sp)
+
+ /* Do the system call. */
+ movi r2, SYS_ify (clone)
+
trap
-
-CLONE_ERROR_LABEL:
- movi r3,-4096
- sub r16,zero,r2
- bgeu r3,r2,CLONE_OK
-
- /* store errno */
- call __errno_location
- stw r16,0(r2)
- movi r2,-1
-
-CLONE_OK:
- ldw ra,4(sp)
- ldw r16,0(sp)
- addi sp,sp,8
+
+ /* See if we're on the newly created thread. */
+ beq r2, zero, thread_start
+ /* Successful return from the parent */
ret
-.size clone,.-clone
+thread_start:
+ /* We expect the argument registers to be preserved across system
+ calls and across task cloning, so flags should be in r4 here. */
+ andi r2, r4, CLONE_VM
+ bne r2, zero, 2f
+ DO_CALL (getpid, 0)
+#ifdef RESET_PID
+ stw r2, PID_OFFSET(r23)
+ stw r2, TID_OFFSET(r23)
+#endif
+2:
+ ldw r5, 4(sp) /* Function pointer. */
+ ldw r4, 0(sp) /* Argument pointer. */
+ addi sp, sp, 8
+
+ /* Call the user's function. */
+ callr r5
+ /* _exit with the result. */
+ mov r4, r2
+#ifdef __PIC__
+ nextpc r22
+1: movhi r8, %hiadj(_gp_got - 1b)
+ addi r8, r8, %lo(_gp_got - 1b)
+ add r22, r22, r8
+ ldw r8, %call(HIDDEN_JUMPTARGET(_exit))(r22)
+ jmp r8
+#else
+ jmpi _exit
#endif
+
+END(__clone)
+libc_hidden_def (__clone)
+weak_alias (__clone, clone)
diff --git a/libc/sysdeps/linux/nios2/clone.c b/libc/sysdeps/linux/nios2/clone.c
deleted file mode 100644
index eec9f42ff..000000000
--- a/libc/sysdeps/linux/nios2/clone.c
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * libc/sysdeps/linux/nios2/clone.c -- `clone' syscall for linux/nios2
- * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
- *
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- *
- *
- * Copyright (C) 2004,05 Microtronix Datacom Ltd
- * Copyright (C) 2002,03 NEC Electronics Corporation
- * Copyright (C) 2002,03 Miles Bader <miles@gnu.org>
- *
- * Written by Miles Bader <miles@gnu.org>
- * Nios2 port by Wentao Xu
- */
-
-#include <errno.h>
-#include <sched.h>
-#include <sys/syscall.h>
-
-int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg, ...)
-{
- register unsigned long rval __asm__ ("r2") = -EINVAL;
-
- if (fn && child_stack) {
- register unsigned long syscall __asm__ ("r3");
- register unsigned long arg0 __asm__ ("r4");
- register unsigned long arg1 __asm__ ("r5");
-
- /* Clone this thread. */
- rval = TRAP_ID_SYSCALL;
- syscall = __NR_clone;
- arg0 = flags;
- arg1 = (unsigned long)child_stack;
- __asm__ __volatile__ ("trap "
- : "=r" (rval), "=r" (syscall)
- : "0" (rval),"1" (syscall), "r" (arg0), "r" (arg1)
- );
-
- if (rval == 0) {
- /* In child thread, call fn and exit. */
- arg0 = (*fn) (arg);
- syscall = __NR_exit;
- __asm__ __volatile__ ("trap "
- : "=r" (rval), "=r" (syscall)
- : "1" (syscall), "r" (arg0));
- }
- }
-
- __syscall_return (int, rval);
-}
diff --git a/libc/sysdeps/linux/nios2/crt1.S b/libc/sysdeps/linux/nios2/crt1.S
index c178452ae..e13d59599 100644
--- a/libc/sysdeps/linux/nios2/crt1.S
+++ b/libc/sysdeps/linux/nios2/crt1.S
@@ -1,20 +1,40 @@
-/*
- * libc/sysdeps/linux/nios2/crt0.S -- entry point for linux/nios2
- *
- * Copyright (C) 2004,05,06 Microtronix Datacom Ltd
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Wentao Xu <wentao@microtronix.com>
- * Updated by Thomas Chou <thomas@wytron.com.tw> for crt1.S
- *
- */
+/* Startup code for Nios II
+ Copyright (C) 1995-2016 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.
+
+ In addition to the permissions in the GNU Lesser General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file with other
+ programs, and to distribute those programs without any restriction
+ coming from the use of this file. (The GNU Lesser General Public
+ License restrictions do apply in other respects; for example, they
+ cover modification of the file, and distribution when not linked
+ into another program.)
+
+ Note that people who make modified versions of this file are not
+ obligated to grant this special exception for their modified
+ versions; it is their choice whether to do so. The GNU Lesser
+ General Public License gives permission to release a modified
+ version without this exception; this exception also makes it
+ possible to release a modified version which carries forward this
+ exception.
+
+ 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 <features.h>
#include <asm/unistd.h>
-#define TRAP_ID_SYSCALL 0
.global _start
.type _start,@function
@@ -27,45 +47,64 @@
.type main,@function
.type __uClibc_main,@function
.text
- .balign 4
+
_start:
- nop
- br 0f
-0:
- /* load gp */
- movhi gp, %hiadj(_gp)
- addi gp, gp, %lo(_gp)
-
- /* load main, argc, argv from stack */
- movhi r4, %hi(main)
- ori r4, r4, %lo(main) /* main */
- ldw r5, 0(sp) /* argc */
- ldw r6, 4(sp) /* argv */
-
- /* load the 4th arg */
- movhi r7, %hi(_init)
- ori r7, r7, %lo(_init)
-
- /* Allocate space on the stack for 6-7th arg, reuse 5th space */
- addi sp,sp,-8
- /* push 5-7th args on stack */
- movhi r8, %hi(_fini)
- ori r8, r8, %lo(_fini)
- stw r8, 0(sp)
-
- stw r2, 4(sp) /* rtld_fini */
- stw sp, 8(sp) /* stack_end */
-
- /* call uClibc_main, shouldn't return */
-#ifdef __PIC__
- /* just pray 16 bit offset is enough */
- br __uClibc_main
-#else
- call __uClibc_main
-#endif
+ /* Set up the global pointer. */
+ movhi gp, %hiadj(_gp)
+ addi gp, gp, %lo(_gp)
+
+ /* Save the stack pointer. */
+ mov r2, sp
+
+ /* Create room on the stack for the fini, rtld_fini and stack_end args
+ to __uClibc_main. */
+ subi sp, sp, 12
+
+ /* Push stack_end */
+ stw r2, 8(sp)
+
+ /* Push rtld_fini */
+ stw r4, 4(sp)
+
+ /* Set up the GOT pointer. */
+ nextpc r22
+1: movhi r2, %hiadj(_gp_got - 1b)
+ addi r2, r2, %lo(_gp_got - 1b)
+ add r22, r22, r2
+
+ /* r6 == argv */
+ addi r6, sp, 16
+
+ /* r5 == argc */
+ ldw r5, 12(sp)
+
+ /* r4 == main */
+ movhi r4, %call_hiadj(main)
+ addi r4, r4, %call_lo(main)
+ add r4, r4, r22
+ ldw r4, 0(r4)
+
+ /* fp == 0 */
+ mov fp, zero
+
+ /* Let the libc call main and exit with its return code. */
+ movhi r2, %call_hiadj(__uClibc_main)
+ addi r2, r2, %call_lo(__uClibc_main)
+ add r2, r2, r22
+ ldw r2, 0(r2)
+ callr r2
+
+ /* should never get here....*/
+ movhi r2, %call_hiadj(abort)
+ addi r2, r2, %call_lo(abort)
+ add r2, r2, r22
+ ldw r2, 0(r2)
+ callr r2
- /* crash in the event of return */
-__exit:
- movui r2, TRAP_ID_SYSCALL
- movui r3, __NR_exit
- trap
+/* Define a symbol for the first piece of initialized data. */
+ .data
+ .globl __data_start
+__data_start:
+ .long 0
+ .weak data_start
+ data_start = __data_start
diff --git a/libc/sysdeps/linux/nios2/fpu_control.h b/libc/sysdeps/linux/nios2/fpu_control.h
deleted file mode 100644
index 4ba51b5eb..000000000
--- a/libc/sysdeps/linux/nios2/fpu_control.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* FPU control word bits. Nios2 version.
- Copyright (C) 1996, 1997, 1998, 1999, 2000 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/>. */
-
-#ifndef _FPU_CONTROL_H
-#define _FPU_CONTROL_H
-
-/* MIPS FPU floating point control register bits.
- *
- * 31-25 -> floating point conditions code bits 7-1. These bits are only
- * available in MIPS IV.
- * 24 -> flush denormalized results to zero instead of
- * causing unimplemented operation exception. This bit is only
- * available for MIPS III and newer.
- * 23 -> Condition bit
- * 22-18 -> reserved (read as 0, write with 0)
- * 17 -> cause bit for unimplemented operation
- * 16 -> cause bit for invalid exception
- * 15 -> cause bit for division by zero exception
- * 14 -> cause bit for overflow exception
- * 13 -> cause bit for underflow exception
- * 12 -> cause bit for inexact exception
- * 11 -> enable exception for invalid exception
- * 10 -> enable exception for division by zero exception
- * 9 -> enable exception for overflow exception
- * 8 -> enable exception for underflow exception
- * 7 -> enable exception for inexact exception
- * 6 -> flag invalid exception
- * 5 -> flag division by zero exception
- * 4 -> flag overflow exception
- * 3 -> flag underflow exception
- * 2 -> flag inexact exception
- * 1-0 -> rounding control
- *
- *
- * Rounding Control:
- * 00 - rounding to nearest (RN)
- * 01 - rounding toward zero (RZ)
- * 10 - rounding (up) toward plus infinity (RP)
- * 11 - rounding (down)toward minus infinity (RM)
- */
-
-#include <features.h>
-
-/* masking of interrupts */
-#define _FPU_MASK_V 0x0800 /* Invalid operation */
-#define _FPU_MASK_Z 0x0400 /* Division by zero */
-#define _FPU_MASK_O 0x0200 /* Overflow */
-#define _FPU_MASK_U 0x0100 /* Underflow */
-#define _FPU_MASK_I 0x0080 /* Inexact operation */
-
-/* flush denormalized numbers to zero */
-#define _FPU_FLUSH_TZ 0x1000000
-
-/* rounding control */
-#define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */
-#define _FPU_RC_ZERO 0x1
-#define _FPU_RC_UP 0x2
-#define _FPU_RC_DOWN 0x3
-
-#define _FPU_RESERVED 0xfe3c0000 /* Reserved bits in cw */
-
-
-/* The fdlibm code requires strict IEEE double precision arithmetic,
- and no interrupts for exceptions, rounding to nearest. */
-
-#define _FPU_DEFAULT 0x00000000
-
-/* IEEE: same as above, but exceptions */
-#define _FPU_IEEE 0x00000F80
-
-/* Type of the control word. */
-typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
-
-/* Macros for accessing the hardware control word. */
-#define _FPU_GETCW(cw) __asm__ ("cfc1 %0,$31" : "=r" (cw))
-#define _FPU_SETCW(cw) __asm__ ("ctc1 %0,$31" : : "r" (cw))
-
-#if 0
-/* Default control word set at startup. */
-extern fpu_control_t __fpu_control;
-#endif
-
-#endif /* fpu_control.h */
diff --git a/libc/sysdeps/linux/nios2/jmpbuf-offsets.h b/libc/sysdeps/linux/nios2/jmpbuf-offsets.h
index b7d19cafb..20482b380 100644
--- a/libc/sysdeps/linux/nios2/jmpbuf-offsets.h
+++ b/libc/sysdeps/linux/nios2/jmpbuf-offsets.h
@@ -6,12 +6,16 @@
#include <features.h>
-#define JB_REGS 0
-#define JB_PC 32
-#define JB_SP 36
-#define JB_FP 40
-#define JB_GP 44
-#define JB_FPREGS 48
+#define JB_R16 0
+#define JB_R17 1
+#define JB_R18 2
+#define JB_R19 3
+#define JB_R20 4
+#define JB_R21 5
+#define JB_R22 6
+#define JB_FP 7
+#define JB_RA 8
+#define JB_SP 9
#ifdef __UCLIBC_HAS_FPU__
# define JB_SIZE 304
diff --git a/libc/sysdeps/linux/nios2/jmpbuf-unwind.h b/libc/sysdeps/linux/nios2/jmpbuf-unwind.h
index c22ab2409..fe0028b09 100644
--- a/libc/sysdeps/linux/nios2/jmpbuf-unwind.h
+++ b/libc/sysdeps/linux/nios2/jmpbuf-unwind.h
@@ -1,12 +1,39 @@
-/*
- * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
- *
- * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
- */
+/* Examine __jmp_buf for unwinding frames. Nios II version.
+ Copyright (C) 2005-2016 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 <setjmp.h>
+#include <jmpbuf-offsets.h>
/* Test if longjmp to JMPBUF would unwind the frame
containing a local variable at ADDRESS. */
+
#define _JMPBUF_UNWINDS(jmpbuf, address) \
- ((void *) (address) < (void *) (jmpbuf)->__sp)
+ ((void *) (address) < (void *) (jmpbuf[JB_SP]))
+
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+
+#include <stdint.h>
+#include <unwind.h>
+
+#define _JMPBUF_CFA_UNWINDS_ADJ(_jmpbuf, _context, _adj) \
+ _JMPBUF_UNWINDS_ADJ (_jmpbuf, (void *) _Unwind_GetCFA (_context), _adj)
+
+#define _JMPBUF_UNWINDS_ADJ(_jmpbuf, _address, _adj) \
+ ((uintptr_t) (_address) - (_adj) < (uintptr_t) (_jmpbuf)[JB_SP] - (_adj))
+
+#endif
diff --git a/libc/sysdeps/linux/nios2/setjmp.S b/libc/sysdeps/linux/nios2/setjmp.S
index 6071685b0..8050dba89 100644
--- a/libc/sysdeps/linux/nios2/setjmp.S
+++ b/libc/sysdeps/linux/nios2/setjmp.S
@@ -1,49 +1,56 @@
-/*
- * libc/sysdeps/linux/nios2/setjmp.S
- *
- * Copyright (C) 2004,05,06 Microtronix Datacom Ltd
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Wentao Xu <wentao@microtronix.com>
- *
- */
-
-#include <features.h>
+/* setjmp for Nios II.
+ Copyright (C) 1991-2016 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>
#include <jmpbuf-offsets.h>
-.globl __sigsetjmp
-.type __sigsetjmp,@function
-.balign 4
-
-__sigsetjmp:
- stw r16, (JB_REGS+ 0)(r4)
- stw r17, (JB_REGS+ 4)(r4)
- stw r18, (JB_REGS+ 8)(r4)
- stw r19, (JB_REGS+12)(r4)
- stw r20, (JB_REGS+16)(r4)
- stw r21, (JB_REGS+20)(r4)
- stw r22, (JB_REGS+24)(r4)
- stw r23, (JB_REGS+28)(r4)
-
- stw ra, JB_PC(r4)
- stw sp, JB_SP(r4)
- stw fp, JB_FP(r4)
- stw gp, JB_GP(r4)
-
-#ifdef __UCLIBC_HAS_FPU__
- SAVE_FPU r4 JB_FPREGS
-#endif
-
-#ifdef __PIC__
- /* just pray 16 bit offset is enough */
- br __sigjmp_save
-#else
- movhi r8, %hi(__sigjmp_save)
- ori r8, r8, %lo(__sigjmp_save)
- jmp r8
-#endif
-
-.size __sigsetjmp,.-__sigsetjmp
+ .text
+ENTRY(setjmp)
+ movi r5, 1
+ br __sigsetjmp
+END(setjmp)
+libc_hidden_def(setjmp)
+
+ENTRY(_setjmp)
+ mov r5, zero
+ br __sigsetjmp
+END(_setjmp)
+libc_hidden_def(_setjmp)
+
+/* Save the current program position in ENV and return 0. */
+ENTRY(__sigsetjmp)
+ stw r16, (JB_R16*4)(r4)
+ stw r17, (JB_R17*4)(r4)
+ stw r18, (JB_R18*4)(r4)
+ stw r19, (JB_R19*4)(r4)
+ stw r20, (JB_R20*4)(r4)
+ stw r21, (JB_R21*4)(r4)
+ stw r22, (JB_R22*4)(r4)
+ stw fp, (JB_FP*4)(r4)
+ stw ra, (JB_RA*4)(r4)
+ stw sp, (JB_SP*4)(r4)
+ /* Save the signal mask if requested. */
+ nextpc r2
+
+1: movhi r3, %hiadj(__sigjmp_save - 1b)
+ addi r3, r3, %lo(__sigjmp_save - 1b)
+ add r2, r2, r3
+ jmp r2
+
+END(__sigsetjmp)
+libc_hidden_def(__sigsetjmp)
diff --git a/libc/sysdeps/linux/nios2/syscall.c b/libc/sysdeps/linux/nios2/syscall.c
deleted file mode 100644
index 60ddd02a6..000000000
--- a/libc/sysdeps/linux/nios2/syscall.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * libc/sysdeps/linux/nios2/syscall.c -- generic syscall function for linux/nios2
- *
- * Copyright (C) 2004 Microtronix Datacom Ltd.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program 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 Library General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this program; see the file COPYING.LIB. If not, see
- * <http://www.gnu.org/licenses/>.
- */
-
-#include <features.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/syscall.h>
-
-
-long syscall(long sysnum, long a, long b, long c, long d, long e, long f)
-{
- register long _r2 __asm__("r2")=(long)TRAP_ID_SYSCALL;
- register long _r3 __asm__("r3")=(long)sysnum;
-
- register long _r4 __asm__("r4")=(long)(a);
- register long _r5 __asm__("r5")=(long)(b);
- register long _r6 __asm__("r6")=(long)(c);
- register long _r7 __asm__("r7")=(long)(d);
- register long _r8 __asm__("r8")=(long)(e);
- register long _r9 __asm__("r9")=(long)(f);
- __asm__ __volatile__(
- "trap "
- : "=r"(_r2), "=r"(_r3)
- : "0"(_r2), "1"(_r3),
- "r"(_r4), "r"(_r5), "r"(_r6), "r"(_r7), "r"(_r8), "r"(_r9)
- : "memory");
-
- __syscall_return (long, _r2);
-}
-
diff --git a/libc/sysdeps/linux/nios2/sysdep.h b/libc/sysdeps/linux/nios2/sysdep.h
new file mode 100644
index 000000000..681381815
--- /dev/null
+++ b/libc/sysdeps/linux/nios2/sysdep.h
@@ -0,0 +1,34 @@
+/* Assembler macros for Nios II.
+ Copyright (C) 2015-2016 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 <common/sysdep.h>
+
+#ifdef __ASSEMBLER__
+
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+
+#define ENTRY(name) \
+ .globl C_SYMBOL_NAME(name); \
+ .type C_SYMBOL_NAME(name),%function; \
+ C_LABEL(name)
+
+#undef END
+#define END(name) \
+ ASM_SIZE_DIRECTIVE(name)
+
+#endif /* __ASSEMBLER__ */
diff --git a/libc/sysdeps/linux/nios2/vfork.S b/libc/sysdeps/linux/nios2/vfork.S
index 2aee81e6c..99e4a73e1 100644
--- a/libc/sysdeps/linux/nios2/vfork.S
+++ b/libc/sysdeps/linux/nios2/vfork.S
@@ -1,50 +1,54 @@
-/*
- * libc/sysdeps/linux/nios2/vfork.S -- `vfork' syscall for linux/nios2
- *
- * Copyright (C) 2004 Microtronix Datacom Ltd
- *
- * This file is subject to the terms and conditions of the GNU Lesser
- * General Public License. See the file COPYING.LIB in the main
- * directory of this archive for more details.
- *
- * Written by Wentao Xu <wentao@microtronix.com>
- */
-
-#include <sys/syscall.h>
-
-#define __NR_vfork 1071
-
-.text
-.global __vfork
-.hidden __vfork
-.type __vfork,%function
-.align 4
-__vfork:
- movui r2, TRAP_ID_SYSCALL
- movui r3, __NR_vfork
- trap
- movi r8, -4096
- bltu r8, r2, fix_errno
- ret
-fix_errno:
- sub r8, r0, r2
-
- addi sp, sp, -8
- stw ra, 4(sp)
- stw r8, 0(sp)
-#ifndef __PIC__
- call __errno_location
-#else
-
+/* vfork for Nios II Linux.
+ Copyright (C) 2005-2016 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>
+
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+#include <tcb-offsets.h>
+#endif
+
+ENTRY(__vfork)
+
+#ifdef RESET_PID
+ ldw r6, PID_OFFSET(r23)
+ sub r7, zero, r6
+ bne r7, zero, 2f
+ movhi r7, %hi(0x80000000)
+2:
+ stw r7, PID_OFFSET(r23)
#endif
- ldw ra, 4(sp)
- ldw r8, 0(sp)
- stw r8, 0(r2)
-
- addi r2, r0, -1
- addi sp, sp, 8
- ret
-
-.size __vfork,.-__vfork
-weak_alias(__vfork,vfork)
+
+ movi r4, 0x4111 /* (CLONE_VM | CLONE_VFORK | SIGCHLD) */
+ mov r5, zero
+
+ /* Do the system call. */
+ movi r2, SYS_ify(clone)
+
+ trap
+
+ beq r2, zero, 1f
+#ifdef RESET_PID
+ stw r6, PID_OFFSET(r23)
+#endif
+1:
+ ret
+
+END(__vfork)
+
+weak_alias(__vfork, vfork)
libc_hidden_def(vfork)