summaryrefslogtreecommitdiffstats
path: root/libc/sysdeps/linux
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux')
-rw-r--r--libc/sysdeps/linux/mips/Makefile.arch12
-rw-r--r--libc/sysdeps/linux/mips/__longjmp.c42
-rw-r--r--libc/sysdeps/linux/mips/bits/dlfcn.h28
-rw-r--r--libc/sysdeps/linux/mips/bits/fcntl.h127
-rw-r--r--libc/sysdeps/linux/mips/bits/kernel_stat.h74
-rw-r--r--libc/sysdeps/linux/mips/bits/kernel_types.h2
-rw-r--r--libc/sysdeps/linux/mips/bits/mman.h30
-rw-r--r--libc/sysdeps/linux/mips/bits/resource.h22
-rw-r--r--libc/sysdeps/linux/mips/bits/setjmp.h10
-rw-r--r--libc/sysdeps/linux/mips/bits/sigcontext.h84
-rw-r--r--libc/sysdeps/linux/mips/bits/sigcontextinfo.h18
-rw-r--r--libc/sysdeps/linux/mips/bits/siginfo.h27
-rw-r--r--libc/sysdeps/linux/mips/bits/socket.h31
-rw-r--r--libc/sysdeps/linux/mips/bits/stat.h77
-rw-r--r--libc/sysdeps/linux/mips/bits/syscalls.h563
-rw-r--r--libc/sysdeps/linux/mips/bits/uClibc_arch_features.h3
-rw-r--r--libc/sysdeps/linux/mips/bits/wordsize.h4
-rw-r--r--libc/sysdeps/linux/mips/brk.c7
-rw-r--r--libc/sysdeps/linux/mips/bsd-_setjmp.S7
-rw-r--r--libc/sysdeps/linux/mips/bsd-setjmp.S7
-rw-r--r--libc/sysdeps/linux/mips/cacheflush.c6
-rw-r--r--libc/sysdeps/linux/mips/clone.S161
-rw-r--r--libc/sysdeps/linux/mips/crt1.S26
-rw-r--r--libc/sysdeps/linux/mips/crti.S108
-rw-r--r--libc/sysdeps/linux/mips/crtn.S100
-rw-r--r--libc/sysdeps/linux/mips/fpu_control.h2
-rw-r--r--libc/sysdeps/linux/mips/pipe.S32
-rw-r--r--libc/sysdeps/linux/mips/posix_fadvise.c39
-rw-r--r--libc/sysdeps/linux/mips/posix_fadvise64.c43
-rw-r--r--libc/sysdeps/linux/mips/pread_write.c251
-rw-r--r--libc/sysdeps/linux/mips/readahead.c41
-rw-r--r--libc/sysdeps/linux/mips/setjmp.S10
-rw-r--r--libc/sysdeps/linux/mips/setjmp_aux.c70
-rw-r--r--libc/sysdeps/linux/mips/sigaction.c177
-rw-r--r--libc/sysdeps/linux/mips/sys/asm.h16
-rw-r--r--libc/sysdeps/linux/mips/sys/regdef.h2
-rw-r--r--libc/sysdeps/linux/mips/sys/sysmips.h12
-rw-r--r--libc/sysdeps/linux/mips/sys/ucontext.h201
-rw-r--r--libc/sysdeps/linux/mips/sys/user.h12
-rw-r--r--libc/sysdeps/linux/mips/syscall.S6
-rw-r--r--libc/sysdeps/linux/mips/sysmips.c2
41 files changed, 1606 insertions, 886 deletions
diff --git a/libc/sysdeps/linux/mips/Makefile.arch b/libc/sysdeps/linux/mips/Makefile.arch
index 1742eaac4..da5ca1e0f 100644
--- a/libc/sysdeps/linux/mips/Makefile.arch
+++ b/libc/sysdeps/linux/mips/Makefile.arch
@@ -1,18 +1,18 @@
# Makefile for uClibc
#
-# Copyright (C) 2006 Steven J. Hill <sjhill@uclibc.org>
# Copyright (C) 2000-2005 Erik Andersen <andersen@uclibc.org>
#
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := __longjmp.c brk.c setjmp_aux.c mmap.c cacheflush.c \
- pread_write.c sysmips.c _test_and_set.c sigaction.c
+CSRC := \
+ __longjmp.c brk.c setjmp_aux.c mmap.c __syscall_error.c \
+ cacheflush.c pread_write.c sysmips.c _test_and_set.c sigaction.c \
+ readahead.c posix_fadvise.c posix_fadvise64.c
-SSRC := bsd-_setjmp.S bsd-setjmp.S setjmp.S clone.S syscall.S \
- syscall_error.S pipe.S vfork.S
+SSRC := bsd-_setjmp.S bsd-setjmp.S setjmp.S clone.S syscall.S pipe.S
-ARCH_HEADERS := sgidefs.h sysdep.h
+ARCH_HEADERS := sgidefs.h
# regdef.h
include $(top_srcdir)libc/sysdeps/linux/Makefile.commonarch
diff --git a/libc/sysdeps/linux/mips/__longjmp.c b/libc/sysdeps/linux/mips/__longjmp.c
index ee9c455cc..9dc09f27a 100644
--- a/libc/sysdeps/linux/mips/__longjmp.c
+++ b/libc/sysdeps/linux/mips/__longjmp.c
@@ -20,6 +20,7 @@
#include <features.h>
#include <setjmp.h>
#include <stdlib.h>
+#include <sgidefs.h>
#ifndef __GNUC__
#error This file uses GNU C extensions; you must compile with GCC.
@@ -38,12 +39,23 @@ void __longjmp (__jmp_buf env, int val_arg)
/* Pull back the floating point callee-saved registers. */
#if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+ __asm__ __volatile__ ("l.d $f24, %0" : : "m" (env[0].__fpregs[0]));
+ __asm__ __volatile__ ("l.d $f25, %0" : : "m" (env[0].__fpregs[1]));
+ __asm__ __volatile__ ("l.d $f26, %0" : : "m" (env[0].__fpregs[2]));
+ __asm__ __volatile__ ("l.d $f27, %0" : : "m" (env[0].__fpregs[3]));
+ __asm__ __volatile__ ("l.d $f28, %0" : : "m" (env[0].__fpregs[4]));
+ __asm__ __volatile__ ("l.d $f29, %0" : : "m" (env[0].__fpregs[5]));
+ __asm__ __volatile__ ("l.d $f30, %0" : : "m" (env[0].__fpregs[6]));
+ __asm__ __volatile__ ("l.d $f31, %0" : : "m" (env[0].__fpregs[7]));
+#else /* O32 || N32 */
__asm__ __volatile__ ("l.d $f20, %0" : : "m" (env[0].__fpregs[0]));
__asm__ __volatile__ ("l.d $f22, %0" : : "m" (env[0].__fpregs[1]));
__asm__ __volatile__ ("l.d $f24, %0" : : "m" (env[0].__fpregs[2]));
__asm__ __volatile__ ("l.d $f26, %0" : : "m" (env[0].__fpregs[3]));
__asm__ __volatile__ ("l.d $f28, %0" : : "m" (env[0].__fpregs[4]));
__asm__ __volatile__ ("l.d $f30, %0" : : "m" (env[0].__fpregs[5]));
+#endif /* O32 || N32 */
/* Get and reconstruct the floating point csr. */
__asm__ __volatile__ ("lw $2, %0" : : "m" (env[0].__fpc_csr));
@@ -51,9 +63,14 @@ void __longjmp (__jmp_buf env, int val_arg)
#endif
/* Get the GP. */
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+ __asm__ __volatile__ ("ld $gp, %0" : : "m" (env[0].__gp));
+#else /* O32 || N32 */
__asm__ __volatile__ ("lw $gp, %0" : : "m" (env[0].__gp));
+#endif /* O32 || N32 */
/* Get the callee-saved registers. */
+#if _MIPS_SIM == _MIPS_SIM_ABI32
__asm__ __volatile__ ("lw $16, %0" : : "m" (env[0].__regs[0]));
__asm__ __volatile__ ("lw $17, %0" : : "m" (env[0].__regs[1]));
__asm__ __volatile__ ("lw $18, %0" : : "m" (env[0].__regs[2]));
@@ -62,15 +79,36 @@ void __longjmp (__jmp_buf env, int val_arg)
__asm__ __volatile__ ("lw $21, %0" : : "m" (env[0].__regs[5]));
__asm__ __volatile__ ("lw $22, %0" : : "m" (env[0].__regs[6]));
__asm__ __volatile__ ("lw $23, %0" : : "m" (env[0].__regs[7]));
+#else /* N32 || N64 */
+ __asm__ __volatile__ ("ld $16, %0" : : "m" (env[0].__regs[0]));
+ __asm__ __volatile__ ("ld $17, %0" : : "m" (env[0].__regs[1]));
+ __asm__ __volatile__ ("ld $18, %0" : : "m" (env[0].__regs[2]));
+ __asm__ __volatile__ ("ld $19, %0" : : "m" (env[0].__regs[3]));
+ __asm__ __volatile__ ("ld $20, %0" : : "m" (env[0].__regs[4]));
+ __asm__ __volatile__ ("ld $21, %0" : : "m" (env[0].__regs[5]));
+ __asm__ __volatile__ ("ld $22, %0" : : "m" (env[0].__regs[6]));
+ __asm__ __volatile__ ("ld $23, %0" : : "m" (env[0].__regs[7]));
+#endif /* N32 || N64 */
/* Get the PC. */
+#if _MIPS_SIM == _MIPS_SIM_ABI32
__asm__ __volatile__ ("lw $25, %0" : : "m" (env[0].__pc));
+#elif _MIPS_SIM == _MIPS_SIM_NABI32
+ __asm__ __volatile__ ("lw $31, %0" : : "m" (env[0].__pc));
+#else /* N64 */
+ __asm__ __volatile__ ("ld $31, %0" : : "m" (env[0].__pc));
+#endif /* N64 */
/* Restore the stack pointer and the FP. They have to be restored
last and in a single asm as gcc, depending on options used, may
use either of them to access env. */
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+ __asm__ __volatile__ ("ld $29, %0\n\t"
+ "ld $30, %1\n\t" : : "m" (env[0].__sp), "m" (env[0].__fp));
+#else /* O32 || N32 */
__asm__ __volatile__ ("lw $29, %0\n\t"
"lw $30, %1\n\t" : : "m" (env[0].__sp), "m" (env[0].__fp));
+#endif /* O32 || N32 */
/* Give setjmp 1 if given a 0, or what they gave us if non-zero. */
if (val == 0)
@@ -78,7 +116,11 @@ void __longjmp (__jmp_buf env, int val_arg)
else
__asm__ __volatile__ ("move $2, %0" : : "r" (val));
+#if _MIPS_SIM == _MIPS_SIM_ABI32
__asm__ __volatile__ ("jr $25");
+#else /* N32 || N64 */
+ __asm__ __volatile__ ("jr $31");
+#endif /* N32 || N64 */
/* Avoid `volatile function does return' warnings. */
for (;;);
diff --git a/libc/sysdeps/linux/mips/bits/dlfcn.h b/libc/sysdeps/linux/mips/bits/dlfcn.h
index 55e68e91e..1f054f979 100644
--- a/libc/sysdeps/linux/mips/bits/dlfcn.h
+++ b/libc/sysdeps/linux/mips/bits/dlfcn.h
@@ -1,5 +1,6 @@
/* System dependent definitions for run-time dynamic loading.
- Copyright (C) 1996, 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1999, 2000, 2001, 2004
+ 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
@@ -24,8 +25,9 @@
/* The MODE argument to `dlopen' contains one of the following: */
#define RTLD_LAZY 0x0001 /* Lazy function call binding. */
#define RTLD_NOW 0x0002 /* Immediate function call binding. */
-#define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */
+#define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */
#define RTLD_NOLOAD 0x00008 /* Do not load the object. */
+#define RTLD_DEEPBIND 0x00010 /* Use deep binding. */
/* If the following bit is set in the MODE argument to `dlopen',
the symbols of the loaded object and its dependencies are made
@@ -40,3 +42,25 @@
/* Do not delete object when closed. */
#define RTLD_NODELETE 0x01000
+#if 0 /*def __USE_GNU*/
+/* To support profiling of shared objects it is a good idea to call
+ the function found using `dlsym' using the following macro since
+ these calls do not use the PLT. But this would mean the dynamic
+ loader has no chance to find out when the function is called. The
+ macro applies the necessary magic so that profiling is possible.
+ Rewrite
+ foo = (*fctp) (arg1, arg2);
+ into
+ foo = DL_CALL_FCT (fctp, (arg1, arg2));
+*/
+# define DL_CALL_FCT(fctp, args) \
+ (_dl_mcount_wrapper_check ((void *) (fctp)), (*(fctp)) args)
+
+__BEGIN_DECLS
+
+/* This function calls the profiling functions. */
+extern void _dl_mcount_wrapper_check (void *__selfpc) __THROW;
+
+__END_DECLS
+
+#endif
diff --git a/libc/sysdeps/linux/mips/bits/fcntl.h b/libc/sysdeps/linux/mips/bits/fcntl.h
index 87affe3f3..90011d5d0 100644
--- a/libc/sysdeps/linux/mips/bits/fcntl.h
+++ b/libc/sysdeps/linux/mips/bits/fcntl.h
@@ -18,32 +18,33 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
-#ifndef _FCNTL_H
+#ifndef _FCNTL_H
# error "Never use <bits/fcntl.h> directly; include <fcntl.h> instead."
#endif
#include <sgidefs.h>
#include <sys/types.h>
+#ifdef __USE_GNU
+# include <bits/uio.h>
+#endif
+
/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
located on an ext2 file system */
-#define O_ACCMODE 0x0003
-#define O_RDONLY 0x0000
-#define O_WRONLY 0x0001
-#define O_RDWR 0x0002
-#define O_APPEND 0x0008
-#define O_SYNC 0x0010
-#define O_NONBLOCK 0x0080
-#define O_CREAT 0x0100 /* not fcntl */
-#define O_TRUNC 0x0200 /* not fcntl */
-#define O_EXCL 0x0400 /* not fcntl */
-#define O_NOCTTY 0x0800 /* not fcntl */
-#define O_FSYNC O_SYNC
-#define O_ASYNC 0x1000
-
-#ifdef __USE_LARGEFILE64
-# define O_LARGEFILE 0x2000 /* Allow large file opens. */
-#endif
+#define O_ACCMODE 0003
+#define O_RDONLY 00
+#define O_WRONLY 01
+#define O_RDWR 02
+#define O_APPEND 0x0008
+#define O_SYNC 0x0010
+#define O_NONBLOCK 0x0080
+#define O_NDELAY O_NONBLOCK
+#define O_CREAT 0x0100 /* not fcntl */
+#define O_TRUNC 0x0200 /* not fcntl */
+#define O_EXCL 0x0400 /* not fcntl */
+#define O_NOCTTY 0x0800 /* not fcntl */
+#define O_FSYNC O_SYNC
+#define O_ASYNC 0x1000
#ifdef __USE_GNU
# define O_NOFOLLOW 0x20000 /* Do not follow links. */
@@ -52,16 +53,22 @@
# define O_NOATIME 0x40000 /* Do not set atime. */
#endif
-#define O_NDELAY O_NONBLOCK
-
-/* For now Linux has no synchronisity options for data and read
- operations. We define the symbols here but let them do the same as
- O_SYNC since this is a superset. */
+/* For now Linux has no synchronisity options for data and read operations.
+ We define the symbols here but let them do the same as O_SYNC since
+ this is a superset. */
#if defined __USE_POSIX199309 || defined __USE_UNIX98
# define O_DSYNC O_SYNC /* Synchronize data. */
# define O_RSYNC O_SYNC /* Synchronize read operations. */
#endif
+#ifdef __USE_LARGEFILE64
+# if __WORDSIZE == 64
+# define O_LARGEFILE 0
+# else
+# define O_LARGEFILE 0x2000 /* Allow large file opens. */
+# endif
+#endif
+
/* Values for the second argument to `fcntl'. */
#define F_DUPFD 0 /* Duplicate file descriptor. */
#define F_GETFD 1 /* Get file descriptor flags. */
@@ -78,9 +85,15 @@
# define F_SETLKW F_SETLKW64 /* Set record locking info (blocking). */
#endif
-#define F_GETLK64 33 /* Get record locking info. */
-#define F_SETLK64 34 /* Set record locking info (non-blocking). */
-#define F_SETLKW64 35 /* Set record locking info (blocking). */
+#if __WORDSIZE == 64
+# define F_GETLK64 14 /* Get record locking info. */
+# define F_SETLK64 6 /* Set record locking info (non-blocking). */
+# define F_SETLKW64 7 /* Set record locking info (blocking). */
+#else
+# define F_GETLK64 33 /* Get record locking info. */
+# define F_SETLK64 34 /* Set record locking info (non-blocking). */
+# define F_SETLKW64 35 /* Set record locking info (blocking). */
+#endif
#if defined __USE_BSD || defined __USE_UNIX98
# define F_SETOWN 24 /* Get owner of socket (receiver of SIGIO). */
@@ -96,9 +109,11 @@
# define F_SETLEASE 1024 /* Set a lease. */
# define F_GETLEASE 1025 /* Enquire what lease is active. */
# define F_NOTIFY 1026 /* Request notfications on a directory. */
+# define F_DUPFD_CLOEXEC 1030 /* Duplicate file descriptor with
+ close-on-exit set on new fd. */
#endif
-/* for F_[GET|SET]FL */
+/* For F_[GET|SET]FL. */
#define FD_CLOEXEC 1 /* actually anything with low bit set goes */
/* For posix fcntl() and `l_type' field of a `struct flock' for lockf(). */
@@ -106,12 +121,12 @@
#define F_WRLCK 1 /* Write lock. */
#define F_UNLCK 2 /* Remove lock. */
-/* for old implementation of bsd flock () */
+/* For old implementation of bsd flock(). */
#define F_EXLCK 4 /* or 3 */
#define F_SHLCK 8 /* or 4 */
#ifdef __USE_BSD
-/* Operations for bsd flock(), also used by the kernel implementation */
+/* Operations for bsd flock(), also used by the kernel implementation. */
# define LOCK_SH 1 /* shared lock */
# define LOCK_EX 2 /* exclusive lock */
# define LOCK_NB 4 /* or'd with one of the above to prevent
@@ -137,7 +152,7 @@
# define DN_MULTISHOT 0x80000000 /* Don't remove notifier. */
#endif
-typedef struct flock
+struct flock
{
short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
@@ -159,7 +174,8 @@ typedef struct flock
flock in o32 and n32, never has this field. */
long int pad[4];
#endif
-} flock_t;
+ };
+typedef struct flock flock_t;
#ifdef __USE_LARGEFILE64
struct flock64
@@ -172,7 +188,6 @@ struct flock64
};
#endif
-
/* Define some more compatibility macros to be backward compatible with
BSD systems which did not managed to hide these kernel macros. */
#ifdef __USE_BSD
@@ -193,16 +208,58 @@ struct flock64
# define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */
#endif
-/* Linux-specific operations for posix_fadvise. */
+
#ifdef __USE_GNU
-# define LINUX_FADV_ASYNC_WRITE 32 /* Start writeout on range. */
-# define LINUX_FADV_WRITE_WAIT 33 /* Wait upon writeout to range. */
+#if 0
+/* Flags for SYNC_FILE_RANGE. */
+# define SYNC_FILE_RANGE_WAIT_BEFORE 1 /* Wait upon writeout of all pages
+ in the range before performing the
+ write. */
+# define SYNC_FILE_RANGE_WRITE 2 /* Initiate writeout of all those
+ dirty pages in the range which are
+ not presently under writeback. */
+# define SYNC_FILE_RANGE_WAIT_AFTER 4 /* Wait upon writeout of all pages in
+ the range after performing the
+ write. */
+#endif
+
+/* Flags for SPLICE and VMSPLICE. */
+# define SPLICE_F_MOVE 1 /* Move pages instead of copying. */
+# define SPLICE_F_NONBLOCK 2 /* Don't block on the pipe splicing
+ (but we may still block on the fd
+ we splice from/to). */
+# define SPLICE_F_MORE 4 /* Expect more data. */
+# define SPLICE_F_GIFT 8 /* Pages passed in are a gift. */
#endif
__BEGIN_DECLS
+#ifdef __USE_GNU
+
/* Provide kernel hint to read ahead. */
extern ssize_t readahead (int __fd, __off64_t __offset, size_t __count)
__THROW;
+
+#if 0
+/* Selective file content synch'ing. */
+extern int sync_file_range (int __fd, __off64_t __from, __off64_t __to,
+ unsigned int __flags);
+#endif
+
+/* Splice address range into a pipe. */
+extern ssize_t vmsplice (int __fdout, const struct iovec *__iov,
+ size_t __count, unsigned int __flags);
+
+/* Splice two files together. */
+extern ssize_t splice (int __fdin, __off64_t *__offin, int __fdout,
+ __off64_t *__offout, size_t __len,
+ unsigned int __flags);
+
+/* In-kernel implementation of tee for pipe buffers. */
+extern ssize_t tee (int __fdin, int __fdout, size_t __len,
+ unsigned int __flags);
+
+#endif
__END_DECLS
+
diff --git a/libc/sysdeps/linux/mips/bits/kernel_stat.h b/libc/sysdeps/linux/mips/bits/kernel_stat.h
index 2bce38884..13c23d359 100644
--- a/libc/sysdeps/linux/mips/bits/kernel_stat.h
+++ b/libc/sysdeps/linux/mips/bits/kernel_stat.h
@@ -1,13 +1,65 @@
#ifndef _BITS_STAT_STRUCT_H
#define _BITS_STAT_STRUCT_H
+#ifndef _LIBC
+#error bits/kernel_stat.h is for internal uClibc use only!
+#endif
+
/* 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... */
-#if __WORDSIZE == 64
-#define kernel_stat kernel_stat64
-#else
+#include <sgidefs.h>
+
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+/* The memory layout is the same as of struct stat64 of the 32-bit kernel. */
+struct kernel_stat {
+ __kernel_dev_t st_dev;
+ unsigned int st_pad1[3];
+ __kernel_ino_t st_ino;
+ __kernel_mode_t st_mode;
+ __kernel_nlink_t st_nlink;
+ __kernel_uid_t st_uid;
+ __kernel_gid_t st_gid;
+ __kernel_dev_t st_rdev;
+ unsigned int st_pad2[3];
+ __kernel_off_t st_size;
+ unsigned int st_atime;
+ unsigned int st_atime_nsec;
+ unsigned int st_mtime;
+ unsigned int st_mtime_nsec;
+ unsigned int st_ctime;
+ unsigned int st_ctime_nsec;
+ unsigned int st_blksize;
+ unsigned int reserved3;
+ unsigned long st_blocks;
+};
+#define kernel_stat64 kernel_stat
+#elif _MIPS_SIM == _MIPS_SIM_NABI32
+/* The memory layout is the same as of struct stat64 of the 32-bit kernel. */
+struct kernel_stat {
+ unsigned int st_dev;
+ unsigned int st_pad1[3];
+ unsigned long long st_ino;
+ __kernel_mode_t st_mode;
+ __kernel_nlink_t st_nlink;
+ __kernel_uid_t st_uid;
+ __kernel_gid_t st_gid;
+ unsigned int st_rdev;
+ unsigned int st_pad2[3];
+ unsigned long long st_size;
+ unsigned int st_atime;
+ unsigned int st_atime_nsec;
+ unsigned int st_mtime;
+ unsigned int st_mtime_nsec;
+ unsigned int st_ctime;
+ unsigned int st_ctime_nsec;
+ unsigned int st_blksize;
+ unsigned int reserved3;
+ unsigned long long st_blocks;
+};
+#define kernel_stat64 kernel_stat
+#else /* O32 */
struct kernel_stat {
__kernel_dev_t st_dev;
long st_pad1[3];
@@ -21,16 +73,15 @@ struct kernel_stat {
__kernel_off_t st_size;
long st_pad3;
time_t st_atime;
- long reserved0;
+ long st_atime_nsec;
time_t st_mtime;
- long reserved1;
+ long st_mtime_nsec;
time_t st_ctime;
- long reserved2;
+ long st_ctime_nsec;
long st_blksize;
long st_blocks;
long st_pad4[14];
};
-#endif
struct kernel_stat64 {
unsigned long st_dev;
@@ -44,15 +95,18 @@ struct kernel_stat64 {
unsigned long st_pad1[3]; /* Reserved for st_rdev expansion */
long long st_size;
time_t st_atime;
- unsigned long reserved0; /* Reserved for st_atime expansion */
+ unsigned long st_atime_nsec;
time_t st_mtime;
- unsigned long reserved1; /* Reserved for st_mtime expansion */
+ unsigned long st_mtime_nsec;
time_t st_ctime;
- unsigned long reserved2; /* Reserved for st_ctime expansion */
+ unsigned long st_ctime_nsec;
unsigned long st_blksize;
unsigned long st_pad2;
long long st_blocks;
};
+#endif /* O32 */
+
+#define STAT_HAVE_NSEC 1
#endif /* _BITS_STAT_STRUCT_H */
diff --git a/libc/sysdeps/linux/mips/bits/kernel_types.h b/libc/sysdeps/linux/mips/bits/kernel_types.h
index f23b24874..b7e61bd6b 100644
--- a/libc/sysdeps/linux/mips/bits/kernel_types.h
+++ b/libc/sysdeps/linux/mips/bits/kernel_types.h
@@ -9,7 +9,7 @@
# if __WORDSIZE == 64
typedef unsigned int __kernel_dev_t;
-typedef unsigned int __kernel_ino_t;
+typedef unsigned long __kernel_ino_t;
typedef unsigned int __kernel_mode_t;
typedef unsigned int __kernel_nlink_t;
typedef long __kernel_off_t;
diff --git a/libc/sysdeps/linux/mips/bits/mman.h b/libc/sysdeps/linux/mips/bits/mman.h
index b1b00e6f3..47d33933a 100644
--- a/libc/sysdeps/linux/mips/bits/mman.h
+++ b/libc/sysdeps/linux/mips/bits/mman.h
@@ -50,7 +50,7 @@
/* Other flags. */
#define MAP_FIXED 0x10 /* Interpret addr exactly. */
#ifdef __USE_MISC
-# define MAP_FILE 0x00
+# define MAP_FILE 0
# define MAP_ANONYMOUS 0x0800 /* Don't use a file. */
# define MAP_ANON MAP_ANONYMOUS
# define MAP_RENAME MAP_ANONYMOUS
@@ -70,22 +70,30 @@
/* Flags to `msync'. */
#define MS_ASYNC 1 /* Sync memory asynchronously. */
-#define MS_INVALIDATE 2 /* Invalidate the caches. */
#define MS_SYNC 4 /* Synchronous memory sync. */
+#define MS_INVALIDATE 2 /* Invalidate the caches. */
/* Flags for `mlockall'. */
#define MCL_CURRENT 1 /* Lock all currently mapped pages. */
#define MCL_FUTURE 2 /* Lock all additions to address
space. */
+/* Flags for `mremap'. */
+#ifdef __USE_GNU
+# define MREMAP_MAYMOVE 1
+# define MREMAP_FIXED 2
+#endif
+
/* Advice to `madvise'. */
#ifdef __USE_BSD
-#define MADV_NORMAL 0 /* default page-in behavior */
-#define MADV_RANDOM 1 /* page-in minimum required */
-#define MADV_SEQUENTIAL 2 /* read-ahead aggressively */
-#define MADV_WILLNEED 3 /* pre-fault pages */
-#define MADV_DONTNEED 4 /* discard these pages */
-#define MADV_REMOVE 5 /* remove these pages & resources */
+# define MADV_NORMAL 0 /* No further special treatment. */
+# define MADV_RANDOM 1 /* Expect random page references. */
+# define MADV_SEQUENTIAL 2 /* Expect sequential page references. */
+# define MADV_WILLNEED 3 /* Will need these pages. */
+# define MADV_DONTNEED 4 /* Don't need these pages. */
+# define MADV_REMOVE 9 /* Remove these pages and resources. */
+# define MADV_DONTFORK 10 /* Do not inherit across fork. */
+# define MADV_DOFORK 11 /* Do inherit across fork. */
#endif
/* The POSIX people had to invent similar names for the same things. */
@@ -96,9 +104,3 @@
# define POSIX_MADV_WILLNEED 3 /* Will need these pages. */
# define POSIX_MADV_DONTNEED 4 /* Don't need these pages. */
#endif
-
-/* Flags for `mremap'. */
-#ifdef __USE_GNU
-# define MREMAP_MAYMOVE 1
-# define MREMAP_FIXED 2
-#endif
diff --git a/libc/sysdeps/linux/mips/bits/resource.h b/libc/sysdeps/linux/mips/bits/resource.h
index 9e99f5d5d..1c8b99a93 100644
--- a/libc/sysdeps/linux/mips/bits/resource.h
+++ b/libc/sysdeps/linux/mips/bits/resource.h
@@ -107,14 +107,22 @@ enum __rlimit_resource
};
/* Value to indicate that there is no limit. */
-#ifndef __USE_FILE_OFFSET64
-# define RLIM_INFINITY ((long int)(~0UL >> 1))
+#if _MIPS_SIM == _ABI64
+/* The N64 syscall uses this value. */
+# define RLIM_INFINITY 0xffffffffffffffffUL
+# ifdef __USE_LARGEFILE64
+# define RLIM64_INFINITY 0xffffffffffffffffUL
+# endif
#else
-# define RLIM_INFINITY 0x7fffffffffffffffLL
-#endif
-
-#ifdef __USE_LARGEFILE64
-# define RLIM64_INFINITY 0x7fffffffffffffffLL
+/* The O32 and N32 syscalls use 0x7fffffff. */
+# ifndef __USE_FILE_OFFSET64
+# define RLIM_INFINITY ((long int)(~0UL >> 1))
+# else
+# define RLIM_INFINITY 0x7fffffffffffffffULL
+# endif
+# ifdef __USE_LARGEFILE64
+# define RLIM64_INFINITY 0x7fffffffffffffffULL
+# endif
#endif
/* We can represent all limits. */
diff --git a/libc/sysdeps/linux/mips/bits/setjmp.h b/libc/sysdeps/linux/mips/bits/setjmp.h
index 4eb8e9f2a..08e74fe0a 100644
--- a/libc/sysdeps/linux/mips/bits/setjmp.h
+++ b/libc/sysdeps/linux/mips/bits/setjmp.h
@@ -24,6 +24,8 @@
# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
#endif
+#include <sgidefs.h>
+
typedef struct
{
/* Program counter. */
@@ -33,7 +35,11 @@ typedef struct
void * __sp;
/* Callee-saved registers s0 through s7. */
+#if _MIPS_SIM == _MIPS_SIM_ABI32
int __regs[8];
+#else
+ long long __regs[8];
+#endif
/* The frame pointer. */
void * __fp;
@@ -45,7 +51,11 @@ typedef struct
int __fpc_csr;
/* Callee-saved floating point registers. */
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+ double __fpregs[8];
+#else /* N32 || O32 */
double __fpregs[6];
+#endif /* N32 || O32 */
} __jmp_buf[1];
#ifdef __USE_MISC
diff --git a/libc/sysdeps/linux/mips/bits/sigcontext.h b/libc/sysdeps/linux/mips/bits/sigcontext.h
new file mode 100644
index 000000000..99faeed39
--- /dev/null
+++ b/libc/sysdeps/linux/mips/bits/sigcontext.h
@@ -0,0 +1,84 @@
+/* Copyright (C) 1996, 1997, 1998, 2003, 2004, 2006 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. */
+
+#ifndef _BITS_SIGCONTEXT_H
+#define _BITS_SIGCONTEXT_H 1
+
+#if !defined _SIGNAL_H && !defined _SYS_UCONTEXT_H
+# error "Never use <bits/sigcontext.h> directly; include <signal.h> instead."
+#endif
+
+#include <sgidefs.h>
+
+#if _MIPS_SIM == _ABIO32
+
+/* Certain unused fields were replaced with new ones in 2.6.12-rc4.
+ The changes were as follows:
+
+ sc_cause -> sc_hi1
+ sc_badvaddr -> sc_lo1
+ sc_sigset[0] -> sc_hi2
+ sc_sigset[1] -> sc_lo2
+ sc_sigset[2] -> sc_hi3
+ sc_sigset[3] -> sc_lo3
+
+ sc_regmask, sc_ownedfp and sc_fpc_eir are not used. */
+struct sigcontext {
+ unsigned int sc_regmask;
+ unsigned int sc_status;
+ unsigned long long sc_pc;
+ unsigned long long sc_regs[32];
+ unsigned long long sc_fpregs[32];
+ unsigned int sc_ownedfp;
+ unsigned int sc_fpc_csr;
+ unsigned int sc_fpc_eir;
+ unsigned int sc_used_math;
+ unsigned int sc_dsp;
+ unsigned long long sc_mdhi;
+ unsigned long long sc_mdlo;
+ unsigned long sc_hi1;
+ unsigned long sc_lo1;
+ unsigned long sc_hi2;
+ unsigned long sc_lo2;
+ unsigned long sc_hi3;
+ unsigned long sc_lo3;
+};
+
+#else
+
+/* This structure changed in 2.6.12-rc4 when DSP support was added. */
+struct sigcontext {
+ unsigned long long sc_regs[32];
+ unsigned long long sc_fpregs[32];
+ unsigned long long sc_mdhi;
+ unsigned long long sc_hi1;
+ unsigned long long sc_hi2;
+ unsigned long long sc_hi3;
+ unsigned long long sc_mdlo;
+ unsigned long long sc_lo1;
+ unsigned long long sc_lo2;
+ unsigned long long sc_lo3;
+ unsigned long long sc_pc;
+ unsigned int sc_fpc_csr;
+ unsigned int sc_used_math;
+ unsigned int sc_dsp;
+ unsigned int sc_reserved;
+};
+
+#endif /* _MIPS_SIM != _ABIO32 */
+#endif
diff --git a/libc/sysdeps/linux/mips/bits/sigcontextinfo.h b/libc/sysdeps/linux/mips/bits/sigcontextinfo.h
index a51c6f043..f453c8d9b 100644
--- a/libc/sysdeps/linux/mips/bits/sigcontextinfo.h
+++ b/libc/sysdeps/linux/mips/bits/sigcontextinfo.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de>, 2000.
@@ -18,6 +18,10 @@
02111-1307 USA. */
+#include <sgidefs.h>
+
+#if _MIPS_SIM == _ABIO32
+
#define SIGCONTEXT unsigned long _code, struct sigcontext *
#define SIGCONTEXT_EXTRA_ARGS _code,
#define GET_PC(ctx) ((void *) ctx->sc_pc)
@@ -25,3 +29,15 @@
#define GET_STACK(ctx) ((void *) ctx->sc_regs[29])
#define CALL_SIGHANDLER(handler, signo, ctx) \
(handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
+
+#else
+
+#define SIGCONTEXT unsigned long _code, ucontext_t *
+#define SIGCONTEXT_EXTRA_ARGS _code,
+#define GET_PC(ctx) ((void *) ctx->uc_mcontext.pc)
+#define GET_FRAME(ctx) ((void *) ctx->uc_mcontext.gregs[30])
+#define GET_STACK(ctx) ((void *) ctx->uc_mcontext.gregs[29])
+#define CALL_SIGHANDLER(handler, signo, ctx) \
+ (handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
+
+#endif
diff --git a/libc/sysdeps/linux/mips/bits/siginfo.h b/libc/sysdeps/linux/mips/bits/siginfo.h
index 248893e86..ba3e1f630 100644
--- a/libc/sysdeps/linux/mips/bits/siginfo.h
+++ b/libc/sysdeps/linux/mips/bits/siginfo.h
@@ -1,5 +1,6 @@
/* siginfo_t, sigevent and constants. Linux/MIPS version.
- Copyright (C) 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005
+ 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
@@ -22,6 +23,8 @@
# error "Never include this file directly. Use <signal.h> instead"
#endif
+#include <bits/wordsize.h>
+
#if (!defined __have_sigval_t \
&& (defined _SIGNAL_H || defined __need_siginfo_t \
|| defined __need_sigevent_t))
@@ -39,8 +42,13 @@ typedef union sigval
&& (defined _SIGNAL_H || defined __need_siginfo_t))
# define __have_siginfo_t 1
-# define __SI_MAX_SIZE 128
-# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3)
+# define __SI_MAX_SIZE 128
+# if __WORDSIZE == 64
+# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 4)
+# else
+# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3)
+# endif
+
typedef struct siginfo
{
@@ -48,6 +56,8 @@ typedef struct siginfo
int si_code; /* Signal code. */
int si_errno; /* If non-zero, an errno value associated with
this signal, as defined in <errno.h>. */
+ int __pad0[__SI_MAX_SIZE / sizeof (int) - __SI_PAD_SIZE - 3];
+ /* Explicit padding. */
union
{
@@ -149,7 +159,7 @@ enum
# define ILL_ILLOPN ILL_ILLOPN
ILL_ILLADR, /* Illegal addressing mode. */
# define ILL_ILLADR ILL_ILLADR
- ILL_ILLTRP, /* Illegal trap. */
+ ILL_ILLTRP, /* Illegal trap. */
# define ILL_ILLTRP ILL_ILLTRP
ILL_PRVOPC, /* Privileged opcode. */
# define ILL_PRVOPC ILL_PRVOPC
@@ -255,7 +265,8 @@ enum
/* Structure to transport application-defined values with signals. */
# define __SIGEV_MAX_SIZE 64
-# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE / sizeof (int)) - 3)
+# define __SIGEV_HEAD_SIZE (sizeof(long) + 2*sizeof(int))
+# define __SIGEV_PAD_SIZE ((__SIGEV_MAX_SIZE - __SIGEV_HEAD_SIZE) / sizeof (int))
/* Forward declaration of the `pthread_attr_t' type. */
struct __pthread_attr_s;
@@ -273,8 +284,8 @@ typedef struct sigevent
struct
{
- void (*_function) (sigval_t); /* Function to start. */
- struct __pthread_attr_s *_attribute; /* Really pthread_attr_t. */
+ void (*_function) (sigval_t); /* Function to start. */
+ void *_attribute; /* Really pthread_attr_t. */
} _sigev_thread;
} _sigev_un;
} sigevent_t;
@@ -294,7 +305,7 @@ enum
# define SIGEV_THREAD SIGEV_THREAD
SIGEV_THREAD_ID = 4 /* Send signal to specific thread. */
-#define SIGEV_THREAD_ID SIGEV_THREAD_ID
+#define SIGEV_THREAD_ID SIGEV_THREAD_ID
};
#endif /* have _SIGNAL_H. */
diff --git a/libc/sysdeps/linux/mips/bits/socket.h b/libc/sysdeps/linux/mips/bits/socket.h
index a10c3a711..c43a4cd2e 100644
--- a/libc/sysdeps/linux/mips/bits/socket.h
+++ b/libc/sysdeps/linux/mips/bits/socket.h
@@ -1,5 +1,6 @@
/* System-specific socket constants and types. Linux/MIPS version.
- Copyright (C) 1991,92,1994-1999,2000,2001 Free Software Foundation, Inc.
+ Copyright (C) 1991, 92, 1994-1999, 2000, 2001, 2004, 2005, 2006
+ 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
@@ -212,16 +213,29 @@ enum
/* Structure describing messages sent by
`sendmsg' and received by `recvmsg'. */
+/* Note: do not change these members to match glibc; these match the
+ SuSv3 spec already (e.g. msg_iovlen/msg_controllen).
+ http://www.opengroup.org/onlinepubs/009695399/basedefs/sys/socket.h.html */
+/* Note: linux kernel uses __kernel_size_t (which is 8bytes on 64bit
+ platforms, and 4bytes on 32bit platforms) for msg_iovlen/msg_controllen */
struct msghdr
{
void *msg_name; /* Address to send to/receive from. */
socklen_t msg_namelen; /* Length of address data. */
struct iovec *msg_iov; /* Vector of data to send/receive into. */
+#if __WORDSIZE == 32
int msg_iovlen; /* Number of elements in the vector. */
+#else
+ size_t msg_iovlen; /* Number of elements in the vector. */
+#endif
void *msg_control; /* Ancillary data (eg BSD filedesc passing). */
+#if __WORDSIZE == 32
socklen_t msg_controllen; /* Ancillary data buffer length. */
+#else
+ size_t msg_controllen; /* Ancillary data buffer length. */
+#endif
int msg_flags; /* Flags on received message. */
};
@@ -254,14 +268,14 @@ struct cmsghdr
+ CMSG_ALIGN (sizeof (struct cmsghdr)))
#define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))
-extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
- struct cmsghdr *__cmsg) __THROW;
+extern struct cmsghdr * __NTH (__cmsg_nxthdr (struct msghdr *__mhdr,
+ struct cmsghdr *__cmsg)) __THROW;
#ifdef __USE_EXTERN_INLINES
# ifndef _EXTERN_INLINE
# define _EXTERN_INLINE extern __inline
# endif
_EXTERN_INLINE struct cmsghdr *
-__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg) __THROW
+__NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg))
{
if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr))
/* The kernel header does this so there may be a reason. */
@@ -269,8 +283,8 @@ __cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg) __THROW
__cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg
+ CMSG_ALIGN (__cmsg->cmsg_len));
- if ((unsigned char *) (__cmsg + 1) >= ((unsigned char *) __mhdr->msg_control
- + __mhdr->msg_controllen)
+ if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control
+ + __mhdr->msg_controllen)
|| ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len)
> ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen)))
/* No more entries. */
@@ -283,13 +297,12 @@ __cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg) __THROW
<linux/socket.h>. */
enum
{
- SCM_RIGHTS = 0x01, /* Transfer file descriptors. */
+ SCM_RIGHTS = 0x01 /* Transfer file descriptors. */
#define SCM_RIGHTS SCM_RIGHTS
#ifdef __USE_BSD
- SCM_CREDENTIALS = 0x02, /* Credentials passing. */
+ , SCM_CREDENTIALS = 0x02 /* Credentials passing. */
# define SCM_CREDENTIALS SCM_CREDENTIALS
#endif
- __SCM_CONNECT = 0x03 /* Data array is `struct scm_connect'. */
};
/* User visible structure for SCM_CREDENTIALS message */
diff --git a/libc/sysdeps/linux/mips/bits/stat.h b/libc/sysdeps/linux/mips/bits/stat.h
index bb4076f05..e35d64928 100644
--- a/libc/sysdeps/linux/mips/bits/stat.h
+++ b/libc/sysdeps/linux/mips/bits/stat.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1992,95,96,97,98,99,2000,2001 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004
+ 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
@@ -20,6 +21,8 @@
# error "Never include <bits/stat.h> directly; use <sys/stat.h> instead."
#endif
+#include <sgidefs.h>
+
/* Versions of the `struct stat' data structure. */
#define _STAT_VER_LINUX_OLD 1
#define _STAT_VER_KERNEL 1
@@ -33,6 +36,7 @@
#define _MKNOD_VER _MKNOD_VER_LINUX /* The bits defined below. */
+#if _MIPS_SIM == _ABIO32
/* Structure describing file characteristics. */
struct stat
{
@@ -62,11 +66,11 @@ struct stat
* st_ctime but we don't have it under Linux.
*/
__time_t st_atime; /* Time of last access. */
- long int __reserved0;
+ unsigned long int st_atimensec; /* Nscecs of last access. */
__time_t st_mtime; /* Time of last modification. */
- long int __reserved1;
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
__time_t st_ctime; /* Time of last status change. */
- long int __reserved2;
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
__blksize_t st_blksize; /* Optimal block size for I/O. */
#ifndef __USE_FILE_OFFSET64
__blkcnt_t st_blocks; /* Number of 512-byte blocks allocated. */
@@ -76,8 +80,38 @@ struct stat
#endif
long int st_pad5[14];
};
+#else /* N32 || N64 */
+/* The memory layout is the same as of struct stat64 of the 32-bit kernel. */
+struct stat {
+ unsigned int st_dev;
+ int st_pad1[3];
+ __ino_t st_ino; /* 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.*/
+ unsigned int st_rdev; /* Device number, if device. */
+ int st_pad2[3];
+ __off_t st_size; /* Size of file, in bytes. */
+ /*
+ * Actually this should be timestruc_t st_atime, st_mtime and
+ * st_ctime but we don't have it under Linux.
+ */
+ int st_atime;
+ int st_atimensec;
+ int st_mtime;
+ int st_mtimensec;
+ int st_ctime;
+ int st_ctimensec;
+ int st_blksize; /* Optimal block size for I/O. */
+ int st_pad3;
+ __blkcnt_t st_blocks; /* Number of 512-byte blocks allocated. */
+ int st_pad4[14];
+};
+#endif /* N32 || N64 */
#ifdef __USE_LARGEFILE64
+#if _MIPS_SIM == _ABIO32
struct stat64
{
__dev_t st_dev;
@@ -95,16 +129,45 @@ struct stat64
* st_ctime but we don't have it under Linux.
*/
__time_t st_atime; /* Time of last access. */
- long int __reserved0;
+ unsigned long int st_atimensec; /* Nscecs of last access. */
__time_t st_mtime; /* Time of last modification. */
- long int __reserved1;
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
__time_t st_ctime; /* Time of last status change. */
- long int __reserved2;
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
__blksize_t st_blksize; /* Optimal block size for I/O. */
long int st_pad3;
__blkcnt64_t st_blocks; /* Number of 512-byte blocks allocated. */
long int st_pad4[14];
};
+#else /* N32 || N64 */
+/* stat64 of N32/N64 is just an alias of stat syscall. */
+struct stat64 {
+ unsigned int st_dev;
+ int st_pad1[3];
+ __ino_t st_ino; /* 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.*/
+ unsigned int st_rdev; /* Device number, if device. */
+ int st_pad2[3];
+ __off_t st_size; /* Size of file, in bytes. */
+ /*
+ * Actually this should be timestruc_t st_atime, st_mtime and
+ * st_ctime but we don't have it under Linux.
+ */
+ int st_atime;
+ int st_atimensec;
+ int st_mtime;
+ int st_mtimensec;
+ int st_ctime;
+ int st_ctimensec;
+ int st_blksize; /* Optimal block size for I/O. */
+ int st_pad3;
+ __blkcnt_t st_blocks; /* Number of 512-byte blocks allocated. */
+ int st_pad4[14];
+};
+#endif /* N32 || N64 */
#endif
/* Tell code we have these members. */
diff --git a/libc/sysdeps/linux/mips/bits/syscalls.h b/libc/sysdeps/linux/mips/bits/syscalls.h
index 7133d83e3..324d75d9f 100644
--- a/libc/sysdeps/linux/mips/bits/syscalls.h
+++ b/libc/sysdeps/linux/mips/bits/syscalls.h
@@ -4,267 +4,390 @@
# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
#endif
-/* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel
- * header files. It also defines the traditional `SYS_<name>' macros for older
- * programs. */
-#include <bits/sysnum.h>
-
-#ifndef __set_errno
-# define __set_errno(val) (*__errno_location ()) = (val)
-#endif
-#ifndef SYS_ify
-# define SYS_ify(syscall_name) (__NR_##syscall_name)
-#endif
+#include <sgidefs.h>
#ifndef __ASSEMBLER__
-#define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
- "$14", "$15", "$24", "$25", "memory"
+#include <errno.h>
+
+#define SYS_ify(syscall_name) (__NR_##syscall_name)
+#undef _syscall0
#define _syscall0(type,name) \
type name(void) \
-{ \
- long err; \
- long sys_result; \
+{ \
+return (type) (INLINE_SYSCALL(name, 0)); \
+}
+
+#undef _syscall1
+#define _syscall1(type,name,type1,arg1) \
+type name(type1 arg1) \
+{ \
+return (type) (INLINE_SYSCALL(name, 1, arg1)); \
+}
+
+#undef _syscall2
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+type name(type1 arg1,type2 arg2) \
+{ \
+return (type) (INLINE_SYSCALL(name, 2, arg1, arg2)); \
+}
+
+#undef _syscall3
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type name(type1 arg1,type2 arg2,type3 arg3) \
+{ \
+return (type) (INLINE_SYSCALL(name, 3, arg1, arg2, arg3)); \
+}
+
+#undef _syscall4
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+{ \
+return (type) (INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4)); \
+}
+
+#undef _syscall5
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+{ \
+return (type) (INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5)); \
+}
+
+#undef _syscall6
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5,type6,arg6) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6) \
+{ \
+return (type) (INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6)); \
+}
+
+#undef _syscall7
+#define _syscall7(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5,type6,arg6,type7,arg7) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6,type7 arg7) \
+{ \
+return (type) (INLINE_SYSCALL(name, 7, arg1, arg2, arg3, arg4, arg5, arg6, arg7)); \
+}
+
+/*
+ * Import from:
+ * glibc-ports/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h
+ * glibc-ports/sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
+ * glibc-ports/sysdeps/unix/sysv/linux/mips/mips64/n64/sysdep.h
+ */
+
+/* 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_var = INTERNAL_SYSCALL (name, err, nr, args); \
+ if ( INTERNAL_SYSCALL_ERROR_P (result_var, err) ) \
+ { \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, err)); \
+ result_var = -1L; \
+ } \
+ result_var; })
+
+#undef INTERNAL_SYSCALL_DECL
+#define INTERNAL_SYSCALL_DECL(err) long err
+
+#undef INTERNAL_SYSCALL_ERROR_P
+#define INTERNAL_SYSCALL_ERROR_P(val, err) ((long) (err))
+
+#undef INTERNAL_SYSCALL_ERRNO
+#define INTERNAL_SYSCALL_ERRNO(val, err) (val)
+
+#undef INTERNAL_SYSCALL
+#define INTERNAL_SYSCALL(name, err, nr, args...) \
+ internal_syscall##nr (, "li\t$2, %2\t\t\t# " #name "\n\t", \
+ "i" (SYS_ify (name)), err, args)
+
+#undef INTERNAL_SYSCALL_NCS
+#define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
+ internal_syscall##nr (= number, , "r" (__v0), err, args)
+
+#if _MIPS_SIM == _ABIO32 || _MIPS_SIM == _ABI64
+# define ARG_TYPE long
+#else
+# define ARG_TYPE long long
+#endif
+
+#define internal_syscall0(ncs_init, cs_init, input, err, dummy...) \
+({ \
+ long _sys_result; \
+ \
{ \
- register unsigned long __v0 asm("$2"); \
- register unsigned long __a3 asm("$7"); \
- __asm__ volatile ( \
- ".set noreorder\n\t" \
- "li $2, %2 # " #name "\n\t" \
- "syscall\n\t" \
- ".set reorder" \
- : "=r" (__v0), "=r" (__a3) \
- : "i" (SYS_ify(name)) \
- : __SYSCALL_CLOBBERS); \
+ register ARG_TYPE __v0 __asm__("$2") ncs_init; \
+ register ARG_TYPE __a3 __asm__("$7"); \
+ __asm__ __volatile__ ( \
+ ".set\tnoreorder\n\t" \
+ cs_init \
+ "syscall\n\t" \
+ ".set reorder" \
+ : "=r" (__v0), "=r" (__a3) \
+ : input \
+ : __SYSCALL_CLOBBERS); \
err = __a3; \
- sys_result = __v0; \
+ _sys_result = __v0; \
} \
- if (err == 0) \
- return (type) sys_result; \
- __set_errno(sys_result); \
- return (type)-1; \
-}
+ _sys_result; \
+})
-#define _syscall1(type,name,atype,a) \
-type name(atype a) \
-{ \
- long err; \
- long sys_result; \
+#define internal_syscall1(ncs_init, cs_init, input, err, arg1) \
+({ \
+ long _sys_result; \
+ \
{ \
- register unsigned long __v0 asm("$2"); \
- register unsigned long __a0 asm("$4") = (unsigned long) a; \
- register unsigned long __a3 asm("$7"); \
- __asm__ volatile ( \
- ".set noreorder\n\t" \
- "li $2, %3\t\t\t# " #name "\n\t" \
- "syscall\n\t" \
- ".set reorder" \
- : "=r" (__v0), "=r" (__a3) \
- : "r" (__a0), "i" (SYS_ify(name)) \
- : __SYSCALL_CLOBBERS); \
+ register ARG_TYPE __v0 __asm__("$2") ncs_init; \
+ register ARG_TYPE __a0 __asm__("$4") = (ARG_TYPE) arg1; \
+ register ARG_TYPE __a3 __asm__("$7"); \
+ __asm__ __volatile__ ( \
+ ".set\tnoreorder\n\t" \
+ cs_init \
+ "syscall\n\t" \
+ ".set reorder" \
+ : "=r" (__v0), "=r" (__a3) \
+ : input, "r" (__a0) \
+ : __SYSCALL_CLOBBERS); \
err = __a3; \
- sys_result = __v0; \
+ _sys_result = __v0; \
} \
- if (err == 0) \
- return (type) sys_result; \
- __set_errno(sys_result); \
- return (type)-1; \
-}
+ _sys_result; \
+})
-#define _syscall2(type,name,atype,a,btype,b) \
-type name(atype a,btype b) \
-{ \
- long err; \
- long sys_result; \
+#define internal_syscall2(ncs_init, cs_init, input, err, arg1, arg2) \
+({ \
+ long _sys_result; \
+ \
{ \
- register unsigned long __v0 asm("$2"); \
- register unsigned long __a0 asm("$4") = (unsigned long) a; \
- register unsigned long __a1 asm("$5") = (unsigned long) b; \
- register unsigned long __a3 asm("$7"); \
- __asm__ volatile ( \
- ".set noreorder\n\t" \
- "li $2, %4\t\t\t# " #name "\n\t" \
- "syscall\n\t" \
- ".set reorder" \
- : "=r" (__v0), "=r" (__a3) \
- : "r" (__a0), "r" (__a1), "i" (SYS_ify(name)) \
- : __SYSCALL_CLOBBERS); \
+ register ARG_TYPE __v0 __asm__("$2") ncs_init; \
+ register ARG_TYPE __a0 __asm__("$4") = (ARG_TYPE) arg1; \
+ register ARG_TYPE __a1 __asm__("$5") = (ARG_TYPE) arg2; \
+ register ARG_TYPE __a3 __asm__("$7"); \
+ __asm__ __volatile__ ( \
+ ".set\tnoreorder\n\t" \
+ cs_init \
+ "syscall\n\t" \
+ ".set\treorder" \
+ : "=r" (__v0), "=r" (__a3) \
+ : input, "r" (__a0), "r" (__a1) \
+ : __SYSCALL_CLOBBERS); \
err = __a3; \
- sys_result = __v0; \
+ _sys_result = __v0; \
} \
- if (err == 0) \
- return (type) sys_result; \
- __set_errno(sys_result); \
- return (type)-1; \
-}
+ _sys_result; \
+})
-#define _syscall3(type,name,atype,a,btype,b,ctype,c) \
-type name (atype a, btype b, ctype c) \
-{ \
- long err; \
- long sys_result; \
+#define internal_syscall3(ncs_init, cs_init, input, err, arg1, arg2, arg3)\
+({ \
+ long _sys_result; \
+ \
{ \
- register unsigned long __v0 asm("$2"); \
- register unsigned long __a0 asm("$4") = (unsigned long) a; \
- register unsigned long __a1 asm("$5") = (unsigned long) b; \
- register unsigned long __a2 asm("$6") = (unsigned long) c; \
- register unsigned long __a3 asm("$7"); \
- __asm__ volatile ( \
- ".set noreorder\n\t" \
- "li $2, %5\t\t\t# " #name "\n\t" \
- "syscall\n\t" \
- ".set reorder" \
- : "=r" (__v0), "=r" (__a3) \
- : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)) \
- : __SYSCALL_CLOBBERS); \
+ register ARG_TYPE __v0 __asm__("$2") ncs_init; \
+ register ARG_TYPE __a0 __asm__("$4") = (ARG_TYPE) arg1; \
+ register ARG_TYPE __a1 __asm__("$5") = (ARG_TYPE) arg2; \
+ register ARG_TYPE __a2 __asm__("$6") = (ARG_TYPE) arg3; \
+ register ARG_TYPE __a3 __asm__("$7"); \
+ __asm__ __volatile__ ( \
+ ".set\tnoreorder\n\t" \
+ cs_init \
+ "syscall\n\t" \
+ ".set\treorder" \
+ : "=r" (__v0), "=r" (__a3) \
+ : input, "r" (__a0), "r" (__a1), "r" (__a2) \
+ : __SYSCALL_CLOBBERS); \
err = __a3; \
- sys_result = __v0; \
+ _sys_result = __v0; \
} \
- if (err == 0) \
- return (type) sys_result; \
- __set_errno(sys_result); \
- return (type)-1; \
-}
+ _sys_result; \
+})
-#define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \
-type name (atype a, btype b, ctype c, dtype d) \
-{ \
- long err; \
- long sys_result; \
+#define internal_syscall4(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4)\
+({ \
+ long _sys_result; \
+ \
{ \
- register unsigned long __v0 asm("$2"); \
- register unsigned long __a0 asm("$4") = (unsigned long) a; \
- register unsigned long __a1 asm("$5") = (unsigned long) b; \
- register unsigned long __a2 asm("$6") = (unsigned long) c; \
- register unsigned long __a3 asm("$7") = (unsigned long) d; \
- __asm__ volatile ( \
- ".set noreorder\n\t" \
- "li $2, %5\t\t\t# " #name "\n\t" \
- "syscall\n\t" \
- ".set reorder" \
- : "=r" (__v0), "+r" (__a3) \
- : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)) \
- : __SYSCALL_CLOBBERS); \
+ register ARG_TYPE __v0 __asm__("$2") ncs_init; \
+ register ARG_TYPE __a0 __asm__("$4") = (ARG_TYPE) arg1; \
+ register ARG_TYPE __a1 __asm__("$5") = (ARG_TYPE) arg2; \
+ register ARG_TYPE __a2 __asm__("$6") = (ARG_TYPE) arg3; \
+ register ARG_TYPE __a3 __asm__("$7") = (ARG_TYPE) arg4; \
+ __asm__ __volatile__ ( \
+ ".set\tnoreorder\n\t" \
+ cs_init \
+ "syscall\n\t" \
+ ".set\treorder" \
+ : "=r" (__v0), "+r" (__a3) \
+ : input, "r" (__a0), "r" (__a1), "r" (__a2) \
+ : __SYSCALL_CLOBBERS); \
err = __a3; \
- sys_result = __v0; \
+ _sys_result = __v0; \
} \
- if (err == 0) \
- return (type) sys_result; \
- __set_errno(sys_result); \
- return (type)-1; \
-}
+ _sys_result; \
+})
+
+#if _MIPS_SIM == _ABIO32
+#include <alloca.h>
+/* We need to use a frame pointer for the functions in which we
+ adjust $sp around the syscall, or debug information and unwind
+ information will be $sp relative and thus wrong during the syscall. As
+ of GCC 3.4.3, this is sufficient. */
+#define FORCE_FRAME_POINTER alloca (4)
-#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \
-type name (atype a,btype b,ctype c,dtype d,etype e) \
-{ \
- long err; \
- long sys_result; \
- const unsigned long *constE = (void*)(unsigned long) e; \
+#define internal_syscall5(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5)\
+({ \
+ long _sys_result; \
+ \
+ FORCE_FRAME_POINTER; \
{ \
- register unsigned long __v0 asm("$2"); \
- register unsigned long __a0 asm("$4") = (unsigned long) a; \
- register unsigned long __a1 asm("$5") = (unsigned long) b; \
- register unsigned long __a2 asm("$6") = (unsigned long) c; \
- register unsigned long __a3 asm("$7") = (unsigned long) d; \
- __asm__ volatile ( \
- ".set noreorder\n\t" \
- "lw $2, %6\n\t" \
- "subu $29, 32\n\t" \
- "sw $2, 16($29)\n\t" \
- "li $2, %5\t\t\t# " #name "\n\t" \
- "syscall\n\t" \
- "addiu $29, 32\n\t" \
- ".set reorder" \
- : "=r" (__v0), "+r" (__a3) \
- : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)), \
- "m" (constE) \
- : __SYSCALL_CLOBBERS); \
+ register long __v0 __asm__("$2") ncs_init; \
+ register long __a0 __asm__("$4") = (long) arg1; \
+ register long __a1 __asm__("$5") = (long) arg2; \
+ register long __a2 __asm__("$6") = (long) arg3; \
+ register long __a3 __asm__("$7") = (long) arg4; \
+ __asm__ __volatile__ ( \
+ ".set\tnoreorder\n\t" \
+ "subu\t$29, 32\n\t" \
+ "sw\t%6, 16($29)\n\t" \
+ cs_init \
+ "syscall\n\t" \
+ "addiu\t$29, 32\n\t" \
+ ".set\treorder" \
+ : "=r" (__v0), "+r" (__a3) \
+ : input, "r" (__a0), "r" (__a1), "r" (__a2), \
+ "r" ((long)arg5) \
+ : __SYSCALL_CLOBBERS); \
err = __a3; \
- sys_result = __v0; \
+ _sys_result = __v0; \
} \
- if (err == 0) \
- return (type) sys_result; \
- __set_errno(sys_result); \
- return (type)-1; \
-}
+ _sys_result; \
+})
-#define _syscall6(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f) \
-type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \
-{ \
- long err; \
- long sys_result; \
- const unsigned long *constE = (void*)(unsigned long) e; \
- const unsigned long *constF = (void*)(unsigned long) f; \
+#define internal_syscall6(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5, arg6)\
+({ \
+ long _sys_result; \
+ \
+ FORCE_FRAME_POINTER; \
{ \
- register unsigned long __v0 asm("$2"); \
- register unsigned long __a0 asm("$4") = (unsigned long) a; \
- register unsigned long __a1 asm("$5") = (unsigned long) b; \
- register unsigned long __a2 asm("$6") = (unsigned long) c; \
- register unsigned long __a3 asm("$7") = (unsigned long) d; \
- __asm__ volatile ( \
- ".set noreorder\n\t" \
- "lw $2, %6\n\t" \
- "lw $8, %7\n\t" \
- "subu $29, 32\n\t" \
- "sw $2, 16($29)\n\t" \
- "sw $8, 20($29)\n\t" \
- "li $2, %5\t\t\t# " #name "\n\t" \
+ register long __v0 __asm__("$2") ncs_init; \
+ register long __a0 __asm__("$4") = (long) arg1; \
+ register long __a1 __asm__("$5") = (long) arg2; \
+ register long __a2 __asm__("$6") = (long) arg3; \
+ register long __a3 __asm__("$7") = (long) arg4; \
+ __asm__ __volatile__ ( \
+ ".set\tnoreorder\n\t" \
+ "subu\t$29, 32\n\t" \
+ "sw\t%6, 16($29)\n\t" \
+ "sw\t%7, 20($29)\n\t" \
+ cs_init \
+ "syscall\n\t" \
+ "addiu\t$29, 32\n\t" \
+ ".set\treorder" \
+ : "=r" (__v0), "+r" (__a3) \
+ : input, "r" (__a0), "r" (__a1), "r" (__a2), \
+ "r" ((long)arg5), "r" ((long)arg6) \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _sys_result; \
+})
+
+#define internal_syscall7(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5, arg6, arg7)\
+({ \
+ long _sys_result; \
+ \
+ FORCE_FRAME_POINTER; \
+ { \
+ register long __v0 __asm__("$2") ncs_init; \
+ register long __a0 __asm__("$4") = (long) arg1; \
+ register long __a1 __asm__("$5") = (long) arg2; \
+ register long __a2 __asm__("$6") = (long) arg3; \
+ register long __a3 __asm__("$7") = (long) arg4; \
+ __asm__ __volatile__ ( \
+ ".set\tnoreorder\n\t" \
+ "subu\t$29, 32\n\t" \
+ "sw\t%6, 16($29)\n\t" \
+ "sw\t%7, 20($29)\n\t" \
+ "sw\t%8, 24($29)\n\t" \
+ cs_init \
+ "syscall\n\t" \
+ "addiu\t$29, 32\n\t" \
+ ".set\treorder" \
+ : "=r" (__v0), "+r" (__a3) \
+ : input, "r" (__a0), "r" (__a1), "r" (__a2), \
+ "r" ((long)arg5), "r" ((long)arg6), "r" ((long)arg7) \
+ : __SYSCALL_CLOBBERS); \
+ err = __a3; \
+ _sys_result = __v0; \
+ } \
+ _sys_result; \
+})
+
+#define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
+ "$14", "$15", "$24", "$25", "memory"
+
+#else /* N32 || N64 */
+
+#define internal_syscall5(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5) \
+({ \
+ long _sys_result; \
+ \
+ { \
+ register ARG_TYPE __v0 __asm__("$2") ncs_init; \
+ register ARG_TYPE __a0 __asm__("$4") = (ARG_TYPE) arg1; \
+ register ARG_TYPE __a1 __asm__("$5") = (ARG_TYPE) arg2; \
+ register ARG_TYPE __a2 __asm__("$6") = (ARG_TYPE) arg3; \
+ register ARG_TYPE __a3 __asm__("$7") = (ARG_TYPE) arg4; \
+ register ARG_TYPE __a4 __asm__("$8") = (ARG_TYPE) arg5; \
+ __asm__ __volatile__ ( \
+ ".set\tnoreorder\n\t" \
+ cs_init \
"syscall\n\t" \
- "addiu $29, 32\n\t" \
- ".set reorder" \
+ ".set\treorder" \
: "=r" (__v0), "+r" (__a3) \
- : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)), \
- "m" (constE), "m" (constF) \
- : __SYSCALL_CLOBBERS); \
+ : input, "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4) \
+ : __SYSCALL_CLOBBERS); \
err = __a3; \
- sys_result = __v0; \
+ _sys_result = __v0; \
} \
- if (err == 0) \
- return (type) sys_result; \
- __set_errno(sys_result); \
- return (type)-1; \
-}
+ _sys_result; \
+})
-#define _syscall7(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f,gtype,g) \
-type name (atype a,btype b,ctype c,dtype d,etype e,ftype f,gtype g) \
-{ \
- long err; \
- long sys_result; \
- const unsigned long *constE = (void*)(unsigned long) e; \
- const unsigned long *constF = (void*)(unsigned long) f; \
- const unsigned long *constG = (void*)(unsigned long) g; \
+#define internal_syscall6(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5, arg6) \
+({ \
+ long _sys_result; \
+ \
{ \
- register unsigned long __v0 asm("$2"); \
- register unsigned long __a0 asm("$4") = (unsigned long) a; \
- register unsigned long __a1 asm("$5") = (unsigned long) b; \
- register unsigned long __a2 asm("$6") = (unsigned long) c; \
- register unsigned long __a3 asm("$7") = (unsigned long) d; \
- __asm__ volatile ( \
- ".set noreorder\n\t" \
- "lw $2, %6\n\t" \
- "lw $8, %7\n\t" \
- "lw $9, %8\n\t" \
- "subu $29, 32\n\t" \
- "sw $2, 16($29)\n\t" \
- "sw $8, 20($29)\n\t" \
- "sw $9, 24($29)\n\t" \
- "li $2, %5\t\t\t# " #name "\n\t" \
+ register ARG_TYPE __v0 __asm__("$2") ncs_init; \
+ register ARG_TYPE __a0 __asm__("$4") = (ARG_TYPE) arg1; \
+ register ARG_TYPE __a1 __asm__("$5") = (ARG_TYPE) arg2; \
+ register ARG_TYPE __a2 __asm__("$6") = (ARG_TYPE) arg3; \
+ register ARG_TYPE __a3 __asm__("$7") = (ARG_TYPE) arg4; \
+ register ARG_TYPE __a4 __asm__("$8") = (ARG_TYPE) arg5; \
+ register ARG_TYPE __a5 __asm__("$9") = (ARG_TYPE) arg6; \
+ __asm__ __volatile__ ( \
+ ".set\tnoreorder\n\t" \
+ cs_init \
"syscall\n\t" \
- "addiu $29, 32\n\t" \
- ".set reorder" \
+ ".set\treorder" \
: "=r" (__v0), "+r" (__a3) \
- : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)), \
- "m" (constE), "m" (constF), "m" (constG) \
- : __SYSCALL_CLOBBERS); \
+ : input, "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4), \
+ "r" (__a5) \
+ : __SYSCALL_CLOBBERS); \
err = __a3; \
- sys_result = __v0; \
+ _sys_result = __v0; \
} \
- if (err == 0) \
- return (type) sys_result; \
- __set_errno(sys_result); \
- return (type)-1; \
-}
+ _sys_result; \
+})
+
+#define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \
+ "$14", "$15", "$24", "$25", "memory"
+
+#endif
#endif /* __ASSEMBLER__ */
#endif /* _BITS_SYSCALLS_H */
diff --git a/libc/sysdeps/linux/mips/bits/uClibc_arch_features.h b/libc/sysdeps/linux/mips/bits/uClibc_arch_features.h
index f8d954e3d..42a7c4526 100644
--- a/libc/sysdeps/linux/mips/bits/uClibc_arch_features.h
+++ b/libc/sysdeps/linux/mips/bits/uClibc_arch_features.h
@@ -17,9 +17,6 @@
/* does your target have a broken create_module() ? */
#undef __UCLIBC_BROKEN_CREATE_MODULE__
-/* does your target prefix all symbols with an _ ? */
-#define __UCLIBC_NO_UNDERSCORES__
-
/* does your target have an asm .set ? */
#undef __UCLIBC_HAVE_ASM_SET_DIRECTIVE__
diff --git a/libc/sysdeps/linux/mips/bits/wordsize.h b/libc/sysdeps/linux/mips/bits/wordsize.h
index ba643b60a..666c7ad07 100644
--- a/libc/sysdeps/linux/mips/bits/wordsize.h
+++ b/libc/sysdeps/linux/mips/bits/wordsize.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003 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
@@ -16,4 +16,4 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
-#define __WORDSIZE 32
+#define __WORDSIZE _MIPS_SZPTR
diff --git a/libc/sysdeps/linux/mips/brk.c b/libc/sysdeps/linux/mips/brk.c
index cf48288f4..36620b210 100644
--- a/libc/sysdeps/linux/mips/brk.c
+++ b/libc/sysdeps/linux/mips/brk.c
@@ -21,10 +21,9 @@
#include <unistd.h>
#include <sys/syscall.h>
-libc_hidden_proto(brk)
-
-void *__curbrk = 0;
+void *__curbrk attribute_hidden = 0;
+libc_hidden_proto(brk)
int brk (void *addr)
{
void *newbrk;
@@ -32,7 +31,7 @@ int brk (void *addr)
{
register long int res __asm__ ("$2");
- asm ("move\t$4,%2\n\t"
+ __asm__ ("move\t$4,%2\n\t"
"li\t%0,%1\n\t"
"syscall" /* Perform the system call. */
: "=r" (res)
diff --git a/libc/sysdeps/linux/mips/bsd-_setjmp.S b/libc/sysdeps/linux/mips/bsd-_setjmp.S
index e03c05ced..6853dea98 100644
--- a/libc/sysdeps/linux/mips/bsd-_setjmp.S
+++ b/libc/sysdeps/linux/mips/bsd-_setjmp.S
@@ -22,6 +22,7 @@
in setjmp doesn't clobber the state restored by longjmp. */
#include <sys/regdef.h>
+#include <sys/asm.h>
#ifdef __PIC__
.option pic2
@@ -35,10 +36,16 @@
_setjmp:
#ifdef __PIC__
+#if (_MIPS_SIM == _MIPS_SIM_ABI32)
.set noreorder
.cpload t9
.set reorder
la t9, __sigsetjmp
+#else
+ .cpsetup t9, v0, _setjmp
+ PTR_LA t9, __sigsetjmp
+ .cpreturn
+#endif
#endif
move a1,zero /* Pass a second argument of zero. */
#ifdef __PIC__
diff --git a/libc/sysdeps/linux/mips/bsd-setjmp.S b/libc/sysdeps/linux/mips/bsd-setjmp.S
index 49a904d29..1f57a97e7 100644
--- a/libc/sysdeps/linux/mips/bsd-setjmp.S
+++ b/libc/sysdeps/linux/mips/bsd-setjmp.S
@@ -22,6 +22,7 @@
in setjmp doesn't clobber the state restored by longjmp. */
#include <sys/regdef.h>
+#include <sys/asm.h>
#ifdef __PIC__
.option pic2
@@ -36,9 +37,15 @@
setjmp:
.set noreorder
#ifdef __PIC__
+#if _MIPS_SIM == _MIPS_SIM_ABI32
.cpload t9
.set reorder
la t9, __sigsetjmp
+#else /* N32 */
+ .cpsetup t9, v0, setjmp
+ PTR_LA t9, __sigsetjmp
+ .cprestore
+#endif /* N32 */
#endif
li a1, 1 /* Pass a second argument of one. */
#ifdef __PIC__
diff --git a/libc/sysdeps/linux/mips/cacheflush.c b/libc/sysdeps/linux/mips/cacheflush.c
index cd23e98d0..f99c58171 100644
--- a/libc/sysdeps/linux/mips/cacheflush.c
+++ b/libc/sysdeps/linux/mips/cacheflush.c
@@ -20,7 +20,11 @@
#include <unistd.h>
#include <sys/syscall.h>
+#ifdef __NR_cacheflush
_syscall3(int, cacheflush, void *, addr, const int, nbytes, const int, op);
strong_alias(cacheflush, _flush_cache)
-_syscall3(int, cachectl, void *, addr, const int, nbytes, const int, op);
+#endif
+#ifdef __NR_cachectl
+_syscall3(int, cachectl, void *, addr, const int, nbytes, const int, op);
+#endif
diff --git a/libc/sysdeps/linux/mips/clone.S b/libc/sysdeps/linux/mips/clone.S
index 82f04adfa..716cd993f 100644
--- a/libc/sysdeps/linux/mips/clone.S
+++ b/libc/sysdeps/linux/mips/clone.S
@@ -1,6 +1,6 @@
-/* Copyright (C) 1996, 1997, 2000, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
- Contributed by Ralf Baechle <ralf@linux-mips.org>, 1996.
+ Contributed by Ralf Baechle <ralf@gnu.ai.mit.edu>, 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
@@ -20,117 +20,100 @@
/* 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 <features.h>
+#include <asm/unistd.h>
+#include <sys/regdef.h>
+#define _ERRNO_H 1
+#include <bits/errno.h>
#include <sys/asm.h>
-#include <sysdep.h>
-#include <bits/errno_values.h>
-#ifdef RESET_PID
-#include <tls.h>
-#endif
-
-#define CLONE_VM 0x00000100
-#define CLONE_THREAD 0x00010000
-/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
- void *parent_tidptr, void *tls, void *child_tidptr) */
+/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg) */
.text
-#if _MIPS_SIM == _ABIO32
-# define EXTRA_LOCALS 1
-#else
-# define EXTRA_LOCALS 0
-#endif
-LOCALSZ= 4
-FRAMESZ= (((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK
-GPOFF= FRAMESZ-(1*SZREG)
-NESTED(__clone,4*SZREG,sp)
+.globl clone ;
+ .align 2;
+ .type clone,@function;
+ .ent clone, 0;
+
+clone:
+ .frame sp, 4*SZREG, sp
#ifdef __PIC__
- SETUP_GP
-#endif
- PTR_SUBU sp, FRAMESZ
- SETUP_GP64 (GPOFF, __clone)
-#ifdef __PIC__
- SAVE_GP (GPOFF)
-#endif
-#ifdef PROF
- .set noat
- move $1,ra
- jal _mcount
- .set at
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+ .set noreorder
+ .cpload $25
+ .set reorder
+ subu sp,32
+ .cprestore 16
+#else /* N32 */
+ PTR_SUBU sp,32 /* fn, arg, gp, pad */
+ .cpsetup $25, 16, clone
+#endif /* N32 */
+#else
+ subu sp,32
#endif
/* Sanity check arguments. */
li v0,EINVAL
- beqz a0,L(error) /* No NULL function pointers. */
- beqz a1,L(error) /* No NULL stack pointers. */
+ beqz a0,error /* No NULL function pointers. */
+ beqz a1,error /* No NULL stack pointers. */
+#if _MIPS_SIM != _MIPS_SIM_ABI32
+ and a1,~(16-1) /* force alignment */
+#endif
PTR_SUBU a1,32 /* Reserve argument save space. */
PTR_S a0,0(a1) /* Save function pointer. */
PTR_S a3,PTRSIZE(a1) /* Save argument pointer. */
-#ifdef RESET_PID
- LONG_S a2,(PTRSIZE*2)(a1) /* Save clone flags. */
-#endif
-
- move a0,a2
- /* Shuffle in the last three arguments - arguments 5, 6, and 7 to
- this function, but arguments 3, 4, and 5 to the syscall. */
-#if _MIPS_SIM == _ABIO32
- PTR_L a2,(FRAMESZ+PTRSIZE+PTRSIZE+16)(sp)
- PTR_S a2,16(sp)
- PTR_L a2,(FRAMESZ+16)(sp)
- PTR_L a3,(FRAMESZ+PTRSIZE+16)(sp)
-#else
- move a2,a4
- move a3,a5
- move a4,a6
-#endif
/* Do the system call */
+ move a0,a2
li v0,__NR_clone
syscall
- bnez a3,L(error)
- beqz v0,L(thread_start)
+ bnez a3,error
+ beqz v0,__thread_start
/* Successful return from the parent */
- RESTORE_GP64
- PTR_ADDU sp, FRAMESZ
- ret
+#if _MIPS_SIM != _MIPS_SIM_ABI32
+ .cpreturn
+#endif
+ PTR_ADDU sp,32
+ j $31 ; nop
/* Something bad happened -- no child created */
-L(error):
- move a0,v0
+error:
+#if _MIPS_SIM != _MIPS_SIM_ABI32
+ .cpreturn
+#endif
+ PTR_ADDU sp,32
+
+ /* uClibc change -- start */
+ move a0,v0 /* Pass return val to C function. */
+ /* uClibc change -- stop */
+
#ifdef __PIC__
PTR_LA t9,__syscall_error
- RESTORE_GP64
- PTR_ADDU sp, FRAMESZ
jr t9
#else
- RESTORE_GP64
- PTR_ADDU sp, FRAMESZ
j __syscall_error
#endif
- END(__clone)
+ .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):
- /* cp is already loaded. */
- SAVE_GP (GPOFF)
- /* The stackframe has been created on entry of clone(). */
+.globl __thread_start;
+ .align 2;
+ .ent __thread_start, 0;
-#ifdef RESET_PID
- /* Check and see if we need to reset the PID. */
- LONG_L a0,(PTRSIZE*2)(sp)
- and a1,a0,CLONE_THREAD
- beqz a1,L(restore_pid)
-L(donepid):
+__thread_start:
+#if _MIPS_SIM == _MIPS_SIM_ABI32
+ /* cp is already loaded. */
+ .cprestore 16
#endif
-
+ /* The stackframe has been created on entry of clone(). */
/* Restore the arg for user's function. */
PTR_L t9,0(sp) /* Function pointer. */
PTR_L a0,PTRSIZE(sp) /* Argument pointer. */
@@ -140,27 +123,5 @@ L(donepid):
/* Call _exit rather than doing it inline for breakpoint purposes. */
move a0,v0
-#ifdef __PIC__
- PTR_LA t9,_exit
- jalr t9
-#else
- jal _exit
-#endif
-
-#ifdef RESET_PID
-L(restore_pid):
- and a1,a0,CLONE_VM
- li v0,-1
- bnez a1,L(gotpid)
- li v0,__NR_getpid
- syscall
-L(gotpid):
- READ_THREAD_POINTER(v1)
- INT_S v0,PID_OFFSET(v1)
- INT_S v0,TID_OFFSET(v1)
- b L(donepid)
-#endif
-
- END(__thread_start)
-
-weak_alias (__clone, clone)
+ jal HIDDEN_JUMPTARGET(_exit)
+ .end __thread_start
diff --git a/libc/sysdeps/linux/mips/crt1.S b/libc/sysdeps/linux/mips/crt1.S
index 35dc8c42e..2e38cf07c 100644
--- a/libc/sysdeps/linux/mips/crt1.S
+++ b/libc/sysdeps/linux/mips/crt1.S
@@ -37,6 +37,7 @@
#include <sys/regdef.h>
+#include <sys/asm.h>
#include <features.h>
@@ -83,6 +84,7 @@
__start:
#ifdef __PIC__
+#if _MIPS_SIM == _MIPS_SIM_ABI32
.set noreorder
move $0, $31 /* Save old ra. */
bal 10f /* Find addr of cpload. */
@@ -92,18 +94,29 @@ __start:
move $31, $0
.set reorder
#else
+ move $0, $31; /* Save old ra. */
+ .set noreorder
+ bal 10f /* Find addr of .cpsetup. */
+ nop
+10:
+ .set reorder
+ .cpsetup $31, $25, 10b
+ move $31, $0
+#endif
+#else
la $28, _gp /* Setup GP correctly if we're non-PIC. */
move $31, $0
#endif
- la $4, main /* main */
- lw $5, 0($29) /* argc */
- addiu $6, $29, 4 /* argv */
+ PTR_LA $4, main /* main */
+ PTR_L $5, 0($29) /* argc */
+ PTR_ADDIU $6, $29, PTRSIZE /* argv */
/* Allocate space on the stack for seven arguments and
* make sure the stack is aligned to double words (8 bytes) */
+#if _MIPS_SIM == _MIPS_SIM_ABI32
and $29, -2 * 4
subu $29, 32
la $7, _init /* init */
@@ -111,6 +124,13 @@ __start:
sw $8, 16($29) /* fini */
sw $2, 20($29) /* rtld_fini */
sw $29, 24($29) /* stack_end */
+#else
+ and $29, -2 * PTRSIZE
+ PTR_LA $7, _init /* init */
+ PTR_LA $8, _fini /* fini */
+ move $9, $2 /* rtld_fini */
+ move $10, $29 /* stack_end */
+#endif
jal __uClibc_main
hlt:
/* Crash if somehow `__uClibc_main' returns anyway. */
diff --git a/libc/sysdeps/linux/mips/crti.S b/libc/sysdeps/linux/mips/crti.S
index b0d523b2f..9311a735f 100644
--- a/libc/sysdeps/linux/mips/crti.S
+++ b/libc/sysdeps/linux/mips/crti.S
@@ -1,3 +1,5 @@
+#include "sgidefs.h"
+#if _MIPS_SIM == _MIPS_SIM_ABI32
.file 1 "initfini.c"
.section .mdebug.abi32
.previous
@@ -48,3 +50,109 @@ _fini:
.end _fini
.ident "GCC: (GNU) 3.3.2"
+#elif _MIPS_SIM == _MIPS_SIM_NABI32
+ .file 1 "initfini.c"
+ .section .mdebug.abiN32
+ .previous
+ .abicalls
+#APP
+
+ .section .init
+#NO_APP
+ .align 2
+ .align 3
+ .globl _init
+ .ent _init
+ .type _init, @function
+_init:
+ .frame $sp,16,$31 # vars= 0, regs= 2/0, args= 0, gp= 0
+ .mask 0x90000000,-8
+ .fmask 0x00000000,0
+ addiu $sp,$sp,-16
+ sd $28,0($sp)
+ lui $28,%hi(%neg(%gp_rel(_init)))
+ addu $28,$28,$25
+ addiu $28,$28,%lo(%neg(%gp_rel(_init)))
+ sd $31,8($sp)
+#APP
+
+ .align 3
+ .end _init
+
+ .section .fini
+#NO_APP
+ .align 2
+ .align 3
+ .globl _fini
+ .ent _fini
+ .type _fini, @function
+_fini:
+ .frame $sp,16,$31 # vars= 0, regs= 2/0, args= 0, gp= 0
+ .mask 0x90000000,-8
+ .fmask 0x00000000,0
+ addiu $sp,$sp,-16
+ sd $28,0($sp)
+ lui $28,%hi(%neg(%gp_rel(_fini)))
+ addu $28,$28,$25
+ addiu $28,$28,%lo(%neg(%gp_rel(_fini)))
+ sd $31,8($sp)
+#APP
+ .align 3
+ .end _fini
+
+ .ident "GCC: (GNU) 3.4.3"
+#else /* N64 */
+ .file 1 "initfini.c"
+ .section .mdebug.abi64
+ .previous
+ .abicalls
+#APP
+
+
+ .section .init
+#NO_APP
+ .align 2
+ .globl _init
+ .ent _init
+ .type _init, @function
+_init:
+ .frame $sp,32,$31 # vars= 0, regs= 2/0, args= 0, extra= 16
+ .mask 0x90000000,-8
+ .fmask 0x00000000,0
+ dsubu $sp,$sp,32
+ sd $31,24($sp)
+ sd $28,16($sp)
+ .set noat
+ lui $1,%hi(%neg(%gp_rel(_init)))
+ addiu $1,$1,%lo(%neg(%gp_rel(_init)))
+ daddu $gp,$1,$25
+ .set at
+#APP
+
+ .align 2
+ .end _init
+
+ .section .fini
+#NO_APP
+ .align 2
+ .globl _fini
+ .ent _fini
+ .type _fini, @function
+_fini:
+ .frame $sp,32,$31 # vars= 0, regs= 2/0, args= 0, extra= 16
+ .mask 0x90000000,-8
+ .fmask 0x00000000,0
+ dsubu $sp,$sp,32
+ sd $31,24($sp)
+ sd $28,16($sp)
+ .set noat
+ lui $1,%hi(%neg(%gp_rel(_fini)))
+ addiu $1,$1,%lo(%neg(%gp_rel(_fini)))
+ daddu $gp,$1,$25
+ .set at
+#APP
+ .align 2
+ .end _fini
+
+ .ident "GCC: (GNU) 3.3.2"
+#endif /* N64 */
diff --git a/libc/sysdeps/linux/mips/crtn.S b/libc/sysdeps/linux/mips/crtn.S
index 7a5e4db6e..cedd593f0 100644
--- a/libc/sysdeps/linux/mips/crtn.S
+++ b/libc/sysdeps/linux/mips/crtn.S
@@ -1,3 +1,5 @@
+#include "sgidefs.h"
+#if _MIPS_SIM == _MIPS_SIM_ABI32
.file 1 "initfini.c"
.section .mdebug.abi32
.previous
@@ -43,3 +45,101 @@
#APP
.ident "GCC: (GNU) 3.3.2"
+#elif _MIPS_SIM == _MIPS_SIM_NABI32
+ .file 1 "initfini.c"
+ .section .mdebug.abiN32
+ .previous
+ .abicalls
+#APP
+
+ .section .init
+#NO_APP
+ .align 2
+ .align 3
+ .globl _init
+ .ent _init
+ .type _init, @function
+#NO_APP
+ ld $31,8($sp)
+ ld $28,0($sp)
+ .set noreorder
+ .set nomacro
+ j $31
+ addiu $sp,$sp,16
+ .set macro
+ .set reorder
+
+ .end _init
+#APP
+
+ .section .fini
+#NO_APP
+ .align 2
+ .align 3
+ .globl _fini
+ .ent _fini
+ .type _fini, @function
+#NO_APP
+ ld $31,8($sp)
+ ld $28,0($sp)
+ .set noreorder
+ .set nomacro
+ j $31
+ addiu $sp,$sp,16
+ .set macro
+ .set reorder
+
+ .end _fini
+#APP
+
+ .ident "GCC: (GNU) 3.4.3"
+#else /* N64 */
+ .file 1 "initfini.c"
+ .section .mdebug.abi64
+ .previous
+ .abicalls
+#APP
+
+
+ .section .init
+#NO_APP
+ .align 2
+ .globl _init
+ .ent _init
+ .type _init, @function
+#NO_APP
+ ld $31,24($sp)
+ ld $28,16($sp)
+ #nop
+ .set noreorder
+ .set nomacro
+ j $31
+ daddu $sp,$sp,32
+ .set macro
+ .set reorder
+
+ .end _init
+#APP
+
+ .section .fini
+#NO_APP
+ .align 2
+ .globl _fini
+ .ent _fini
+ .type _fini, @function
+#NO_APP
+ ld $31,24($sp)
+ ld $28,16($sp)
+ #nop
+ .set noreorder
+ .set nomacro
+ j $31
+ daddu $sp,$sp,32
+ .set macro
+ .set reorder
+
+ .end _fini
+#APP
+
+ .ident "GCC: (GNU) 3.3.2"
+#endif /* N64 */
diff --git a/libc/sysdeps/linux/mips/fpu_control.h b/libc/sysdeps/linux/mips/fpu_control.h
index da18deab5..c58b23503 100644
--- a/libc/sysdeps/linux/mips/fpu_control.h
+++ b/libc/sysdeps/linux/mips/fpu_control.h
@@ -92,7 +92,9 @@ typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__)));
#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/mips/pipe.S b/libc/sysdeps/linux/mips/pipe.S
index e75acb621..8b3023679 100644
--- a/libc/sysdeps/linux/mips/pipe.S
+++ b/libc/sysdeps/linux/mips/pipe.S
@@ -1,29 +1,45 @@
/* pipe system call for Linux/MIPS */
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
/*see uClibc's sh/pipe.c and glibc-2.2.4's mips/pipe.S */
#include <features.h>
-#include <asm/asm.h>
+#include <sys/asm.h>
#include <asm/unistd.h>
-#include <asm/regdef.h>
+#include <sys/regdef.h>
.globl pipe
.ent pipe, 0
+ .type pipe,@function
pipe:
+#ifdef __PIC__
+ SETUP_GP
+#endif
li v0,__NR_pipe
syscall
- beqz a3, 1f
+ bnez a3, 1f
+ sw v0, 0(a0)
+ sw v1, 4(a0)
+ li v0, 0
+ j ra
+1:
+ /* uClibc change -- start */
+ move a0,v0 /* Pass return val to C function. */
+ /* uClibc change -- stop */
+
#ifdef __PIC__
- la t9, __syscall_error
+ SETUP_GP64(v0, pipe)
+ PTR_LA t9, __syscall_error
+ RESTORE_GP64
jr t9
#else
j __syscall_error
#endif
1:
- sw v0, 0(a0)
- sw v1, 4(a0)
- li v0, 0
- j ra
.end pipe
.size pipe,.-pipe
libc_hidden_def(pipe)
diff --git a/libc/sysdeps/linux/mips/posix_fadvise.c b/libc/sysdeps/linux/mips/posix_fadvise.c
new file mode 100644
index 000000000..8546d96ba
--- /dev/null
+++ b/libc/sysdeps/linux/mips/posix_fadvise.c
@@ -0,0 +1,39 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * posix_fadvise() for MIPS uClibc
+ * http://www.opengroup.org/onlinepubs/009695399/functions/posix_fadvise.html
+ *
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <features.h>
+#include <unistd.h>
+#include <errno.h>
+#include <endian.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <fcntl.h>
+
+int posix_fadvise(int fd, off_t offset, off_t len, int advice)
+{
+/* MIPS kernel only has NR_fadvise64 which acts as NR_fadvise64_64 */
+#ifdef __NR_fadvise64
+ INTERNAL_SYSCALL_DECL(err);
+# if _MIPS_SIM == _ABIO32
+ int ret = INTERNAL_SYSCALL(fadvise64, err, 7, fd, 0,
+ __LONG_LONG_PAIR ((long) (offset >> 31), (long) offset),
+ __LONG_LONG_PAIR ((long) (len >> 31), (long) len),
+ advice);
+# else /* N32 || N64 */
+ int ret = INTERNAL_SYSCALL(fadvise64, err, 4, fd, offset, len, advice);
+# endif
+ if (INTERNAL_SYSCALL_ERROR_P (ret, err))
+ return INTERNAL_SYSCALL_ERRNO (ret, err);
+ return 0;
+#else
+ return ENOSYS;
+#endif
+}
diff --git a/libc/sysdeps/linux/mips/posix_fadvise64.c b/libc/sysdeps/linux/mips/posix_fadvise64.c
new file mode 100644
index 000000000..d9b89d123
--- /dev/null
+++ b/libc/sysdeps/linux/mips/posix_fadvise64.c
@@ -0,0 +1,43 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * posix_fadvise64() for MIPS uClibc
+ * http://www.opengroup.org/onlinepubs/009695399/functions/posix_fadvise.html
+ *
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include <features.h>
+#include <unistd.h>
+#include <errno.h>
+#include <endian.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <fcntl.h>
+
+#ifdef __UCLIBC_HAS_LFS__
+
+int posix_fadvise64(int fd, __off64_t offset, __off64_t len, int advice)
+{
+/* MIPS kernel only has NR_fadvise64 which acts as NR_fadvise64_64 */
+#ifdef __NR_fadvise64
+ INTERNAL_SYSCALL_DECL(err);
+# if _MIPS_SIM == _MIPS_SIM_ABI32
+ int ret = INTERNAL_SYSCALL(fadvise64, err, 7, fd, 0,
+ __LONG_LONG_PAIR ((long) (offset >> 32), (long) offset),
+ __LONG_LONG_PAIR ((long) (len >> 32), (long) len),
+ advice);
+# else /* N32 || N64 */
+ int ret = INTERNAL_SYSCALL(fadvise64, err, 4, fd, offset, len, advice);
+# endif
+ if (INTERNAL_SYSCALL_ERROR_P (ret, err))
+ return INTERNAL_SYSCALL_ERRNO (ret, err);
+ return 0;
+#else
+ return ENOSYS;
+#endif
+}
+
+#endif /* __UCLIBC_HAS_LFS__ */
diff --git a/libc/sysdeps/linux/mips/pread_write.c b/libc/sysdeps/linux/mips/pread_write.c
index 302dcd64f..553864531 100644
--- a/libc/sysdeps/linux/mips/pread_write.c
+++ b/libc/sysdeps/linux/mips/pread_write.c
@@ -1,56 +1,23 @@
-/* vi: set sw=4 ts=4:
+/* vi: set sw=4 ts=4: */
+/*
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
*
- * Copyright (C) 2006 by Steven J. Hill <sjhill@realitydiluted.com>
- * Copyright (C) 2002-2005 by Erik Andersen <andersen@uclibc.org>
- *
- * New version based heavily on the files:
- * sysdeps/linux/sysv/linux/mips/pread.c,
- * sysdeps/linux/sysv/linux/mips/pread64.c,
- * sysdeps/linux/sysv/linux/mips/pwrite.c,
- * sysdeps/linux/sysv/linux/mips/pwrite64.c
- * from GNU libc 2.3.5, but with minor rework.
- *
- * Originally based in part on the files:
- * sysdeps/unix/sysv/linux/pwrite.c,
- * sysdeps/unix/sysv/linux/pread.c,
- * sysdeps/posix/pread.c,
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+/*
+ * Based in part on the files
+ * ./sysdeps/unix/sysv/linux/pwrite.c,
+ * ./sysdeps/unix/sysv/linux/pread.c,
+ * sysdeps/posix/pread.c
* sysdeps/posix/pwrite.c
- * from GNU libc 2.2.5, but reworked considerably.
- *
- * 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; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * from GNU libc 2.2.5, but reworked considerably...
*/
-#define _LARGEFILE64_SOURCE
-#include <features.h>
-#undef __OPTIMIZE__
-/* We absolutely do _NOT_ want interfaces silently
- * * * renamed under us or very bad things will happen... */
-#ifdef __USE_FILE_OFFSET64
-# undef __USE_FILE_OFFSET64
-#endif
-
-
-#include <errno.h>
-#include <sys/types.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <stdint.h>
-#include <assert.h>
-#ifdef __UCLIBC_HAS_THREADS_NATIVE__
-#include <sysdep-cancel.h>
-#endif
+#include <endian.h>
+#include <sgidefs.h>
#ifdef __NR_pread64 /* Newer kernels renamed but it's the same. */
# ifdef __NR_pread
@@ -59,79 +26,48 @@
# define __NR_pread __NR_pread64
#endif
-#ifdef __NR_pread
-ssize_t
-__libc_pread (int fd, void *buf, size_t count, off_t offset)
-{
- ssize_t result;
-
-#if _MIPS_SIM != _ABI64
- assert (sizeof (offset) == 4);
+extern __typeof(pread) __libc_pread;
+extern __typeof(pwrite) __libc_pwrite;
+#ifdef __UCLIBC_HAS_LFS__
+extern __typeof(pread64) __libc_pread64;
+extern __typeof(pwrite64) __libc_pwrite64;
#endif
- if (SINGLE_THREAD_P)
- {
- /* First try the syscall. */
-#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64
- result = INLINE_SYSCALL (pread, 4, fd, buf, count, offset);
-#else
- result = INLINE_SYSCALL (pread, 6, fd, buf, count, 0,
- __LONG_LONG_PAIR (offset >> 31, offset));
-#endif
- return result;
- }
+#include <bits/kernel_types.h>
- int oldtype = LIBC_CANCEL_ASYNC ();
-
- /* First try the syscall. */
-#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64
- result = INLINE_SYSCALL (pread, 4, fd, buf,, count, offset);
-#else
- result = INLINE_SYSCALL (pread, 6, fd, buf, count, 0,
- __LONG_LONG_PAIR (offset >> 31, offset));
-#endif
- LIBC_CANCEL_RESET (oldtype);
+#ifdef __NR_pread
- return result;
-}
+# if _MIPS_SIM == _MIPS_SIM_ABI64
+# define __NR___libc_pread __NR_pread
+_syscall4(ssize_t, __libc_pread, int, fd, void *, buf, size_t, count, off_t, offset);
weak_alias (__libc_pread, pread)
-
-#if defined __UCLIBC_HAS_LFS__
-ssize_t
-__libc_pread64 (int fd, void *buf, size_t count, off64_t offset)
+# ifdef __UCLIBC_HAS_LFS__
+# define __NR___libc_pread64 __NR_pread
+_syscall4(ssize_t, __libc_pread64, int, fd, void *, buf, size_t, count, off64_t, offset);
+weak_alias (__libc_pread64, pread64)
+# endif /* __UCLIBC_HAS_LFS__ */
+# else /* O32 || N32 */
+# define __NR___syscall_pread __NR_pread
+static inline _syscall6(ssize_t, __syscall_pread, int, fd, void *, buf,
+ size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo);
+
+ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset)
{
- ssize_t result;
-
- if (SINGLE_THREAD_P)
- {
- /* First try the syscall. */
-#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64
- return INLINE_SYSCALL (pread, 4, fd, buf, count, offset);
-#else
- return INLINE_SYSCALL (pread, 6, fd, buf, count, 0,
- __LONG_LONG_PAIR ((off_t) (offset >> 32),
- (off_t) (offset & 0xffffffff)));
-#endif
- }
-
- int oldtype = LIBC_CANCEL_ASYNC ();
-
- /* First try the syscall. */
-#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64
- result = INLINE_SYSCALL (pread, 4, fd, buf, count, offset);
-#else
- result = INLINE_SYSCALL (pread, 6, fd, buf, count, 0,
- __LONG_LONG_PAIR ((off_t) (offset >> 32),
- (off_t) (offset & 0xffffffff)));
-#endif
-
- LIBC_CANCEL_RESET (oldtype);
+ return(__syscall_pread(fd,buf,count,0,__LONG_LONG_PAIR(offset>>31,offset)));
+}
+weak_alias(__libc_pread,pread)
- return result;
+# ifdef __UCLIBC_HAS_LFS__
+ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset)
+{
+ uint32_t low = offset & 0xffffffff;
+ uint32_t high = offset >> 32;
+ return(__syscall_pread(fd, buf, count, 0, __LONG_LONG_PAIR (high, low)));
}
-weak_alias(__libc_pread64, pread64)
-#endif /* __UCLIBC_HAS_LFS__ */
+weak_alias(__libc_pread64,pread64)
+# endif /* __UCLIBC_HAS_LFS__ */
+# endif /* O32 || N32 */
#endif /* __NR_pread */
@@ -145,78 +81,35 @@ weak_alias(__libc_pread64, pread64)
#endif
#ifdef __NR_pwrite
-ssize_t
-__libc_pwrite (int fd, const void *buf, size_t count, off_t offset)
-{
- ssize_t result;
-
-#if _MIPS_SIM != _ABI64
- assert (sizeof (offset) == 4);
-#endif
-
- if (SINGLE_THREAD_P)
- {
- /* First try the syscall. */
-#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64
- result = INLINE_SYSCALL (pwrite, 4, fd, buf, count, offset);
-#else
- result = INLINE_SYSCALL (pwrite, 6, fd, buf, count, 0,
- __LONG_LONG_PAIR (offset >> 31, offset));
-#endif
- return result;
- }
- int oldtype = LIBC_CANCEL_ASYNC ();
-
- /* First try the syscall. */
-#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64
- result = INLINE_SYSCALL (pwrite, 4, fd, buf, count, offset);
-#else
- result = INLINE_SYSCALL (pwrite, 6, fd, buf, count, 0,
- __LONG_LONG_PAIR (offset >> 31, offset));
-#endif
-
- LIBC_CANCEL_RESET (oldtype);
-
- return result;
+# if _MIPS_SIM == _MIPS_SIM_ABI64
+# define __NR___libc_pwrite __NR_pwrite
+_syscall4(ssize_t, __libc_pwrite, int, fd, const void *, buf, size_t, count, off_t, offset);
+weak_alias (__libc_pwrite, pwrite)
+# ifdef __UCLIBC_HAS_LFS__
+# define __NR___libc_pwrite64 __NR_pwrite
+_syscall4(ssize_t, __libc_pwrite64, int, fd, const void *, buf, size_t, count, off64_t, offset);
+weak_alias (__libc_pwrite64, pwrite64)
+# endif /* __UCLIBC_HAS_LFS__ */
+# else /* O32 || N32 */
+# define __NR___syscall_pwrite __NR_pwrite
+static inline _syscall6(ssize_t, __syscall_pwrite, int, fd, const void *, buf,
+ size_t, count, int, dummy, off_t, offset_hi, off_t, offset_lo);
+
+ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset)
+{
+ return(__syscall_pwrite(fd,buf,count,0,__LONG_LONG_PAIR(offset>>31,offset)));
}
-weak_alias(__libc_pwrite, pwrite)
+weak_alias(__libc_pwrite,pwrite)
-#if defined __UCLIBC_HAS_LFS__
-ssize_t
-__libc_pwrite64 (int fd, const void *buf, size_t count, off64_t offset)
+# ifdef __UCLIBC_HAS_LFS__
+ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset)
{
- ssize_t result;
-
- if (SINGLE_THREAD_P)
- {
- /* First try the syscall. */
-#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64
- result = INLINE_SYSCALL (pwrite, 4, fd, buf, count, offset);
-#else
- result = INLINE_SYSCALL (pwrite, 6, fd, buf, count, 0,
- __LONG_LONG_PAIR ((off_t) (offset >> 32),
- (off_t) (offset & 0xffffffff)));
-#endif
- return result;
- }
-
- int oldtype = LIBC_CANCEL_ASYNC ();
-
- /* First try the syscall. */
-#if _MIPS_SIM == _ABIN32 || _MIPS_SIM == _ABI64
- result = INLINE_SYSCALL (pwrite, 4, fd, buf, count, offset);
-#else
- result = INLINE_SYSCALL (pwrite, 6, fd, buf, count, 0,
- __LONG_LONG_PAIR ((off_t) (offset >> 32),
- (off_t) (offset & 0xffffffff)));
-#endif
-
- LIBC_CANCEL_RESET (oldtype);
-
- return result;
+ uint32_t low = offset & 0xffffffff;
+ uint32_t high = offset >> 32;
+ return(__syscall_pwrite(fd, buf, count, 0, __LONG_LONG_PAIR (high, low)));
}
-weak_alias(__libc_pwrite64, pwrite64)
-#endif /* __UCLIBC_HAS_LFS__ */
-
+weak_alias(__libc_pwrite64,pwrite64)
+# endif /* __UCLIBC_HAS_LFS__ */
+# endif /* O32 || N32 */
#endif /* __NR_pwrite */
diff --git a/libc/sysdeps/linux/mips/readahead.c b/libc/sysdeps/linux/mips/readahead.c
new file mode 100644
index 000000000..9157c2762
--- /dev/null
+++ b/libc/sysdeps/linux/mips/readahead.c
@@ -0,0 +1,41 @@
+/* Provide kernel hint to read ahead.
+ Copyright (C) 2002, 2003, 2004 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 <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+
+#ifdef __UCLIBC_HAS_LFS__
+#include <_lfs_64.h>
+# ifdef __NR_readahead
+
+ssize_t readahead(int fd, off64_t offset, size_t count)
+{
+# if _MIPS_SIM == _ABIO32
+ return INLINE_SYSCALL (readahead, 5, fd, 0,
+ __LONG_LONG_PAIR ((off_t) (offset >> 32), (off_t) offset),
+ count);
+# else /* N32 || N64 */
+ return INLINE_SYSCALL (readahead, 3, fd, offset, count);
+# endif
+}
+
+# endif
+#endif
diff --git a/libc/sysdeps/linux/mips/setjmp.S b/libc/sysdeps/linux/mips/setjmp.S
index 0d9a8d431..226f75524 100644
--- a/libc/sysdeps/linux/mips/setjmp.S
+++ b/libc/sysdeps/linux/mips/setjmp.S
@@ -17,6 +17,7 @@
02111-1307 USA. */
#include <sys/regdef.h>
+#include <sys/asm.h>
/* The function __sigsetjmp_aux saves all the registers, but it can't
reliably access the stack or frame pointers, so we pass them in as
@@ -35,7 +36,11 @@
__sigsetjmp:
#ifdef __PIC__
.set noreorder
+#if _MIPS_SIM == _MIPS_SIM_ABI32
.cpload t9
+#else
+ .cpsetup t9, v0, __sigsetjmp
+#endif
.set reorder
#endif
move a2, sp
@@ -45,7 +50,10 @@ __sigsetjmp:
move a3, $fp
#endif
#ifdef __PIC__
- la t9, __sigsetjmp_aux
+ PTR_LA t9, __sigsetjmp_aux
+#if _MIPS_SIM != _MIPS_SIM_ABI32
+ .cpreturn
+#endif
jr t9
#else
j __sigsetjmp_aux
diff --git a/libc/sysdeps/linux/mips/setjmp_aux.c b/libc/sysdeps/linux/mips/setjmp_aux.c
index 166eb7eb1..751b32d7d 100644
--- a/libc/sysdeps/linux/mips/setjmp_aux.c
+++ b/libc/sysdeps/linux/mips/setjmp_aux.c
@@ -19,6 +19,8 @@
#include <features.h>
#include <setjmp.h>
+#include <sgidefs.h>
+#include <sys/asm.h>
/* This function is only called via the assembly language routine
__sigsetjmp, which arranges to pass in the stack pointer and the frame
@@ -28,20 +30,39 @@
extern int __sigjmp_save (sigjmp_buf, int);
int
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+__sigsetjmp_aux (jmp_buf env, int savemask, long sp, long fp)
+#else /* O32 || N32 */
__sigsetjmp_aux (jmp_buf env, int savemask, int sp, int fp)
+#endif /* O32 || N32 */
{
#if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__
/* Store the floating point callee-saved registers... */
- asm volatile ("s.d $f20, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[0]));
- asm volatile ("s.d $f22, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[1]));
- asm volatile ("s.d $f24, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[2]));
- asm volatile ("s.d $f26, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[3]));
- asm volatile ("s.d $f28, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[4]));
- asm volatile ("s.d $f30, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[5]));
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+ __asm__ __volatile__ ("s.d $f24, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[0]));
+ __asm__ __volatile__ ("s.d $f25, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[1]));
+ __asm__ __volatile__ ("s.d $f26, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[2]));
+ __asm__ __volatile__ ("s.d $f27, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[3]));
+ __asm__ __volatile__ ("s.d $f28, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[4]));
+ __asm__ __volatile__ ("s.d $f29, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[5]));
+ __asm__ __volatile__ ("s.d $f30, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[6]));
+ __asm__ __volatile__ ("s.d $f31, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[7]));
+#else /* O32 || N32 */
+ __asm__ __volatile__ ("s.d $f20, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[0]));
+ __asm__ __volatile__ ("s.d $f22, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[1]));
+ __asm__ __volatile__ ("s.d $f24, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[2]));
+ __asm__ __volatile__ ("s.d $f26, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[3]));
+ __asm__ __volatile__ ("s.d $f28, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[4]));
+ __asm__ __volatile__ ("s.d $f30, %0" : : "m" (env[0].__jmpbuf[0].__fpregs[5]));
+#endif /* O32 || N32 */
#endif
/* .. and the PC; */
- asm volatile ("sw $31, %0" : : "m" (env[0].__jmpbuf[0].__pc));
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+ __asm__ __volatile__ ("sd $31, %0" : : "m" (env[0].__jmpbuf[0].__pc));
+#else
+ __asm__ __volatile__ ("sw $31, %0" : : "m" (env[0].__jmpbuf[0].__pc));
+#endif
/* .. and the stack pointer; */
env[0].__jmpbuf[0].__sp = (void *) sp;
@@ -50,21 +71,36 @@ __sigsetjmp_aux (jmp_buf env, int savemask, int sp, int fp)
env[0].__jmpbuf[0].__fp = (void *) fp;
/* .. and the GP; */
- asm volatile ("sw $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp));
+#if _MIPS_SIM == _MIPS_SIM_ABI64
+ __asm__ __volatile__ ("sd $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp));
+#else
+ __asm__ __volatile__ ("sw $gp, %0" : : "m" (env[0].__jmpbuf[0].__gp));
+#endif
/* .. and the callee-saved registers; */
- asm volatile ("sw $16, %0" : : "m" (env[0].__jmpbuf[0].__regs[0]));
- asm volatile ("sw $17, %0" : : "m" (env[0].__jmpbuf[0].__regs[1]));
- asm volatile ("sw $18, %0" : : "m" (env[0].__jmpbuf[0].__regs[2]));
- asm volatile ("sw $19, %0" : : "m" (env[0].__jmpbuf[0].__regs[3]));
- asm volatile ("sw $20, %0" : : "m" (env[0].__jmpbuf[0].__regs[4]));
- asm volatile ("sw $21, %0" : : "m" (env[0].__jmpbuf[0].__regs[5]));
- asm volatile ("sw $22, %0" : : "m" (env[0].__jmpbuf[0].__regs[6]));
- asm volatile ("sw $23, %0" : : "m" (env[0].__jmpbuf[0].__regs[7]));
+#if (_MIPS_SIM == _MIPS_SIM_ABI32)
+ __asm__ __volatile__ ("sw $16, %0" : : "m" (env[0].__jmpbuf[0].__regs[0]));
+ __asm__ __volatile__ ("sw $17, %0" : : "m" (env[0].__jmpbuf[0].__regs[1]));
+ __asm__ __volatile__ ("sw $18, %0" : : "m" (env[0].__jmpbuf[0].__regs[2]));
+ __asm__ __volatile__ ("sw $19, %0" : : "m" (env[0].__jmpbuf[0].__regs[3]));
+ __asm__ __volatile__ ("sw $20, %0" : : "m" (env[0].__jmpbuf[0].__regs[4]));
+ __asm__ __volatile__ ("sw $21, %0" : : "m" (env[0].__jmpbuf[0].__regs[5]));
+ __asm__ __volatile__ ("sw $22, %0" : : "m" (env[0].__jmpbuf[0].__regs[6]));
+ __asm__ __volatile__ ("sw $23, %0" : : "m" (env[0].__jmpbuf[0].__regs[7]));
+#else /* N32 || N64 */
+ __asm__ __volatile__ ("sd $16, %0" : : "m" (env[0].__jmpbuf[0].__regs[0]));
+ __asm__ __volatile__ ("sd $17, %0" : : "m" (env[0].__jmpbuf[0].__regs[1]));
+ __asm__ __volatile__ ("sd $18, %0" : : "m" (env[0].__jmpbuf[0].__regs[2]));
+ __asm__ __volatile__ ("sd $19, %0" : : "m" (env[0].__jmpbuf[0].__regs[3]));
+ __asm__ __volatile__ ("sd $20, %0" : : "m" (env[0].__jmpbuf[0].__regs[4]));
+ __asm__ __volatile__ ("sd $21, %0" : : "m" (env[0].__jmpbuf[0].__regs[5]));
+ __asm__ __volatile__ ("sd $22, %0" : : "m" (env[0].__jmpbuf[0].__regs[6]));
+ __asm__ __volatile__ ("sd $23, %0" : : "m" (env[0].__jmpbuf[0].__regs[7]));
+#endif /* N32 || N64 */
#if defined __UCLIBC_HAS_FLOATS__ && ! defined __UCLIBC_HAS_SOFT_FLOAT__
/* .. and finally get and reconstruct the floating point csr. */
- asm ("cfc1 %0, $31" : "=r" (env[0].__jmpbuf[0].__fpc_csr));
+ __asm__ ("cfc1 %0, $31" : "=r" (env[0].__jmpbuf[0].__fpc_csr));
#endif
/* Save the signal mask if requested. */
diff --git a/libc/sysdeps/linux/mips/sigaction.c b/libc/sysdeps/linux/mips/sigaction.c
index bd3382f63..0135481ae 100644
--- a/libc/sysdeps/linux/mips/sigaction.c
+++ b/libc/sysdeps/linux/mips/sigaction.c
@@ -1,154 +1,129 @@
-/* Copyright (C) 1997,1998,1999,2000,2002,2003, 2004
- Free Software Foundation, Inc.
+/* Copyright (C) 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.
+ 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.
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.
+ Library 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. */
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Totally hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
+ */
#include <errno.h>
#include <signal.h>
#include <string.h>
-#include <sysdep.h>
#include <sys/syscall.h>
-
-#include "kernel-features.h"
-
-/* The difference here is that the sigaction structure used in the
- kernel is not the same as we use in the libc. Therefore we must
- translate it here. */
#include <bits/kernel_sigaction.h>
-#ifndef LIBC_SIGACTION
+#define SA_RESTORER 0x04000000
+
extern __typeof(sigaction) __libc_sigaction;
-#endif
-#if __ASSUME_REALTIME_SIGNALS == 0
-/* The variable is shared between all wrappers around signal handling
- functions which have RT equivalents. This is the definition. */
-int __libc_missing_rt_sigs;
+#ifdef __NR_rt_sigaction
-#endif
+/* Experimentally off - libc_hidden_proto(memcpy) */
#if _MIPS_SIM != _ABIO32
# ifdef __NR_rt_sigreturn
-static void restore_rt (void) asm ("__restore_rt");
+static void restore_rt (void) __asm__ ("__restore_rt");
# endif
# ifdef __NR_sigreturn
-static void restore (void) asm ("__restore");
+static void restore (void) __asm__ ("__restore");
# endif
#endif
/* If ACT is not NULL, change the action for SIG to *ACT.
If OACT is not NULL, put the old action for SIG in *OACT. */
-int
-__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
+int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
{
-#if __ASSUME_REALTIME_SIGNALS == 0
- struct old_kernel_sigaction k_sigact, k_osigact;
-#endif
- int result;
-
-#if defined __NR_rt_sigaction || __ASSUME_REALTIME_SIGNALS > 0
- /* First try the RT signals. */
-# if __ASSUME_REALTIME_SIGNALS == 0
- if (!__libc_missing_rt_sigs)
-# endif
- {
- struct kernel_sigaction kact, koact;
- /* Save the current error value for later. We need not do this
- if we are guaranteed to have realtime signals. */
-# if __ASSUME_REALTIME_SIGNALS == 0
- int saved_errno = errno;
-# endif
+ int result;
+ struct kernel_sigaction kact, koact;
- if (act)
- {
- kact.k_sa_handler = act->sa_handler;
- memcpy (&kact.sa_mask, &act->sa_mask, sizeof (kernel_sigset_t));
- kact.sa_flags = act->sa_flags;
+ if (act) {
+ kact.k_sa_handler = act->sa_handler;
+ memcpy (&kact.sa_mask, &act->sa_mask, sizeof (kact.sa_mask));
+ kact.sa_flags = act->sa_flags;
# ifdef HAVE_SA_RESTORER
# if _MIPS_SIM == _ABIO32
- kact.sa_restorer = act->sa_restorer;
+ kact.sa_restorer = act->sa_restorer;
# else
- kact.sa_restorer = &restore_rt;
+ kact.sa_restorer = &restore_rt;
# endif
# endif
- }
+ }
- /* XXX The size argument hopefully will have to be changed to the
- real size of the user-level sigset_t. */
- result = INLINE_SYSCALL (rt_sigaction, 4, sig,
- act ? __ptrvalue (&kact) : NULL,
- oact ? __ptrvalue (&koact) : NULL,
- sizeof (kernel_sigset_t));
+ /* XXX The size argument hopefully will have to be changed to the
+ real size of the user-level sigset_t. */
+ result = __syscall_rt_sigaction(sig, act ? __ptrvalue (&kact) : NULL,
+ oact ? __ptrvalue (&koact) : NULL, _NSIG / 8);
-# if __ASSUME_REALTIME_SIGNALS == 0
- if (result >= 0 || errno != ENOSYS)
-# endif
- {
- if (oact && result >= 0)
- {
- oact->sa_handler = koact.k_sa_handler;
- memcpy (&oact->sa_mask, &koact.sa_mask,
- sizeof (kernel_sigset_t));
- oact->sa_flags = koact.sa_flags;
+ if (oact && result >= 0) {
+ oact->sa_handler = koact.k_sa_handler;
+ memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (oact->sa_mask));
+ oact->sa_flags = koact.sa_flags;
# ifdef HAVE_SA_RESTORER
- oact->sa_restorer = koact.sa_restorer;
-# endif
- }
- return result;
- }
-
-# if __ASSUME_REALTIME_SIGNALS == 0
- __set_errno (saved_errno);
- __libc_missing_rt_sigs = 1;
+ oact->sa_restorer = koact.sa_restorer;
# endif
}
-#endif
+ return result;
+}
-#if __ASSUME_REALTIME_SIGNALS == 0
- if (act)
- {
- k_sigact.k_sa_handler = act->sa_handler;
- k_sigact.sa_mask = act->sa_mask.__val[0];
- k_sigact.sa_flags = act->sa_flags;
-# ifdef HAVE_SA_RESTORER
- k_sigact.sa_restorer = act->sa_restorer;
-# endif
- }
- result = INLINE_SYSCALL (sigaction, 3, sig,
- act ? __ptrvalue (&k_sigact) : NULL,
- oact ? __ptrvalue (&k_osigact) : NULL);
- if (oact && result >= 0)
- {
- oact->sa_handler = k_osigact.k_sa_handler;
- oact->sa_mask.__val[0] = k_osigact.sa_mask;
- oact->sa_flags = k_osigact.sa_flags;
+
+#else
+extern void restore (void) __asm__ ("__restore") attribute_hidden;
+
+/* If ACT is not NULL, change the action for SIG to *ACT.
+ If OACT is not NULL, put the old action for SIG in *OACT. */
+int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
+{
+ int result;
+ struct old_kernel_sigaction kact, koact;
+
+ if (act) {
+ kact.k_sa_handler = act->sa_handler;
+ kact.sa_mask = act->sa_mask.__val[0];
+ kact.sa_flags = act->sa_flags;
# ifdef HAVE_SA_RESTORER
# if _MIPS_SIM == _ABIO32
- oact->sa_restorer = k_osigact.sa_restorer;
+ kact.sa_restorer = act->sa_restorer;
# else
- oact->sa_restorer = &restore;
+ kact.sa_restorer = &restore_rt;
# endif
# endif
}
- return result;
-#endif
+
+ result = __syscall_sigaction(sig, act ? __ptrvalue (&kact) : NULL,
+ oact ? __ptrvalue (&koact) : NULL);
+
+ if (result < 0) {
+ __set_errno(-result);
+ return -1;
+ }
+
+ if (oact) {
+ oact->sa_handler = koact.k_sa_handler;
+ oact->sa_mask.__val[0] = koact.sa_mask;
+ oact->sa_flags = koact.sa_flags;
+# ifdef HAVE_SA_RESTORER
+ oact->sa_restorer = koact.sa_restorer;
+# endif
+ }
+ return result;
}
+#endif
+
#ifndef LIBC_SIGACTION
libc_hidden_proto(sigaction)
weak_alias(__libc_sigaction,sigaction)
diff --git a/libc/sysdeps/linux/mips/sys/asm.h b/libc/sysdeps/linux/mips/sys/asm.h
index e961f3694..76f6af3e1 100644
--- a/libc/sysdeps/linux/mips/sys/asm.h
+++ b/libc/sysdeps/linux/mips/sys/asm.h
@@ -470,20 +470,4 @@ symbol = value
# define MTC0 dmtc0
#endif
-/* The MIPS archtectures do not have a uniform memory model. Particular
- platforms may provide additional guarantees - for instance, the R4000
- LL and SC instructions implicitly perform a SYNC, and the 4K promises
- strong ordering.
-
- However, in the absence of those guarantees, we must assume weak ordering
- and SYNC explicitly where necessary.
-
- Some obsolete MIPS processors may not support the SYNC instruction. This
- applies to "true" MIPS I processors; most of the processors which compile
- using MIPS I implement parts of MIPS II. */
-
-#ifndef MIPS_SYNC
-# define MIPS_SYNC sync
-#endif
-
#endif /* sys/asm.h */
diff --git a/libc/sysdeps/linux/mips/sys/regdef.h b/libc/sysdeps/linux/mips/sys/regdef.h
index 2d94130af..9d2c4c1c4 100644
--- a/libc/sysdeps/linux/mips/sys/regdef.h
+++ b/libc/sysdeps/linux/mips/sys/regdef.h
@@ -20,8 +20,6 @@
#ifndef _SYS_REGDEF_H
#define _SYS_REGDEF_H
-#include <sgidefs.h>
-
/*
* Symbolic register names for 32 bit ABI
*/
diff --git a/libc/sysdeps/linux/mips/sys/sysmips.h b/libc/sysdeps/linux/mips/sys/sysmips.h
index 7760c755a..6a63dc2b2 100644
--- a/libc/sysdeps/linux/mips/sys/sysmips.h
+++ b/libc/sysdeps/linux/mips/sys/sysmips.h
@@ -22,9 +22,17 @@
#include <features.h>
/*
- * Get the kernel definition for sysmips(2)
+ * Commands for the sysmips(2) call
+ *
+ * sysmips(2) is deprecated - though some existing software uses it.
+ * We only support the following commands. Sysmips exists for compatibility
+ * purposes only so new software should avoid it.
*/
-#include <asm/sysmips.h>
+#define SETNAME 1 /* set hostname */
+#define FLUSH_CACHE 3 /* writeback and invalidate caches */
+#define MIPS_FIXADE 7 /* control address error fixing */
+#define MIPS_RDNVRAM 10 /* read NVRAM */
+#define MIPS_ATOMIC_SET 2001 /* atomically set variable */
__BEGIN_DECLS
diff --git a/libc/sysdeps/linux/mips/sys/ucontext.h b/libc/sysdeps/linux/mips/sys/ucontext.h
index 90aa09a80..ac496f3d6 100644
--- a/libc/sysdeps/linux/mips/sys/ucontext.h
+++ b/libc/sysdeps/linux/mips/sys/ucontext.h
@@ -1,5 +1,5 @@
-/* Copyright (C) 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
+/* Copyright (C) 1997, 1998, 2000, 2003, 2004, 2006 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
@@ -16,143 +16,102 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
-/* System V/mips ABI compliant context switching support. */
-
+/* Don't rely on this, the interface is currently messed up and may need to
+ be broken to be fixed. */
#ifndef _SYS_UCONTEXT_H
#define _SYS_UCONTEXT_H 1
#include <features.h>
+#include <sgidefs.h>
#include <signal.h>
-/* Type for general register. */
-#if _MIPS_SIM == _MIPS_SIM_ABI32
-typedef __uint32_t greg_t;
-#else
-typedef __uint64_t greg_t;
-#endif
+/* We need the signal context definitions even if they are not used
+ included in <signal.h>. */
+#include <bits/sigcontext.h>
+
+/* Type for general register. Even in o32 we assume 64-bit registers,
+ like the kernel. */
+__extension__ typedef unsigned long long int greg_t;
/* Number of general registers. */
-#define NGREG 36
+#define NGREG 32
+#define NFPREG 32
/* Container for all general registers. */
typedef greg_t gregset_t[NGREG];
-/* Number of each register is the `gregset_t' array. */
-enum
-{
- CTX_R0 = 0,
-#define CTX_R0 CTX_R0
- CTX_AT = 1,
-#define CTX_AT CTX_AT
- CTX_V0 = 2,
-#define CTX_V0 CTX_V0
- CTX_V1 = 3,
-#define CTX_V1 CTX_V1
- CTX_A0 = 4,
-#define CTX_A0 CTX_A0
- CTX_A1 = 5,
-#define CTX_A1 CTX_A1
- CTX_A2 = 6,
-#define CTX_A2 CTX_A2
- CTX_A3 = 7,
-#define CTX_A3 CTX_A3
- CTX_T0 = 8,
-#define CTX_T0 CTX_T0
- CTX_T1 = 9,
-#define CTX_T1 CTX_T1
- CTX_T2 = 10,
-#define CTX_T2 CTX_T2
- CTX_T3 = 11,
-#define CTX_T3 CTX_T3
- CTX_T4 = 12,
-#define CTX_T4 CTX_T4
- CTX_T5 = 13,
-#define CTX_T5 CTX_T5
- CTX_T6 = 14,
-#define CTX_T6 CTX_T6
- CTX_T7 = 15,
-#define CTX_T7 CTX_T7
- CTX_S0 = 16,
-#define CTX_S0 CTX_S0
- CTX_S1 = 17,
-#define CTX_S1 CTX_S1
- CTX_S2 = 18,
-#define CTX_S2 CTX_S2
- CTX_S3 = 19,
-#define CTX_S3 CTX_S3
- CTX_S4 = 20,
-#define CTX_S4 CTX_S4
- CTX_S5 = 21,
-#define CTX_S5 CTX_S5
- CTX_S6 = 22,
-#define CTX_S6 CTX_S6
- CTX_S7 = 23,
-#define CTX_S7 CTX_S7
- CTX_T8 = 24,
-#define CTX_T8 CTX_T8
- CTX_T9 = 25,
-#define CTX_T9 CTX_T9
- CTX_K0 = 26,
-#define CTX_K0 CTX_K0
- CTX_K1 = 27,
-#define CTX_K1 CTX_K1
- CTX_GP = 28,
-#define CTX_GP CTX_GP
- CTX_SP = 29,
-#define CTX_SP CTX_SP
- CTX_S8 = 30,
-#define CTX_S8 CTX_S8
- CTX_RA = 31,
-#define CTX_RA CTX_RA
- CTX_MDLO = 32,
-#define CTX_MDLO CTX_MDLO
- CTX_MDHI = 33,
-#define CTX_MDHI CTX_MDHI
- CTX_CAUSE = 34,
-#define CTX_CAUSE CTX_CAUSE
- CTX_EPC = 35,
-#define CTX_EPC CTX_EPC
-};
-
-/* Structure to describe FPU registers. */
-typedef struct fpregset
-{
- union
- {
-#if _MIPS_SIM == _MIPS_SIM_ABI32
- double fp_dregs[16];
- float fp_fregs[32];
- unsigned int fp_regs[32];
-#else
- double fp_dregs[32];
- /* float fp_fregs[32]; */
- __uint64_t fp_regs[32];
-#endif
- } fp_r;
- unsigned int fp_csr;
- unsigned int fp_pad;
+/* Container for all FPU registers. */
+typedef struct fpregset {
+ union {
+ double fp_dregs[NFPREG];
+ struct {
+ float _fp_fregs;
+ unsigned int _fp_pad;
+ } fp_fregs[NFPREG];
+ } fp_r;
} fpregset_t;
+
/* Context to describe whole processor state. */
+#if _MIPS_SIM == _ABIO32
+/* Earlier versions of glibc for mips had an entirely different
+ definition of mcontext_t, that didn't even resemble the
+ corresponding kernel data structure. Since all legitimate uses of
+ ucontext_t in glibc mustn't have accessed anything beyond
+ uc_mcontext and, even then, taking a pointer to it, casting it to
+ sigcontext_t, and accessing it as such, which is what it has always
+ been, this can still be rectified. Fortunately, makecontext,
+ [gs]etcontext et all have never been implemented. */
typedef struct
-{
- gregset_t gpregs;
- fpregset_t fpregs;
-} mcontext_t;
+ {
+ unsigned int regmask;
+ unsigned int status;
+ greg_t pc;
+ gregset_t gregs;
+ fpregset_t fpregs;
+ unsigned int fp_owned;
+ unsigned int fpc_csr;
+ unsigned int fpc_eir;
+ unsigned int used_math;
+ unsigned int dsp;
+ greg_t mdhi;
+ greg_t mdlo;
+ unsigned long hi1;
+ unsigned long lo1;
+ unsigned long hi2;
+ unsigned long lo2;
+ unsigned long hi3;
+ unsigned long lo3;
+ } mcontext_t;
+#else
+typedef struct
+ {
+ gregset_t gregs;
+ fpregset_t fpregs;
+ greg_t mdhi;
+ greg_t hi1;
+ greg_t hi2;
+ greg_t hi3;
+ greg_t mdlo;
+ greg_t lo1;
+ greg_t lo2;
+ greg_t lo3;
+ greg_t pc;
+ unsigned int fpc_csr;
+ unsigned int used_math;
+ unsigned int dsp;
+ unsigned int reserved;
+ } mcontext_t;
+#endif
/* Userlevel context. */
typedef struct ucontext
-{
-#if _MIPS_SIM == _MIPS_SIM_ABI32
- unsigned long int uc_flags;
-#else
- __uint64_t uc_flags;
-#endif
- struct ucontext *uc_link;
- __sigset_t uc_sigmask;
- stack_t uc_stack;
- mcontext_t uc_mcontext;
- int uc_filler[48];
-} ucontext_t;
+ {
+ unsigned long int uc_flags;
+ struct ucontext *uc_link;
+ stack_t uc_stack;
+ mcontext_t uc_mcontext;
+ __sigset_t uc_sigmask;
+ } ucontext_t;
#endif /* sys/ucontext.h */
diff --git a/libc/sysdeps/linux/mips/sys/user.h b/libc/sysdeps/linux/mips/sys/user.h
index 8e6b1e1ef..5d880943e 100644
--- a/libc/sysdeps/linux/mips/sys/user.h
+++ b/libc/sysdeps/linux/mips/sys/user.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004 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
@@ -19,6 +19,8 @@
#ifndef _SYS_USER_H
#define _SYS_USER_H 1
+#include <sgidefs.h>
+
/* The whole purpose of this file is for GDB and GDB only. Don't read
too much into it. Don't use it for anything other than GDB unless
you know what you are doing. */
@@ -30,7 +32,7 @@
instead of included separately, doesn't change in any way the
licensing status of a program that includes user.h. Since this is
for gdb alone, and gdb is GPLed, no surprises here. */
-#if _MIPS_SIM == _MIPS_SIM_ABI32
+#if _MIPS_SIM == _ABIO32
/*
* Various register offset definitions for debuggers, core file
* examiners and whatnot.
@@ -98,7 +100,7 @@
#endif /* __ASM_MIPS_REG_H */
-#else /* _MIPS_SIM != _MIPS_SIM_ABI32 */
+#else /* _MIPS_SIM != _ABIO32 */
/*
* Various register offset definitions for debuggers, core file
@@ -168,9 +170,9 @@
#endif /* _ASM_REG_H */
-#endif /* _MIPS_SIM != _MIPS_SIM_ABI32 */
+#endif /* _MIPS_SIM != _ABIO32 */
-#if _MIPS_SIM == _MIPS_SIM_ABI32
+#if _MIPS_SIM == _ABIO32
struct user
{
diff --git a/libc/sysdeps/linux/mips/syscall.S b/libc/sysdeps/linux/mips/syscall.S
index 683529596..ff6f3d1b4 100644
--- a/libc/sysdeps/linux/mips/syscall.S
+++ b/libc/sysdeps/linux/mips/syscall.S
@@ -29,8 +29,10 @@
.type syscall,@function
.ent syscall
syscall:
+#ifdef __PIC__
+ SETUP_GP
+#endif
.set noreorder
- .cpload t9;
move v0, a0 /* Load system call number from first arg. */
move a0, a1 /* Move the next three args up a register. */
move a1, a2
@@ -68,7 +70,9 @@ syscall:
move a0,v0 /* Pass return val to C function. */
#ifdef __PIC__
+ SETUP_GP64(v0, syscall)
PTR_LA t9, __syscall_error
+ RESTORE_GP64
jr t9
#else
j __syscall_error
diff --git a/libc/sysdeps/linux/mips/sysmips.c b/libc/sysdeps/linux/mips/sysmips.c
index 69b462c33..020f02dd3 100644
--- a/libc/sysdeps/linux/mips/sysmips.c
+++ b/libc/sysdeps/linux/mips/sysmips.c
@@ -2,4 +2,6 @@
#include <sys/syscall.h>
#include <sys/sysmips.h>
+#ifdef __NR_sysmips
_syscall4(int, sysmips, const int, cmd, const long, arg1, const int, arg2, const int, arg3);
+#endif