summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-07-22 17:10:30 +0000
committerEric Andersen <andersen@codepoet.org>2002-07-22 17:10:30 +0000
commit72677cc3d8403da4b35c99617352bde347780222 (patch)
tree7d5d29cc3f49a1b69f90ca9ae6fbf3f61e81b1ce /libc
parent980e7850176c30ba374a706298b2865f387ec2ae (diff)
Rework syscall handling. Rewrite syscall handlers for x86 and ARM.
Prepare to kill the UNIFIED_SYSCALL option and instead have it be a per arch thing that is either enabled or not for that arch. -Erik
Diffstat (limited to 'libc')
-rw-r--r--libc/sysdeps/linux/alpha/bits/syscalls.h194
-rw-r--r--libc/sysdeps/linux/arm/bits/syscalls.h201
-rw-r--r--libc/sysdeps/linux/common/Makefile2
-rw-r--r--libc/sysdeps/linux/common/ftruncate64.c13
-rw-r--r--libc/sysdeps/linux/common/getcwd.c10
-rw-r--r--libc/sysdeps/linux/common/getpagesize.c2
-rw-r--r--libc/sysdeps/linux/common/pread_write.c160
-rw-r--r--libc/sysdeps/linux/common/syscalls.c88
-rw-r--r--libc/sysdeps/linux/common/truncate64.c12
-rw-r--r--libc/sysdeps/linux/h8300/bits/syscalls.h13
-rw-r--r--libc/sysdeps/linux/i386/bits/syscalls.h265
-rw-r--r--libc/sysdeps/linux/i960/bits/syscalls.h13
-rw-r--r--libc/sysdeps/linux/m68k/bits/syscalls.h13
-rw-r--r--libc/sysdeps/linux/mips/Makefile2
-rw-r--r--libc/sysdeps/linux/mips/bits/syscalls.h12
-rw-r--r--libc/sysdeps/linux/mips/setjmp_aux.c2
-rw-r--r--libc/sysdeps/linux/powerpc/bits/syscalls.h170
-rw-r--r--libc/sysdeps/linux/sh/bits/syscalls.h111
-rw-r--r--libc/sysdeps/linux/sparc/bits/syscalls.h13
-rw-r--r--libc/sysdeps/linux/v850/bits/syscalls.h13
20 files changed, 423 insertions, 886 deletions
diff --git a/libc/sysdeps/linux/alpha/bits/syscalls.h b/libc/sysdeps/linux/alpha/bits/syscalls.h
index e1ee1b95c..da6a6d43e 100644
--- a/libc/sysdeps/linux/alpha/bits/syscalls.h
+++ b/libc/sysdeps/linux/alpha/bits/syscalls.h
@@ -1,187 +1,15 @@
-/* Unlike the asm/unistd.h kernel header file (which this is partly based on),
- * this file must be able to cope with PIC and non-PIC code. For some arches
- * there is no difference. For x86 (which has far too few registers) there is
- * a difference. Regardless, including asm/unistd.h is hereby officially
- * forbidden. Don't do it. It is bad for you. */
+#ifndef _BITS_SYSCALLS_H
+#define _BITS_SYSCALLS_H
+#ifndef _SYSCALL_H
+# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."
+#endif
+#include <features.h>
-#define _syscall_return(type) \
- return (_sc_err ? errno = _sc_ret, _sc_ret = -1L : 0), (type) _sc_ret
-
-#define _syscall_clobbers \
- "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", \
- "$22", "$23", "$24", "$25", "$27", "$28" \
-
-#define _syscall0(type, name) \
-type name(void) \
-{ \
- long _sc_ret, _sc_err; \
- { \
- register long _sc_0 __asm__("$0"); \
- register long _sc_19 __asm__("$19"); \
- \
- _sc_0 = __NR_##name; \
- __asm__("callsys # %0 %1 %2" \
- : "=r"(_sc_0), "=r"(_sc_19) \
- : "0"(_sc_0) \
- : _syscall_clobbers); \
- _sc_ret = _sc_0, _sc_err = _sc_19; \
- } \
- _syscall_return(type); \
-}
-
-#define _syscall1(type,name,type1,arg1) \
-type name(type1 arg1) \
-{ \
- long _sc_ret, _sc_err; \
- { \
- register long _sc_0 __asm__("$0"); \
- register long _sc_16 __asm__("$16"); \
- register long _sc_19 __asm__("$19"); \
- \
- _sc_0 = __NR_##name; \
- _sc_16 = (long) (arg1); \
- __asm__("callsys # %0 %1 %2 %3" \
- : "=r"(_sc_0), "=r"(_sc_19) \
- : "0"(_sc_0), "r"(_sc_16) \
- : _syscall_clobbers); \
- _sc_ret = _sc_0, _sc_err = _sc_19; \
- } \
- _syscall_return(type); \
-}
-
-#define _syscall2(type,name,type1,arg1,type2,arg2) \
-type name(type1 arg1,type2 arg2) \
-{ \
- long _sc_ret, _sc_err; \
- { \
- register long _sc_0 __asm__("$0"); \
- register long _sc_16 __asm__("$16"); \
- register long _sc_17 __asm__("$17"); \
- register long _sc_19 __asm__("$19"); \
- \
- _sc_0 = __NR_##name; \
- _sc_16 = (long) (arg1); \
- _sc_17 = (long) (arg2); \
- __asm__("callsys # %0 %1 %2 %3 %4" \
- : "=r"(_sc_0), "=r"(_sc_19) \
- : "0"(_sc_0), "r"(_sc_16), "r"(_sc_17) \
- : _syscall_clobbers); \
- _sc_ret = _sc_0, _sc_err = _sc_19; \
- } \
- _syscall_return(type); \
-}
-
-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
-type name(type1 arg1,type2 arg2,type3 arg3) \
-{ \
- long _sc_ret, _sc_err; \
- { \
- register long _sc_0 __asm__("$0"); \
- register long _sc_16 __asm__("$16"); \
- register long _sc_17 __asm__("$17"); \
- register long _sc_18 __asm__("$18"); \
- register long _sc_19 __asm__("$19"); \
- \
- _sc_0 = __NR_##name; \
- _sc_16 = (long) (arg1); \
- _sc_17 = (long) (arg2); \
- _sc_18 = (long) (arg3); \
- __asm__("callsys # %0 %1 %2 %3 %4 %5" \
- : "=r"(_sc_0), "=r"(_sc_19) \
- : "0"(_sc_0), "r"(_sc_16), "r"(_sc_17), \
- "r"(_sc_18) \
- : _syscall_clobbers); \
- _sc_ret = _sc_0, _sc_err = _sc_19; \
- } \
- _syscall_return(type); \
-}
-
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-{ \
- long _sc_ret, _sc_err; \
- { \
- register long _sc_0 __asm__("$0"); \
- register long _sc_16 __asm__("$16"); \
- register long _sc_17 __asm__("$17"); \
- register long _sc_18 __asm__("$18"); \
- register long _sc_19 __asm__("$19"); \
- \
- _sc_0 = __NR_##name; \
- _sc_16 = (long) (arg1); \
- _sc_17 = (long) (arg2); \
- _sc_18 = (long) (arg3); \
- _sc_19 = (long) (arg4); \
- __asm__("callsys # %0 %1 %2 %3 %4 %5 %6" \
- : "=r"(_sc_0), "=r"(_sc_19) \
- : "0"(_sc_0), "r"(_sc_16), "r"(_sc_17), \
- "r"(_sc_18), "1"(_sc_19) \
- : _syscall_clobbers); \
- _sc_ret = _sc_0, _sc_err = _sc_19; \
- } \
- _syscall_return(type); \
-}
-
-#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) \
-{ \
- long _sc_ret, _sc_err; \
- { \
- register long _sc_0 __asm__("$0"); \
- register long _sc_16 __asm__("$16"); \
- register long _sc_17 __asm__("$17"); \
- register long _sc_18 __asm__("$18"); \
- register long _sc_19 __asm__("$19"); \
- register long _sc_20 __asm__("$20"); \
- \
- _sc_0 = __NR_##name; \
- _sc_16 = (long) (arg1); \
- _sc_17 = (long) (arg2); \
- _sc_18 = (long) (arg3); \
- _sc_19 = (long) (arg4); \
- _sc_20 = (long) (arg5); \
- __asm__("callsys # %0 %1 %2 %3 %4 %5 %6 %7" \
- : "=r"(_sc_0), "=r"(_sc_19) \
- : "0"(_sc_0), "r"(_sc_16), "r"(_sc_17), \
- "r"(_sc_18), "1"(_sc_19), "r"(_sc_20) \
- : _syscall_clobbers); \
- _sc_ret = _sc_0, _sc_err = _sc_19; \
- } \
- _syscall_return(type); \
-}
-
-#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)\
-{ \
- long _sc_ret, _sc_err; \
- { \
- register long _sc_0 __asm__("$0"); \
- register long _sc_16 __asm__("$16"); \
- register long _sc_17 __asm__("$17"); \
- register long _sc_18 __asm__("$18"); \
- register long _sc_19 __asm__("$19"); \
- register long _sc_20 __asm__("$20"); \
- register long _sc_21 __asm__("$21"); \
- \
- _sc_0 = __NR_##name; \
- _sc_16 = (long) (arg1); \
- _sc_17 = (long) (arg2); \
- _sc_18 = (long) (arg3); \
- _sc_19 = (long) (arg4); \
- _sc_20 = (long) (arg5); \
- _sc_21 = (long) (arg6); \
- __asm__("callsys # %0 %1 %2 %3 %4 %5 %6 %7 %8" \
- : "=r"(_sc_0), "=r"(_sc_19) \
- : "0"(_sc_0), "r"(_sc_16), "r"(_sc_17), \
- "r"(_sc_18), "1"(_sc_19), "r"(_sc_20), "r"(_sc_21) \
- : _syscall_clobbers); \
- _sc_ret = _sc_0, _sc_err = _sc_19; \
- } \
- _syscall_return(type); \
-}
-
+/* Do something very evil for now. Until we create our own syscall
+ * macros, short circuit bits/syscall.h and use asm/unistd.h instead */
+#define _BITS_SYSCALL_H
+#include <asm/unistd.h>
+#endif /* _BITS_SYSCALLS_H */
diff --git a/libc/sysdeps/linux/arm/bits/syscalls.h b/libc/sysdeps/linux/arm/bits/syscalls.h
index 42b20ffea..0bf2af4d5 100644
--- a/libc/sysdeps/linux/arm/bits/syscalls.h
+++ b/libc/sysdeps/linux/arm/bits/syscalls.h
@@ -1,119 +1,120 @@
-/* Unlike the asm/unistd.h kernel header file (which this is partly based on),
- * this file must be able to cope with PIC and non-PIC code. For some arches
- * there is no difference. For x86 (which has far too few registers) there is
- * a difference. Regardless, including asm/unistd.h is hereby officially
- * forbidden. Don't do it. It is bad for you. */
-
-#include <features.h>
-
-// TODO -- Add support for __UCLIBC_USE_UNIFIED_SYSCALL__
-
+#ifndef _BITS_SYSCALLS_H
+#define _BITS_SYSCALLS_H
+#ifndef _SYSCALL_H
+# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."
+#endif
-#define __sys2(x) #x
-#define __sys1(x) __sys2(x)
+/* 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/syscall.h>
-#ifndef __syscall
-#define __syscall(name) "swi\t" __sys1(__NR_##name) "\n\t"
+#ifndef __set_errno
+# define __set_errno(val) (*__errno_location ()) = (val)
+#endif
+#ifndef SYS_ify
+# define SYS_ify(syscall_name) (__NR_##syscall_name)
#endif
-#define __syscall_return(type, res) \
-do { \
- if ((unsigned long)(res) >= (unsigned long)(-125)) { \
- errno = -(res); \
- res = -1; \
- } \
- return (type) (res); \
-} while (0)
+/*
+ Some of the sneaky macros in the code were taken from
+ glibc-2.2.5/sysdeps/unix/sysv/linux/arm/sysdep.h
+*/
+#ifndef __ASSEMBLER__
-#define _syscall0(type,name) \
-type name(void) { \
- long __res; \
- __asm__ __volatile__ ( \
- __syscall(name) \
- "mov %0,r0" \
- :"=r" (__res) : : "r0","lr"); \
- __syscall_return(type,__res); \
+#undef _syscall0
+#define _syscall0(type,name) \
+type name(void) \
+{ \
+return (type) (INLINE_SYSCALL(name, 0)); \
}
-#define _syscall1(type,name,type1,arg1) \
-type name(type1 arg1) { \
- long __res; \
- __asm__ __volatile__ ( \
- "mov\tr0,%1\n\t" \
- __syscall(name) \
- "mov %0,r0" \
- : "=r" (__res) \
- : "r" ((long)(arg1)) \
- : "r0","lr"); \
- __syscall_return(type,__res); \
+#undef _syscall1
+#define _syscall1(type,name,type1,arg1) \
+type name(type1 arg1) \
+{ \
+return (type) (INLINE_SYSCALL(name, 1, arg1)); \
}
-#define _syscall2(type,name,type1,arg1,type2,arg2) \
-type name(type1 arg1,type2 arg2) { \
- long __res; \
- __asm__ __volatile__ ( \
- "mov\tr0,%1\n\t" \
- "mov\tr1,%2\n\t" \
- __syscall(name) \
- "mov\t%0,r0" \
- : "=r" (__res) \
- : "r" ((long)(arg1)),"r" ((long)(arg2)) \
- : "r0","r1","lr"); \
- __syscall_return(type,__res); \
+#undef _syscall2
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+type name(type1 arg1,type2 arg2) \
+{ \
+return (type) (INLINE_SYSCALL(name, 2, arg1, arg2)); \
}
-
-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
-type name(type1 arg1,type2 arg2,type3 arg3) { \
- long __res; \
- __asm__ __volatile__ ( \
- "mov\tr0,%1\n\t" \
- "mov\tr1,%2\n\t" \
- "mov\tr2,%3\n\t" \
- __syscall(name) \
- "mov\t%0,r0" \
- : "=r" (__res) \
- : "r" ((long)(arg1)),"r" ((long)(arg2)),"r" ((long)(arg3)) \
- : "r0","r1","r2","lr"); \
- __syscall_return(type,__res); \
+#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) { \
- long __res; \
- __asm__ __volatile__ ( \
- "mov\tr0,%1\n\t" \
- "mov\tr1,%2\n\t" \
- "mov\tr2,%3\n\t" \
- "mov\tr3,%4\n\t" \
- __syscall(name) \
- "mov\t%0,r0" \
- : "=r" (__res) \
- : "r" ((long)(arg1)),"r" ((long)(arg2)), \
- "r" ((long)(arg3)),"r" ((long)(arg4)) \
- : "r0","r1","r2","r3","lr"); \
- __syscall_return(type,__res); \
-}
+#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) { \
- long __res; \
- __asm__ __volatile__ ( \
- "mov\tr0,%1\n\t" \
- "mov\tr1,%2\n\t" \
- "mov\tr2,%3\n\t" \
- "mov\tr3,%4\n\t" \
- "mov\tr4,%5\n\t" \
- __syscall(name) \
- "mov\t%0,r0" \
- : "=r" (__res) \
- : "r" ((long)(arg1)),"r" ((long)(arg2)), \
- "r" ((long)(arg3)),"r" ((long)(arg4)), \
- "r" ((long)(arg5)) \
- : "r0","r1","r2","r3","r4","lr"); \
- __syscall_return(type,__res); \
+#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 INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) \
+ ({ unsigned int _sys_result; \
+ { \
+ register int _a1 asm ("a1"); \
+ LOAD_ARGS_##nr (args) \
+ asm volatile ("swi %1 @ syscall " #name \
+ : "=r" (_a1) \
+ : "i" (SYS_ify(name)) ASM_ARGS_##nr \
+ : "a1", "memory"); \
+ _sys_result = _a1; \
+ } \
+ if (_sys_result >= (unsigned int) -4095) \
+ { \
+ __set_errno (-_sys_result); \
+ _sys_result = (unsigned int) -1; \
+ } \
+ (int) _sys_result; })
+
+#define LOAD_ARGS_0()
+#define ASM_ARGS_0
+#define LOAD_ARGS_1(a1) \
+ _a1 = (int) (a1); \
+ LOAD_ARGS_0 ()
+#define ASM_ARGS_1 ASM_ARGS_0, "r" (_a1)
+#define LOAD_ARGS_2(a1, a2) \
+ register int _a2 asm ("a2") = (int) (a2); \
+ LOAD_ARGS_1 (a1)
+#define ASM_ARGS_2 ASM_ARGS_1, "r" (_a2)
+#define LOAD_ARGS_3(a1, a2, a3) \
+ register int _a3 asm ("a3") = (int) (a3); \
+ LOAD_ARGS_2 (a1, a2)
+#define ASM_ARGS_3 ASM_ARGS_2, "r" (_a3)
+#define LOAD_ARGS_4(a1, a2, a3, a4) \
+ register int _a4 asm ("a4") = (int) (a4); \
+ LOAD_ARGS_3 (a1, a2, a3)
+#define ASM_ARGS_4 ASM_ARGS_3, "r" (_a4)
+#define LOAD_ARGS_5(a1, a2, a3, a4, a5) \
+ register int _v1 asm ("v1") = (int) (a5); \
+ LOAD_ARGS_4 (a1, a2, a3, a4)
+#define ASM_ARGS_5 ASM_ARGS_4, "r" (_v1)
+#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \
+ register int _v2 asm ("v2") = (int) (a6); \
+ LOAD_ARGS_5 (a1, a2, a3, a4, a5)
+#define ASM_ARGS_6 ASM_ARGS_5, "r" (_v2)
+#define LOAD_ARGS_7(a1, a2, a3, a4, a5, a6, a7) \
+ register int _v3 asm ("v3") = (int) (a7); \
+ LOAD_ARGS_6 (a1, a2, a3, a4, a5, a6)
+#define ASM_ARGS_7 ASM_ARGS_6, "r" (_v3)
+
+#endif /* __ASSEMBLER__ */
+#endif /* _BITS_SYSCALLS_H */
diff --git a/libc/sysdeps/linux/common/Makefile b/libc/sysdeps/linux/common/Makefile
index 3e6a5136d..b9a8319cb 100644
--- a/libc/sysdeps/linux/common/Makefile
+++ b/libc/sysdeps/linux/common/Makefile
@@ -34,7 +34,7 @@ CSRC= waitpid.c statfix.c getdnnm.c gethstnm.c getcwd.c \
wait3.c setpgrp.c getdtablesize.c create_module.c ptrace.c \
cmsg_nxthdr.c statfix64.c longjmp.c open64.c ftruncate64.c \
truncate64.c getrlimit64.c setrlimit64.c creat64.c mmap64.c \
- pread_write.c
+ llseek.c pread_write.c _exit.c mknod.c setuid.c sync.c
ifneq ($(strip $(EXCLUDE_BRK)),true)
CSRC+=sbrk.c
endif
diff --git a/libc/sysdeps/linux/common/ftruncate64.c b/libc/sysdeps/linux/common/ftruncate64.c
index 01cdcd7d3..fb95450c1 100644
--- a/libc/sysdeps/linux/common/ftruncate64.c
+++ b/libc/sysdeps/linux/common/ftruncate64.c
@@ -20,20 +20,23 @@
#include <sys/syscall.h>
#if defined __UCLIBC_HAVE_LFS__ && defined __NR_ftruncate64
+#ifndef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) __syscall_ftruncate64 (args)
+#define __NR___syscall_ftruncate64 __NR_ftruncate64
+static inline _syscall3(int, __syscall_ftruncate64, int, fd, int, high_length, int, low_length);
+#endif
+
+
#if __WORDSIZE == 64
/* For a 64 bit machine, life is simple... */
_syscall2(int, ftruncate64, int, fd, __off64_t, length);
#elif __WORDSIZE == 32
-#define __NR___ftruncate64 __NR_ftruncate64
-static inline _syscall3(int, __ftruncate64, int, fd,
- uint32_t, length_first_half,
- uint32_t, length_second_half);
/* The exported ftruncate64 function. */
int ftruncate64 (int fd, __off64_t length)
{
uint32_t low = length & 0xffffffff;
uint32_t high = length >> 32;
- return __ftruncate64(fd, __LONG_LONG_PAIR (high, low));
+ return INLINE_SYSCALL(ftruncate64, 3, fd, __LONG_LONG_PAIR (high, low));
}
#else
#error Your machine is not 64 bit or 32 bit, I am dazed and confused.
diff --git a/libc/sysdeps/linux/common/getcwd.c b/libc/sysdeps/linux/common/getcwd.c
index 1ec00a36e..9cdd84b47 100644
--- a/libc/sysdeps/linux/common/getcwd.c
+++ b/libc/sysdeps/linux/common/getcwd.c
@@ -8,8 +8,12 @@
#include <sys/syscall.h>
#ifdef __NR_getcwd
-#define __NR___getcwd __NR_getcwd
-static inline _syscall2(int, __getcwd, char *, buf, unsigned long, size);
+
+#ifndef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) __syscall_getcwd (args)
+#define __NR___syscall_getcwd __NR_getcwd
+static inline _syscall2(int, __syscall_getcwd, char *, buf, unsigned long, size);
+#endif
char *getcwd(char *buf, int size)
{
@@ -31,7 +35,7 @@ char *getcwd(char *buf, int size)
if (buf == NULL)
return NULL;
}
- ret = __getcwd(buf, size);
+ ret = INLINE_SYSCALL(getcwd, 2, buf, size);
if (ret < 0) {
if (allocbuf) {
free(allocbuf);
diff --git a/libc/sysdeps/linux/common/getpagesize.c b/libc/sysdeps/linux/common/getpagesize.c
index 362dd7b2b..859338003 100644
--- a/libc/sysdeps/linux/common/getpagesize.c
+++ b/libc/sysdeps/linux/common/getpagesize.c
@@ -21,7 +21,7 @@
#include <sys/param.h>
/* Return the system page size. */
-int __getpagesize()
+int __getpagesize(void)
{
#ifdef EXEC_PAGESIZE
return EXEC_PAGESIZE;
diff --git a/libc/sysdeps/linux/common/pread_write.c b/libc/sysdeps/linux/common/pread_write.c
index 4aa1fdf7e..61d1bee4f 100644
--- a/libc/sysdeps/linux/common/pread_write.c
+++ b/libc/sysdeps/linux/common/pread_write.c
@@ -23,41 +23,72 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#define _GNU_SOURCE
+#define _LARGEFILE64_SOURCE
#include <features.h>
-#if defined _FILE_OFFSET_BITS && _FILE_OFFSET_BITS != 64
-#undef _FILE_OFFSET_BITS
-#define _FILE_OFFSET_BITS 64
-#endif
-#ifndef __USE_LARGEFILE64
-# define __USE_LARGEFILE64 1
-#endif
+#undef __OPTIMIZE__
/* We absolutely do _NOT_ want interfaces silently
- * renamed under us or very bad things will happen... */
+ * * * 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>
-#define _XOPEN_SOURCE 500
#include <unistd.h>
#ifdef __NR_pread
-#define __NR___syscall_pread __NR_pread
-static inline _syscall5(ssize_t, __syscall_pread, int, fd, void *, buf, size_t, count,
- __off_t, offset_hi, __off_t, offset_lo);
+#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_HAVE_LFS__
+
+#ifndef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) __syscall_pread (args)
+#define __NR___syscall_pread __NR_pread
+static inline _syscall5(ssize_t, __syscall_pread, int, fd, void *, buf,
+ size_t, count, off_t, offset_hi, off_t, offset_lo);
#endif
+ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset)
+{
+ return(INLINE_SYSCALL (pread, 5, fd, buf,
+ count, __LONG_LONG_PAIR ((off_t) (offset >> 32), (off_t) (offset & 0xffffffff))));
+}
+weak_alias (__libc_pread64, pread64)
+#endif /* __UCLIBC_HAVE_LFS__ */
+#endif /* __NR_pread */
+
+
#ifdef __NR_pwrite
-#define __NR___syscall_pwrite __NR_pwrite
-static inline _syscall5(ssize_t, __syscall_pwrite, int, fd, const void *, buf, size_t, count,
- __off_t, offset_hi, __off_t, offset_lo);
+#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)
+#if defined __UCLIBC_HAVE_LFS__
+
+#ifndef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) __syscall_write (args)
+#define __NR___syscall_write __NR_write
+static inline _syscall5(ssize_t, __syscall_write, int, fd, const void *, buf,
+ size_t, count, off_t, offset_hi, off_t, offset_lo);
#endif
+ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset)
+{
+ return(INLINE_SYSCALL (pwrite, 5, fd, buf,
+ count, __LONG_LONG_PAIR ((off_t) (offset >> 32), (off_t) (offset & 0xffffffff))));
+}
+weak_alias (__libc_pwrite64, pwrite64)
+#endif /* __UCLIBC_HAVE_LFS__ */
+#endif /* __NR_pwrite */
+
+
+#if ! defined __NR_pread || ! defined __NR_pwrite
static ssize_t __fake_pread_write(int fd, void *buf,
- size_t count, __off_t offset, int do_pwrite)
+ size_t count, off_t offset, int do_pwrite)
{
int save_errno;
ssize_t result;
@@ -69,7 +100,7 @@ static ssize_t __fake_pread_write(int fd, void *buf,
return -1;
/* Set to wanted position. */
- if (lseek (fd, offset, SEEK_SET) == (__off_t) -1)
+ if (lseek (fd, offset, SEEK_SET) == (off_t) -1)
return -1;
if (do_pwrite==1) {
@@ -83,7 +114,7 @@ static ssize_t __fake_pread_write(int fd, void *buf,
/* Now we have to restore the position. If this fails we
* have to return this as an error. */
save_errno = errno;
- if (lseek(fd, old_offset, SEEK_SET) == (__off_t) -1)
+ if (lseek(fd, old_offset, SEEK_SET) == (off_t) -1)
{
if (result == -1)
__set_errno(save_errno);
@@ -93,47 +124,6 @@ static ssize_t __fake_pread_write(int fd, void *buf,
return(result);
}
-ssize_t __libc_pread(int fd, void *buf, size_t count, __off_t offset)
-{
-#ifndef __NR_pread
- return(__fake_pread_write(fd, buf, count, offset, 0));
-#else
- ssize_t result;
-
- /* First try the syscall. */
- result = __syscall_pread(fd, buf, count, __LONG_LONG_PAIR(0, offset));
-
- /* Bummer. Syscall failed or is missing. Fake it */
- if (result == -1 && errno == ENOSYS) {
- result = __fake_pread_write(fd, buf, count, offset, 0);
- }
-#endif
- return result;
-}
-weak_alias (__libc_pread, pread)
-
-ssize_t __libc_pwrite(int fd, const void *buf, size_t count, __off_t offset)
-{
-#ifndef __NR_pwrite
- return(__fake_pread_write(fd, buf, count, offset, 1));
-#else
- ssize_t result;
-
- /* First try the syscall. */
- result = __syscall_pwrite(fd, buf, count, __LONG_LONG_PAIR(0, offset));
-
- /* Bummer. Syscall failed or is missing. Fake it */
- if (result == -1 && errno == ENOSYS) {
- result = __fake_pread_write(fd, (void*)buf, count, offset, 1);
- }
-#endif
- return result;
-}
-weak_alias (__libc_pwrite, pwrite)
-
-
-
-
#if defined __UCLIBC_HAVE_LFS__
static ssize_t __fake_pread_write64(int fd, void *buf,
size_t count, off64_t offset, int do_pwrite)
@@ -169,45 +159,39 @@ static ssize_t __fake_pread_write64(int fd, void *buf,
__set_errno (save_errno);
return result;
}
+#endif /* __UCLIBC_HAVE_LFS__ */
+#endif /* ! defined __NR_pread || ! defined __NR_pwrite */
+
+#ifndef __NR_pread
+ssize_t __libc_pread(int fd, void *buf, size_t count, off_t offset)
+{
+ return(__fake_pread_write(fd, buf, count, offset, 0));
+}
+weak_alias (__libc_pread, pread)
+#if defined __UCLIBC_HAVE_LFS__
ssize_t __libc_pread64(int fd, void *buf, size_t count, off64_t offset)
{
-#ifndef __NR_pread
return(__fake_pread_write64(fd, buf, count, offset, 0));
-#else
- ssize_t result;
- /* First try the syscall. */
- result = __syscall_pread(fd, buf, count,
- __LONG_LONG_PAIR((__off_t) (offset >> 32), (__off_t) (offset & 0xffffffff)));
-
- /* Bummer. Syscall failed or is missing. Fake it */
- if (result == -1 && errno == ENOSYS) {
- result = __fake_pread_write64(fd, buf, count, offset, 0);
- }
- return result;
-#endif
}
weak_alias (__libc_pread64, pread64)
+#endif /* __UCLIBC_HAVE_LFS__ */
+#endif /* ! __NR_pread */
+
+
+#ifndef __NR_pwrite
+ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset)
+{
+ return(__fake_pread_write(fd, buf, count, offset, 1));
+}
+weak_alias (__libc_pwrite, pwrite)
+#if defined __UCLIBC_HAVE_LFS__
ssize_t __libc_pwrite64(int fd, const void *buf, size_t count, off64_t offset)
{
-#ifndef __NR_pwrite
return(__fake_pread_write64(fd, (void*)buf, count, offset, 1));
-#else
- ssize_t result;
-
- /* First try the syscall. */
- result = __syscall_pwrite(fd, buf, count,
- __LONG_LONG_PAIR((__off_t) (offset >> 32), (__off_t) (offset & 0xffffffff)));
-
- /* Bummer. Syscall failed or is missing. Fake it */
- if (result == -1 && errno == ENOSYS) {
- result = __fake_pread_write64(fd, (void*)buf, count, offset, 1);
- }
- return result;
-#endif
}
weak_alias (__libc_pwrite64, pwrite64)
-
-#endif
+#endif /* __UCLIBC_HAVE_LFS__ */
+#endif /* ! __NR_pwrite */
diff --git a/libc/sysdeps/linux/common/syscalls.c b/libc/sysdeps/linux/common/syscalls.c
index 1b63c3dba..4acd0401c 100644
--- a/libc/sysdeps/linux/common/syscalls.c
+++ b/libc/sysdeps/linux/common/syscalls.c
@@ -22,18 +22,23 @@
*
*/
+#define _GNU_SOURCE
+#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>
+
//#define __NR_exit 1
-#ifdef L__exit
-/* Do not include unistd.h, so gcc doesn't whine about
- * _exit returning. It really doesn't return... */
-#define __NR__exit __NR_exit
-_syscall1(void, _exit, int, status);
-#endif
+//See _exit.c
//#define __NR_fork 2
#ifdef L___libc_fork
@@ -150,23 +155,7 @@ time_t time (time_t *t)
#endif
//#define __NR_mknod 14
-#ifdef L_mknod
-#include <unistd.h>
-extern int mknod(const char *pathname, mode_t mode, dev_t dev);
-_syscall3(int, mknod, const char *, pathname, mode_t, mode, dev_t, dev);
-
-int __xmknod (int version, const char * path, mode_t mode, dev_t *dev)
-{
- switch(version)
- {
- case 1:
- return mknod (path, mode, *dev);
- default:
- __set_errno(EINVAL);
- return -1;
- }
-}
-#endif
+//See mknod.c
//#define __NR_chmod 15
#ifdef L_chmod
@@ -198,10 +187,6 @@ _syscall3(int, lchown, const char *, path, uid_t, owner, gid_t, group);
#define __NR___libc_lseek __NR_lseek
_syscall3(__off_t, __libc_lseek, int, fildes, __off_t, offset, int, whence);
weak_alias(__libc_lseek, lseek)
-#ifndef __NR__llseek
-weak_alias(__libc_lseek, llseek)
-weak_alias(__libc_lseek, lseek64)
-#endif
#endif
//#define __NR_getpid 20
@@ -231,20 +216,7 @@ _syscall1(int, umount, const char *, specialfile);
#endif
//#define __NR_setuid 23
-#ifdef L___setuid
-#define __NR___setuid __NR_setuid
-#include <unistd.h>
-static inline
-_syscall1(int, __setuid, uid_t, uid);
-int setuid(uid_t uid)
-{
- if (uid == (uid_t) ~0) {
- __set_errno (EINVAL);
- return -1;
- }
- return(__setuid(uid));
-}
-#endif
+// See setuid.c
//#define __NR_getuid 24
#ifdef L_getuid
@@ -422,10 +394,7 @@ int nice (int incr)
//#define __NR_ftime 35
//#define __NR_sync 36
-#ifdef L_sync
-#include <unistd.h>
-_syscall0(void, sync);
-#endif
+//See sync.c
//#define __NR_kill 37
#ifdef L_kill
@@ -723,8 +692,8 @@ int setrlimit (__rlimit_resource_t resource, const struct rlimit *rlimits)
#else /* We don't need to wrap setrlimit */
#ifdef L_setrlimit
#include <unistd.h>
-#include <sys/resource.h>
-_syscall2(int, setrlimit, int, resource, const struct rlimit *, rlim);
+struct rlimit;
+_syscall2(int, setrlimit, unsigned int, resource, const struct rlimit *, rlim);
#endif
#endif /* __NR_setrlimit */
@@ -1240,30 +1209,7 @@ _syscall1(int, setfsgid, gid_t, gid);
#endif
//#define __NR__llseek 140
-#ifdef L__llseek
-#ifdef __UCLIBC_HAVE_LFS__
-#ifdef __NR__llseek
-extern int _llseek(int fd, __off_t offset_hi, __off_t offset_lo,
- __loff_t *result, int whence);
-
-_syscall5(int, _llseek, int, fd, __off_t, offset_hi, __off_t, offset_lo,
- __loff_t *, result, int, whence);
-
-__loff_t __libc_lseek64(int fd, __loff_t offset, int whence)
-{
- int ret;
- __loff_t result;
-
- ret = _llseek(fd, __LONG_LONG_PAIR((__off_t) (offset >> 32),
- (__off_t) (offset & 0xffffffff)), &result, whence);
-
- return ret ? (__loff_t) ret : result;
-}
-weak_alias(__libc_lseek64, llseek);
-weak_alias(__libc_lseek64, lseek64);
-#endif
-#endif
-#endif
+//See llseek.c
//#define __NR_getdents 141
#ifdef L_getdents
diff --git a/libc/sysdeps/linux/common/truncate64.c b/libc/sysdeps/linux/common/truncate64.c
index e6b4023d7..3205f748d 100644
--- a/libc/sysdeps/linux/common/truncate64.c
+++ b/libc/sysdeps/linux/common/truncate64.c
@@ -20,20 +20,22 @@
#include <sys/syscall.h>
#if defined __UCLIBC_HAVE_LFS__ && defined __NR_truncate64
+#ifndef INLINE_SYSCALL
+#define INLINE_SYSCALL(name, nr, args...) __syscall_truncate64 (args)
+#define __NR___syscall_truncate64 __NR_truncate64
+static inline _syscall3(int, __syscall_truncate64, const char *, path, int, high_length, int, low_length);
+#endif
+
#if __WORDSIZE == 64
/* For a 64 bit machine, life is simple... */
_syscall2(int, truncate64, const char *, path, __off64_t, length);
#elif __WORDSIZE == 32
-#define __NR___truncate64 __NR_truncate64
-static inline _syscall3(int, __truncate64, const char *, path,
- uint32_t, length_first_half,
- uint32_t, length_second_half);
/* The exported truncate64 function. */
int truncate64 (const char * path, __off64_t length)
{
uint32_t low = length & 0xffffffff;
uint32_t high = length >> 32;
- return __truncate64(path, __LONG_LONG_PAIR (high, low));
+ return INLINE_SYSCALL(truncate64, 3, path, __LONG_LONG_PAIR (high, low));
}
#else
#error Your machine is not 64 bit or 32 bit, I am dazed and confused.
diff --git a/libc/sysdeps/linux/h8300/bits/syscalls.h b/libc/sysdeps/linux/h8300/bits/syscalls.h
index 5c30e2193..da6a6d43e 100644
--- a/libc/sysdeps/linux/h8300/bits/syscalls.h
+++ b/libc/sysdeps/linux/h8300/bits/syscalls.h
@@ -1,10 +1,15 @@
-/*
- * nothing needed here until we want pthread support or similar
- */
+#ifndef _BITS_SYSCALLS_H
+#define _BITS_SYSCALLS_H
+#ifndef _SYSCALL_H
+# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."
+#endif
#include <features.h>
-/* Do something very evil for now. Until we include our out syscall
+
+/* Do something very evil for now. Until we create our own syscall
* macros, short circuit bits/syscall.h and use asm/unistd.h instead */
#define _BITS_SYSCALL_H
#include <asm/unistd.h>
+#endif /* _BITS_SYSCALLS_H */
+
diff --git a/libc/sysdeps/linux/i386/bits/syscalls.h b/libc/sysdeps/linux/i386/bits/syscalls.h
index 940e9db50..cb70d15e3 100644
--- a/libc/sysdeps/linux/i386/bits/syscalls.h
+++ b/libc/sysdeps/linux/i386/bits/syscalls.h
@@ -1,147 +1,95 @@
-/* Unlike the asm/unistd.h kernel header file (which this is partly based on),
- * this file must be able to cope with PIC and non-PIC code. For some arches
- * there is no difference. For x86 (which has far too few registers) there is
- * a difference. Regardless, including asm/unistd.h is hereby officially
- * forbidden. Don't do it. It is bad for you. */
+#ifndef _BITS_SYSCALLS_H
+#define _BITS_SYSCALLS_H
+#ifndef _SYSCALL_H
+# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."
+#endif
-#include <features.h>
+/* 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/syscall.h>
-#ifndef __UCLIBC_USE_UNIFIED_SYSCALL__
+#ifndef __set_errno
+# define __set_errno(val) (*__errno_location ()) = (val)
+#endif
-#undef __syscall_return
-#define __syscall_return(type, res) \
-do { \
- if ((unsigned long)(res) >= (unsigned long)(-125)) { \
- errno = -(res); \
- res = -1; \
- } \
- return (type) (res); \
-} while (0)
+/*
+ Some of the sneaky macros in the code were taken from
+ glibc-2.2.5/sysdeps/unix/sysv/linux/i386/sysdep.h
+*/
+
+#ifndef __ASSEMBLER__
+
+/* We need some help from the assembler to generate optimal code. We
+ define some macros here which later will be used. */
+asm (".L__X'%ebx = 1\n\t"
+ ".L__X'%ecx = 2\n\t"
+ ".L__X'%edx = 2\n\t"
+ ".L__X'%eax = 3\n\t"
+ ".L__X'%esi = 3\n\t"
+ ".L__X'%edi = 3\n\t"
+ ".L__X'%ebp = 3\n\t"
+ ".L__X'%esp = 3\n\t"
+ ".macro bpushl name reg\n\t"
+ ".if 1 - \\name\n\t"
+ ".if 2 - \\name\n\t"
+ "pushl %ebx\n\t"
+ ".else\n\t"
+ "xchgl \\reg, %ebx\n\t"
+ ".endif\n\t"
+ ".endif\n\t"
+ ".endm\n\t"
+ ".macro bpopl name reg\n\t"
+ ".if 1 - \\name\n\t"
+ ".if 2 - \\name\n\t"
+ "popl %ebx\n\t"
+ ".else\n\t"
+ "xchgl \\reg, %ebx\n\t"
+ ".endif\n\t"
+ ".endif\n\t"
+ ".endm\n\t"
+ ".macro bmovl name reg\n\t"
+ ".if 1 - \\name\n\t"
+ ".if 2 - \\name\n\t"
+ "movl \\reg, %ebx\n\t"
+ ".endif\n\t"
+ ".endif\n\t"
+ ".endm\n\t");
#undef _syscall0
#define _syscall0(type,name) \
type name(void) \
{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name)); \
-__syscall_return(type,__res); \
+return (type) (INLINE_SYSCALL(name, 0)); \
}
-
-#if defined(__PIC__)
-
-/*
- * PIC uses %ebx, so we need to save it during system calls
- */
-
#undef _syscall1
#define _syscall1(type,name,type1,arg1) \
type name(type1 arg1) \
{ \
-long __res; \
-__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \
- : "=a" (__res) \
- : "0" (__NR_##name),"r" ((long)(arg1))); \
-__syscall_return(type,__res); \
+return (type) (INLINE_SYSCALL(name, 1, arg1)); \
}
#undef _syscall2
#define _syscall2(type,name,type1,arg1,type2,arg2) \
type name(type1 arg1,type2 arg2) \
{ \
-long __res; \
-__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \
- : "=a" (__res) \
- : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2))); \
-__syscall_return(type,__res); \
+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) \
{ \
-long __res; \
-__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \
- : "=a" (__res) \
- : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3))); \
-__syscall_return(type,__res); \
+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) \
{ \
-long __res; \
-__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \
- : "=a" (__res) \
- : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3)),"S" ((long)(arg4))); \
-__syscall_return(type,__res); \
-}
-
-#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) \
-{ \
-long __res; \
-__asm__ volatile ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \
- : "=a" (__res) \
- : "0" (__NR_##name),"m" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \
-__syscall_return(type,__res); \
-}
-
-#else /* not doing __PIC__ */
-
-#undef _syscall1
-#define _syscall1(type,name,type1,arg1) \
-type name(type1 arg1) \
-{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1))); \
-__syscall_return(type,__res); \
-}
-
-#undef _syscall2
-#define _syscall2(type,name,type1,arg1,type2,arg2) \
-type name(type1 arg1,type2 arg2) \
-{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \
-__syscall_return(type,__res); \
-}
-
-#undef _syscall3
-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
-type name(type1 arg1,type2 arg2,type3 arg3) \
-{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3))); \
-__syscall_return(type,__res); \
-}
-
-#undef _syscall4
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3)),"S" ((long)(arg4))); \
-__syscall_return(type,__res); \
+return (type) (INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4)); \
}
#undef _syscall5
@@ -149,50 +97,55 @@ __syscall_return(type,__res); \
type5,arg5) \
type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
{ \
-long __res; \
-__asm__ volatile ("int $0x80" \
- : "=a" (__res) \
- : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
- "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \
-__syscall_return(type,__res); \
+return (type) (INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5)); \
}
-
-#endif /* __PIC__ */
-
-
-#else
-
-#define unified_syscall_body(name) \
-__asm__ ( \
-".text\n.align 4\n.global "###name"\n.type "###name",@function\n" \
-#name":\nmovb $"__STR_NR_##name \
-",%al;\n jmp __uClibc_syscall\n.Lfe1"###name":\n.size "###name \
-",.Lfe1"###name"-"###name \
-)
-
-#undef _syscall0
-#define _syscall0(type,name) \
-unified_syscall_body(name)
-
-#undef _syscall1
-#define _syscall1(type,name,type1,arg1) \
-unified_syscall_body(name)
-
-#undef _syscall2
-#define _syscall2(type,name,type1,arg1,type2,arg2) \
-unified_syscall_body(name)
-
-#undef _syscall3
-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
-unified_syscall_body(name)
-
-#undef _syscall4
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-unified_syscall_body(name)
-
-#undef _syscall5
-#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
-unified_syscall_body(name)
-
-#endif
+#define INLINE_SYSCALL(name, nr, args...) \
+ ({ \
+ unsigned int resultvar; \
+ asm volatile ( \
+ LOADARGS_##nr \
+ "movl %1, %%eax\n\t" \
+ "int $0x80\n\t" \
+ RESTOREARGS_##nr \
+ : "=a" (resultvar) \
+ : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc"); \
+ if (resultvar >= 0xfffff001) \
+ { \
+ __set_errno (-resultvar); \
+ resultvar = 0xffffffff; \
+ } \
+ (int) resultvar; })
+
+#define LOADARGS_0
+#define LOADARGS_1 \
+ "bpushl .L__X'%k2, %k2\n\t" \
+ "bmovl .L__X'%k2, %k2\n\t"
+#define LOADARGS_2 LOADARGS_1
+#define LOADARGS_3 LOADARGS_1
+#define LOADARGS_4 LOADARGS_1
+#define LOADARGS_5 LOADARGS_1
+
+#define RESTOREARGS_0
+#define RESTOREARGS_1 \
+ "bpopl .L__X'%k2, %k2\n\t"
+#define RESTOREARGS_2 RESTOREARGS_1
+#define RESTOREARGS_3 RESTOREARGS_1
+#define RESTOREARGS_4 RESTOREARGS_1
+#define RESTOREARGS_5 RESTOREARGS_1
+
+#define ASMFMT_0()
+#define ASMFMT_1(arg1) \
+ , "acdSD" (arg1)
+#define ASMFMT_2(arg1, arg2) \
+ , "adCD" (arg1), "c" (arg2)
+#define ASMFMT_3(arg1, arg2, arg3) \
+ , "aCD" (arg1), "c" (arg2), "d" (arg3)
+#define ASMFMT_4(arg1, arg2, arg3, arg4) \
+ , "aD" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
+#define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
+ , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
+
+
+#endif /* __ASSEMBLER__ */
+#endif /* _BITS_SYSCALLS_H */
diff --git a/libc/sysdeps/linux/i960/bits/syscalls.h b/libc/sysdeps/linux/i960/bits/syscalls.h
index 5c30e2193..da6a6d43e 100644
--- a/libc/sysdeps/linux/i960/bits/syscalls.h
+++ b/libc/sysdeps/linux/i960/bits/syscalls.h
@@ -1,10 +1,15 @@
-/*
- * nothing needed here until we want pthread support or similar
- */
+#ifndef _BITS_SYSCALLS_H
+#define _BITS_SYSCALLS_H
+#ifndef _SYSCALL_H
+# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."
+#endif
#include <features.h>
-/* Do something very evil for now. Until we include our out syscall
+
+/* Do something very evil for now. Until we create our own syscall
* macros, short circuit bits/syscall.h and use asm/unistd.h instead */
#define _BITS_SYSCALL_H
#include <asm/unistd.h>
+#endif /* _BITS_SYSCALLS_H */
+
diff --git a/libc/sysdeps/linux/m68k/bits/syscalls.h b/libc/sysdeps/linux/m68k/bits/syscalls.h
index 5c30e2193..da6a6d43e 100644
--- a/libc/sysdeps/linux/m68k/bits/syscalls.h
+++ b/libc/sysdeps/linux/m68k/bits/syscalls.h
@@ -1,10 +1,15 @@
-/*
- * nothing needed here until we want pthread support or similar
- */
+#ifndef _BITS_SYSCALLS_H
+#define _BITS_SYSCALLS_H
+#ifndef _SYSCALL_H
+# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."
+#endif
#include <features.h>
-/* Do something very evil for now. Until we include our out syscall
+
+/* Do something very evil for now. Until we create our own syscall
* macros, short circuit bits/syscall.h and use asm/unistd.h instead */
#define _BITS_SYSCALL_H
#include <asm/unistd.h>
+#endif /* _BITS_SYSCALLS_H */
+
diff --git a/libc/sysdeps/linux/mips/Makefile b/libc/sysdeps/linux/mips/Makefile
index a3fe845e8..4f6b806c9 100644
--- a/libc/sysdeps/linux/mips/Makefile
+++ b/libc/sysdeps/linux/mips/Makefile
@@ -30,7 +30,7 @@ TARGET_MACHINE_TYPE=$(shell $(CC) -dumpmachine)
CRT0=crt0.S
CRT0_OBJ=$(patsubst %.S,%.o, $(CRT0))
-SSRC=bsd-_setjmp.S bsd-setjmp.S setjmp.S clone.S
+SSRC=bsd-_setjmp.S bsd-setjmp.S setjmp.S clone.S fork.S __uClibc_syscall.S
SOBJS=$(patsubst %.S,%.o, $(SSRC))
CSRC=__longjmp.c brk.c vfork.c setjmp_aux.c _mmap.c pipe.c __syscall_error.c
diff --git a/libc/sysdeps/linux/mips/bits/syscalls.h b/libc/sysdeps/linux/mips/bits/syscalls.h
index 5c30e2193..e1981445f 100644
--- a/libc/sysdeps/linux/mips/bits/syscalls.h
+++ b/libc/sysdeps/linux/mips/bits/syscalls.h
@@ -1,10 +1,14 @@
-/*
- * nothing needed here until we want pthread support or similar
- */
+#ifndef _BITS_SYSCALLS_H
+#define _BITS_SYSCALLS_H
+#ifndef _SYSCALL_H
+# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."
+#endif
#include <features.h>
-/* Do something very evil for now. Until we include our out syscall
+
+/* Do something very evil for now. Until we create our own syscall
* macros, short circuit bits/syscall.h and use asm/unistd.h instead */
#define _BITS_SYSCALL_H
#include <asm/unistd.h>
+#endif /* _BITS_SYSCALLS_H */
diff --git a/libc/sysdeps/linux/mips/setjmp_aux.c b/libc/sysdeps/linux/mips/setjmp_aux.c
index 1cd2b2155..b957cea33 100644
--- a/libc/sysdeps/linux/mips/setjmp_aux.c
+++ b/libc/sysdeps/linux/mips/setjmp_aux.c
@@ -24,6 +24,8 @@
pointer. We do things this way because it's difficult to reliably
access them in C. */
+extern int __sigjmp_save (sigjmp_buf, int);
+
int
__sigsetjmp_aux (jmp_buf env, int savemask, int sp, int fp)
{
diff --git a/libc/sysdeps/linux/powerpc/bits/syscalls.h b/libc/sysdeps/linux/powerpc/bits/syscalls.h
index 93c0f3f48..6efff713e 100644
--- a/libc/sysdeps/linux/powerpc/bits/syscalls.h
+++ b/libc/sysdeps/linux/powerpc/bits/syscalls.h
@@ -1,152 +1,20 @@
-#include <asm/unistd.h>
-
-#undef __NR
-#define __NR(n) #n
-
-#undef __syscall_return
-#define __syscall_return(type) \
- return (__sc_err & 0x10000000 ? errno = __sc_ret, __sc_ret = -1 : 0), \
- (type) __sc_ret
-
-#undef __syscall_clobbers
-#define __syscall_clobbers \
- "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12"
-
-#undef _syscall0
-#define _syscall0(type,name) \
-type name(void) \
-{ \
- unsigned long __sc_ret, __sc_err; \
- { \
- register unsigned long __sc_0 __asm__ ("r0"); \
- register unsigned long __sc_3 __asm__ ("r3"); \
- \
- __sc_0 = __NR_##name; \
- __asm__ __volatile__ \
- ("sc \n\t" \
- "mfcr %1 " \
- : "=&r" (__sc_3), "=&r" (__sc_0) \
- : "0" (__sc_3), "1" (__sc_0) \
- : __syscall_clobbers); \
- __sc_ret = __sc_3; \
- __sc_err = __sc_0; \
- } \
- __syscall_return (type); \
-}
+#ifndef _BITS_SYSCALLS_H
+#define _BITS_SYSCALLS_H
+#ifndef _SYSCALL_H
+# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."
+#endif
-#undef _syscall1
-#define _syscall1(type,name,type1,arg1) \
-type name(type1 arg1) \
-{ \
- unsigned long __sc_ret, __sc_err; \
- { \
- register unsigned long __sc_0 __asm__ ("r0"); \
- register unsigned long __sc_3 __asm__ ("r3"); \
- \
- __sc_3 = (unsigned long) (arg1); \
- __sc_0 = __NR_##name; \
- __asm__ __volatile__ \
- ("sc \n\t" \
- "mfcr %1 " \
- : "=&r" (__sc_3), "=&r" (__sc_0) \
- : "0" (__sc_3), "1" (__sc_0) \
- : __syscall_clobbers); \
- __sc_ret = __sc_3; \
- __sc_err = __sc_0; \
- } \
- __syscall_return (type); \
-}
+#include <features.h>
-#undef _syscall2
-#define _syscall2(type,name,type1,arg1,type2,arg2) \
-type name(type1 arg1, type2 arg2) \
-{ \
- unsigned long __sc_ret, __sc_err; \
- { \
- register unsigned long __sc_0 __asm__ ("r0"); \
- register unsigned long __sc_3 __asm__ ("r3"); \
- register unsigned long __sc_4 __asm__ ("r4"); \
- \
- __sc_3 = (unsigned long) (arg1); \
- __sc_4 = (unsigned long) (arg2); \
- __sc_0 = __NR_##name; \
- __asm__ __volatile__ \
- ("sc \n\t" \
- "mfcr %1 " \
- : "=&r" (__sc_3), "=&r" (__sc_0) \
- : "0" (__sc_3), "1" (__sc_0), \
- "r" (__sc_4) \
- : __syscall_clobbers); \
- __sc_ret = __sc_3; \
- __sc_err = __sc_0; \
- } \
- __syscall_return (type); \
-}
-
-#undef _syscall3
-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
-type name(type1 arg1, type2 arg2, type3 arg3) \
-{ \
- unsigned long __sc_ret, __sc_err; \
- { \
- register unsigned long __sc_0 __asm__ ("r0"); \
- register unsigned long __sc_3 __asm__ ("r3"); \
- register unsigned long __sc_4 __asm__ ("r4"); \
- register unsigned long __sc_5 __asm__ ("r5"); \
- \
- __sc_3 = (unsigned long) (arg1); \
- __sc_4 = (unsigned long) (arg2); \
- __sc_5 = (unsigned long) (arg3); \
- __sc_0 = __NR_##name; \
- __asm__ __volatile__ \
- ("sc \n\t" \
- "mfcr %1 " \
- : "=&r" (__sc_3), "=&r" (__sc_0) \
- : "0" (__sc_3), "1" (__sc_0), \
- "r" (__sc_4), \
- "r" (__sc_5) \
- : __syscall_clobbers); \
- __sc_ret = __sc_3; \
- __sc_err = __sc_0; \
- } \
- __syscall_return (type); \
-}
-
-#undef _syscall4
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-{ \
- unsigned long __sc_ret, __sc_err; \
- { \
- register unsigned long __sc_0 __asm__ ("r0"); \
- register unsigned long __sc_3 __asm__ ("r3"); \
- register unsigned long __sc_4 __asm__ ("r4"); \
- register unsigned long __sc_5 __asm__ ("r5"); \
- register unsigned long __sc_6 __asm__ ("r6"); \
- \
- __sc_3 = (unsigned long) (arg1); \
- __sc_4 = (unsigned long) (arg2); \
- __sc_5 = (unsigned long) (arg3); \
- __sc_6 = (unsigned long) (arg4); \
- __sc_0 = __NR_##name; \
- __asm__ __volatile__ \
- ("sc \n\t" \
- "mfcr %1 " \
- : "=&r" (__sc_3), "=&r" (__sc_0) \
- : "0" (__sc_3), "1" (__sc_0), \
- "r" (__sc_4), \
- "r" (__sc_5), \
- "r" (__sc_6) \
- : __syscall_clobbers); \
- __sc_ret = __sc_3; \
- __sc_err = __sc_0; \
- } \
- __syscall_return (type); \
-}
+/* Do something very evil for now. Until we create our own syscall
+ * macros, short circuit bits/syscall.h and use asm/unistd.h instead */
+#define _BITS_SYSCALL_H
+#include <asm/unistd.h>
-#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) \
+/* The kernel includes don't provide _syscall6, so provide our own */
+#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) \
{ \
unsigned long __sc_ret, __sc_err; \
{ \
@@ -156,12 +24,14 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
register unsigned long __sc_5 __asm__ ("r5"); \
register unsigned long __sc_6 __asm__ ("r6"); \
register unsigned long __sc_7 __asm__ ("r7"); \
+ register unsigned long __sc_8 __asm__ ("r8"); \
\
__sc_3 = (unsigned long) (arg1); \
__sc_4 = (unsigned long) (arg2); \
__sc_5 = (unsigned long) (arg3); \
__sc_6 = (unsigned long) (arg4); \
__sc_7 = (unsigned long) (arg5); \
+ __sc_8 = (unsigned long) (arg6); \
__sc_0 = __NR_##name; \
__asm__ __volatile__ \
("sc \n\t" \
@@ -171,10 +41,16 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
"r" (__sc_4), \
"r" (__sc_5), \
"r" (__sc_6), \
- "r" (__sc_7) \
+ "r" (__sc_7), \
+ "r" (__sc_8) \
: __syscall_clobbers); \
__sc_ret = __sc_3; \
__sc_err = __sc_0; \
} \
__syscall_return (type); \
}
+
+
+
+#endif /* _BITS_SYSCALLS_H */
+
diff --git a/libc/sysdeps/linux/sh/bits/syscalls.h b/libc/sysdeps/linux/sh/bits/syscalls.h
index 9759f0b4a..da6a6d43e 100644
--- a/libc/sysdeps/linux/sh/bits/syscalls.h
+++ b/libc/sysdeps/linux/sh/bits/syscalls.h
@@ -1,106 +1,15 @@
-/* This file is based on the asm/unistd.h kernel header file.
- * Including asm/unistd.h is hereby officially forbidden.
- * Don't do it. It is bad for you. */
+#ifndef _BITS_SYSCALLS_H
+#define _BITS_SYSCALLS_H
+#ifndef _SYSCALL_H
+# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."
+#endif
#include <features.h>
-/* FIXME: perhaps sh needs separate PIC syscalls? */
-
-
-#define __syscall_return(type, res) \
-do { \
- if ((unsigned long)(res) >= (unsigned long)(-125)) { \
- /* Avoid using "res" which is declared to be in register r0; \
- errno might expand to a function call and clobber it. */ \
- int __err = -(res); \
- errno = __err; \
- res = -1; \
- } \
- return (type) (res); \
-} while (0)
-
-/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
-#define _syscall0(type,name) \
-type name(void) \
-{ \
-register long __sc0 __asm__ ("r3") = __NR_##name; \
-__asm__ __volatile__ ("trapa #0x10" \
- : "=z" (__sc0) \
- : "0" (__sc0) \
- : "memory" ); \
-__syscall_return(type,__sc0); \
-}
-
-#define _syscall1(type,name,type1,arg1) \
-type name(type1 arg1) \
-{ \
-register long __sc0 __asm__ ("r3") = __NR_##name; \
-register long __sc4 __asm__ ("r4") = (long) arg1; \
-__asm__ __volatile__ ("trapa #0x11" \
- : "=z" (__sc0) \
- : "0" (__sc0), "r" (__sc4) \
- : "memory"); \
-__syscall_return(type,__sc0); \
-}
-
-#define _syscall2(type,name,type1,arg1,type2,arg2) \
-type name(type1 arg1,type2 arg2) \
-{ \
-register long __sc0 __asm__ ("r3") = __NR_##name; \
-register long __sc4 __asm__ ("r4") = (long) arg1; \
-register long __sc5 __asm__ ("r5") = (long) arg2; \
-__asm__ __volatile__ ("trapa #0x12" \
- : "=z" (__sc0) \
- : "0" (__sc0), "r" (__sc4), "r" (__sc5) \
- : "memory"); \
-__syscall_return(type,__sc0); \
-}
-
-#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
-type name(type1 arg1,type2 arg2,type3 arg3) \
-{ \
-register long __sc0 __asm__ ("r3") = __NR_##name; \
-register long __sc4 __asm__ ("r4") = (long) arg1; \
-register long __sc5 __asm__ ("r5") = (long) arg2; \
-register long __sc6 __asm__ ("r6") = (long) arg3; \
-__asm__ __volatile__ ("trapa #0x13" \
- : "=z" (__sc0) \
- : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6) \
- : "memory"); \
-__syscall_return(type,__sc0); \
-}
-
-#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
-{ \
-register long __sc0 __asm__ ("r3") = __NR_##name; \
-register long __sc4 __asm__ ("r4") = (long) arg1; \
-register long __sc5 __asm__ ("r5") = (long) arg2; \
-register long __sc6 __asm__ ("r6") = (long) arg3; \
-register long __sc7 __asm__ ("r7") = (long) arg4; \
-__asm__ __volatile__ ("trapa #0x14" \
- : "=z" (__sc0) \
- : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), \
- "r" (__sc7) \
- : "memory" ); \
-__syscall_return(type,__sc0); \
-}
-
-#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) \
-{ \
-register long __sc3 __asm__ ("r3") = __NR_##name; \
-register long __sc4 __asm__ ("r4") = (long) arg1; \
-register long __sc5 __asm__ ("r5") = (long) arg2; \
-register long __sc6 __asm__ ("r6") = (long) arg3; \
-register long __sc7 __asm__ ("r7") = (long) arg4; \
-register long __sc0 __asm__ ("r0") = (long) arg5; \
-__asm__ __volatile__ ("trapa #0x15" \
- : "=z" (__sc0) \
- : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), "r" (__sc7), \
- "r" (__sc3) \
- : "memory" ); \
-__syscall_return(type,__sc0); \
-}
+/* Do something very evil for now. Until we create our own syscall
+ * macros, short circuit bits/syscall.h and use asm/unistd.h instead */
+#define _BITS_SYSCALL_H
+#include <asm/unistd.h>
+#endif /* _BITS_SYSCALLS_H */
diff --git a/libc/sysdeps/linux/sparc/bits/syscalls.h b/libc/sysdeps/linux/sparc/bits/syscalls.h
index 5c30e2193..da6a6d43e 100644
--- a/libc/sysdeps/linux/sparc/bits/syscalls.h
+++ b/libc/sysdeps/linux/sparc/bits/syscalls.h
@@ -1,10 +1,15 @@
-/*
- * nothing needed here until we want pthread support or similar
- */
+#ifndef _BITS_SYSCALLS_H
+#define _BITS_SYSCALLS_H
+#ifndef _SYSCALL_H
+# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."
+#endif
#include <features.h>
-/* Do something very evil for now. Until we include our out syscall
+
+/* Do something very evil for now. Until we create our own syscall
* macros, short circuit bits/syscall.h and use asm/unistd.h instead */
#define _BITS_SYSCALL_H
#include <asm/unistd.h>
+#endif /* _BITS_SYSCALLS_H */
+
diff --git a/libc/sysdeps/linux/v850/bits/syscalls.h b/libc/sysdeps/linux/v850/bits/syscalls.h
index 5c30e2193..da6a6d43e 100644
--- a/libc/sysdeps/linux/v850/bits/syscalls.h
+++ b/libc/sysdeps/linux/v850/bits/syscalls.h
@@ -1,10 +1,15 @@
-/*
- * nothing needed here until we want pthread support or similar
- */
+#ifndef _BITS_SYSCALLS_H
+#define _BITS_SYSCALLS_H
+#ifndef _SYSCALL_H
+# error "Never use <bits/syscall.h> directly; include <sys/syscall.h> instead."
+#endif
#include <features.h>
-/* Do something very evil for now. Until we include our out syscall
+
+/* Do something very evil for now. Until we create our own syscall
* macros, short circuit bits/syscall.h and use asm/unistd.h instead */
#define _BITS_SYSCALL_H
#include <asm/unistd.h>
+#endif /* _BITS_SYSCALLS_H */
+