diff options
author | Eric Andersen <andersen@codepoet.org> | 2002-07-22 17:10:30 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2002-07-22 17:10:30 +0000 |
commit | 72677cc3d8403da4b35c99617352bde347780222 (patch) | |
tree | 7d5d29cc3f49a1b69f90ca9ae6fbf3f61e81b1ce | |
parent | 980e7850176c30ba374a706298b2865f387ec2ae (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
22 files changed, 425 insertions, 896 deletions
diff --git a/extra/scripts/gen_bits_syscall_h.sh b/extra/scripts/gen_bits_syscall_h.sh index 6ebbb434b..ce599c9b0 100755 --- a/extra/scripts/gen_bits_syscall_h.sh +++ b/extra/scripts/gen_bits_syscall_h.sh @@ -22,7 +22,6 @@ $CC -E - | echo "# error \"Never use <bits/syscall.h> directly; include <sys/syscall.h> instead.\"" ; echo "#endif" ; echo ; sed -ne 's/^UCLIBC_\([A-Za-z0-9_]*\) *\(.*\)/#define __NR_\1 \2\ -#define SYS_\1 __NR_\1\ -#define __STR_NR_\1 \"\2\"/gp' +#define SYS_\1 __NR_\1/gp' echo "#endif" ; echo ; ) diff --git a/include/sys/syscall.h b/include/sys/syscall.h index 723a99ee0..788468180 100644 --- a/include/sys/syscall.h +++ b/include/sys/syscall.h @@ -19,14 +19,7 @@ #ifndef _SYSCALL_H #define _SYSCALL_H 1 -/* This file provides us with our own private copy of the _syscall[0-5] macros. - * This is important, since on some arches (such as i386) the kernel's macros - * don't handle things like PIC code, so we can't use them. */ +/* This file provides us with the nicely useful _syscall[0-5] macros. */ #include <bits/syscalls.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> - #endif 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 */ + |