From 72677cc3d8403da4b35c99617352bde347780222 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Mon, 22 Jul 2002 17:10:30 +0000 Subject: 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 --- libc/sysdeps/linux/common/Makefile | 2 +- libc/sysdeps/linux/common/ftruncate64.c | 13 ++- libc/sysdeps/linux/common/getcwd.c | 10 +- libc/sysdeps/linux/common/getpagesize.c | 2 +- libc/sysdeps/linux/common/pread_write.c | 160 ++++++++++++++------------------ libc/sysdeps/linux/common/syscalls.c | 88 ++++-------------- libc/sysdeps/linux/common/truncate64.c | 12 ++- 7 files changed, 113 insertions(+), 174 deletions(-) (limited to 'libc/sysdeps/linux/common') 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 #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 #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 /* 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 -#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 #include #include -#define _XOPEN_SOURCE 500 #include #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 +#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 #include #include + //#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 -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 -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 -_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 -#include -_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 #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. -- cgit v1.2.3