diff options
Diffstat (limited to 'libc')
| -rw-r--r-- | libc/sysdeps/linux/common/posix_fadvise.c | 14 | ||||
| -rw-r--r-- | libc/sysdeps/linux/common/posix_fadvise64.c | 36 | ||||
| -rw-r--r-- | libc/sysdeps/linux/sh/bits/syscalls.h | 145 |
3 files changed, 187 insertions, 8 deletions
diff --git a/libc/sysdeps/linux/common/posix_fadvise.c b/libc/sysdeps/linux/common/posix_fadvise.c index 45734f9b2..95aa4d27b 100644 --- a/libc/sysdeps/linux/common/posix_fadvise.c +++ b/libc/sysdeps/linux/common/posix_fadvise.c @@ -33,8 +33,18 @@ int posix_fadvise(int fd, off_t offset, off_t len, int advice) return 0; } #else -_syscall4(int, posix_fadvise, int, fd, off_t, offset, - off_t, len, int, advice); +static __inline__ int syscall_posix_fadvise(int fd, off_t offset1, off_t offset2, off_t len, int advice); +#define __NR_syscall_posix_fadvise __NR_fadvise64 +_syscall5(int, syscall_posix_fadvise, int, fd, off_t, offset1, + off_t, offset2, off_t, len, int, advice); + +int posix_fadvise(int fd, off_t offset, off_t len, int advice) +{ + int ret = syscall_posix_fadvise(fd, __LONG_LONG_PAIR (offset >> 31, offset), len, advice); + if (ret == -1) + return errno; + return ret; +} #endif diff --git a/libc/sysdeps/linux/common/posix_fadvise64.c b/libc/sysdeps/linux/common/posix_fadvise64.c index 5d8ed65b6..03e25ed93 100644 --- a/libc/sysdeps/linux/common/posix_fadvise64.c +++ b/libc/sysdeps/linux/common/posix_fadvise64.c @@ -40,14 +40,35 @@ int posix_fadvise64(int fd, __off64_t offset, __off64_t len, int advice) return INTERNAL_SYSCALL_ERRNO (ret, err); } #else -_syscall4(int, posix_fadvise64, int, fd, __off64_t, offset, +static __inline__ int syscall_posix_fadvise(int fd, off_t offset1, off_t offset2, off_t len, int advice); +#define __NR_syscall_posix_fadvise64 __NR_posix_fadvise64 +_syscall4(int, syscall_posix_fadvise64, int, fd, __off64_t, offset, __off64_t, len, int, advice); +int posix_fadvise64(int fd, __off64_t offset, __off64_t len, int advice) +{ + int ret = syscall_posix_fadvise64(fd, offset, len, advice); + if (ret == -1) + return errno; + return ret; +} #endif /* 32 bit implementation is kind of a pita */ #elif __WORDSIZE == 32 -#ifdef _syscall6 /* workaround until everyone has _syscall6() */ +#ifdef INTERNAL_SYSCALL +int posix_fadvise64(int fd, __off64_t offset, __off64_t len, int advice) +{ + INTERNAL_SYSCALL_DECL (err); + int ret = INTERNAL_SYSCALL (fadvise64_64, err, 6, fd, + __LONG_LONG_PAIR(offset >> 32, offset & 0xffffffff), + __LONG_LONG_PAIR(len >> 32, len & 0xffffffff), + advice); + if (!INTERNAL_SYSCALL_ERROR_P (ret, err)) + return 0; + return INTERNAL_SYSCALL_ERRNO (ret, err); +} +#elif defined _syscall6 /* workaround until everyone has _syscall6() */ #define __NR___syscall_fadvise64_64 __NR_fadvise64_64 static __inline__ _syscall6(int, __syscall_fadvise64_64, int, fd, unsigned long, high_offset, unsigned long, low_offset, @@ -55,14 +76,17 @@ static __inline__ _syscall6(int, __syscall_fadvise64_64, int, fd, int, advice); int posix_fadvise64(int fd, __off64_t offset, __off64_t len, int advice) { - return (__syscall_fadvise64_64(fd, + int ret = __syscall_fadvise64_64(fd, __LONG_LONG_PAIR(offset >> 32, offset & 0xffffffff), __LONG_LONG_PAIR(len >> 32, len & 0xffffffff), - advice)); + advice); + if (ret == -1) + return errno; + return ret; } #else -#warning _syscall6 has not been defined for your machine :( -#endif /* _syscall6 */ +#warning neither INTERNAL_SYSCALL nor _syscall6 has been defined for your machine :( +#endif /* INTERNAL_SYSCALL */ #else #error your machine is neither 32 bit or 64 bit ... it must be magical diff --git a/libc/sysdeps/linux/sh/bits/syscalls.h b/libc/sysdeps/linux/sh/bits/syscalls.h index 234f80653..e0ab65b82 100644 --- a/libc/sysdeps/linux/sh/bits/syscalls.h +++ b/libc/sysdeps/linux/sh/bits/syscalls.h @@ -140,6 +140,151 @@ __asm__ __volatile__ ("trapa %1" \ __syscall_return(type,__sc0); \ } +#define SYSCALL_INST_STR0 "trapa #0x10\n\t" +#define SYSCALL_INST_STR1 "trapa #0x11\n\t" +#define SYSCALL_INST_STR2 "trapa #0x12\n\t" +#define SYSCALL_INST_STR3 "trapa #0x13\n\t" +#define SYSCALL_INST_STR4 "trapa #0x14\n\t" +#define SYSCALL_INST_STR5 "trapa #0x15\n\t" +#define SYSCALL_INST_STR6 "trapa #0x16\n\t" + +# ifdef NEED_SYSCALL_INST_PAD +# define SYSCALL_INST_PAD "\ + or r0,r0; or r0,r0; or r0,r0; or r0,r0; or r0,r0" +# else +# define SYSCALL_INST_PAD +# endif + +#define ASMFMT_0 +#define ASMFMT_1 \ + , "r" (r4) +#define ASMFMT_2 \ + , "r" (r4), "r" (r5) +#define ASMFMT_3 \ + , "r" (r4), "r" (r5), "r" (r6) +#define ASMFMT_4 \ + , "r" (r4), "r" (r5), "r" (r6), "r" (r7) +#define ASMFMT_5 \ + , "r" (r4), "r" (r5), "r" (r6), "r" (r7), "0" (r0) +#define ASMFMT_6 \ + , "r" (r4), "r" (r5), "r" (r6), "r" (r7), "0" (r0), "r" (r1) +#define ASMFMT_7 \ + , "r" (r4), "r" (r5), "r" (r6), "r" (r7), "0" (r0), "r" (r1), "r" (r2) + +#define SUBSTITUTE_ARGS_0() +#define SUBSTITUTE_ARGS_1(arg1) \ + long int _arg1 = (long int) (arg1); \ + register long int r4 __asm__ ("%r4") = (long int) (_arg1) +#define SUBSTITUTE_ARGS_2(arg1, arg2) \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + register long int r4 __asm__ ("%r4") = (long int) (_arg1); \ + register long int r5 __asm__ ("%r5") = (long int) (_arg2) +#define SUBSTITUTE_ARGS_3(arg1, arg2, arg3) \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + register long int r4 __asm__ ("%r4") = (long int) (_arg1); \ + register long int r5 __asm__ ("%r5") = (long int) (_arg2); \ + register long int r6 __asm__ ("%r6") = (long int) (_arg3) +#define SUBSTITUTE_ARGS_4(arg1, arg2, arg3, arg4) \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + long int _arg4 = (long int) (arg4); \ + register long int r4 __asm__ ("%r4") = (long int) (_arg1); \ + register long int r5 __asm__ ("%r5") = (long int) (_arg2); \ + register long int r6 __asm__ ("%r6") = (long int) (_arg3); \ + register long int r7 __asm__ ("%r7") = (long int) (_arg4) +#define SUBSTITUTE_ARGS_5(arg1, arg2, arg3, arg4, arg5) \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + long int _arg4 = (long int) (arg4); \ + long int _arg5 = (long int) (arg5); \ + register long int r4 __asm__ ("%r4") = (long int) (_arg1); \ + register long int r5 __asm__ ("%r5") = (long int) (_arg2); \ + register long int r6 __asm__ ("%r6") = (long int) (_arg3); \ + register long int r7 __asm__ ("%r7") = (long int) (_arg4); \ + register long int r0 __asm__ ("%r0") = (long int) (_arg5) +#define SUBSTITUTE_ARGS_6(arg1, arg2, arg3, arg4, arg5, arg6) \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + long int _arg4 = (long int) (arg4); \ + long int _arg5 = (long int) (arg5); \ + long int _arg6 = (long int) (arg6); \ + register long int r4 __asm__ ("%r4") = (long int)(_arg1); \ + register long int r5 __asm__ ("%r5") = (long int) (_arg2); \ + register long int r6 __asm__ ("%r6") = (long int) (_arg3); \ + register long int r7 __asm__ ("%r7") = (long int) (_arg4); \ + register long int r0 __asm__ ("%r0") = (long int) (_arg5); \ + register long int r1 __asm__ ("%r1") = (long int) (_arg6) +#define SUBSTITUTE_ARGS_7(arg1, arg2, arg3, arg4, arg5, arg6, arg7) \ + long int _arg1 = (long int) (arg1); \ + long int _arg2 = (long int) (arg2); \ + long int _arg3 = (long int) (arg3); \ + long int _arg4 = (long int) (arg4); \ + long int _arg5 = (long int) (arg5); \ + long int _arg6 = (long int) (arg6); \ + long int _arg7 = (long int) (arg7); \ + register long int r4 __asm__ ("%r4") = (long int) (_arg1); \ + register long int r5 __asm__ ("%r5") = (long int) (_arg2); \ + register long int r6 __asm__ ("%r6") = (long int) (_arg3); \ + register long int r7 __asm__ ("%r7") = (long int) (_arg4); \ + register long int r0 __asm__ ("%r0") = (long int) (_arg5); \ + register long int r1 __asm__ ("%r1") = (long int) (_arg6); \ + register long int r2 __asm__ ("%r2") = (long int) (_arg7) + +#undef INLINE_SYSCALL +#define INLINE_SYSCALL(name, nr, args...) \ + ({ \ + unsigned int __resultvar = INTERNAL_SYSCALL (name, , nr, args); \ + if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (__resultvar, ), 0)) \ + { \ + __set_errno (INTERNAL_SYSCALL_ERRNO (__resultvar, )); \ + __resultvar = 0xffffffff; \ + } \ + (int) __resultvar; }) + +#undef INTERNAL_SYSCALL +#define INTERNAL_SYSCALL(name, err, nr, args...) \ + ({ \ + unsigned long int resultvar; \ + register long int r3 __asm__ ("%r3") = SYS_ify (name); \ + SUBSTITUTE_ARGS_##nr(args); \ + \ + __asm__ volatile (SYSCALL_INST_STR##nr SYSCALL_INST_PAD \ + : "=z" (resultvar) \ + : "r" (r3) ASMFMT_##nr \ + : "memory"); \ + \ + (int) resultvar; }) + +/* The _NCS variant allows non-constant syscall numbers. */ +#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ + ({ \ + unsigned long int resultvar; \ + register long int r3 __asm__ ("%r3") = (name); \ + SUBSTITUTE_ARGS_##nr(args); \ + \ + __asm__ volatile (SYSCALL_INST_STR##nr SYSCALL_INST_PAD \ + : "=z" (resultvar) \ + : "r" (r3) ASMFMT_##nr \ + : "memory"); \ + \ + (int) resultvar; }) + +#undef INTERNAL_SYSCALL_DECL +#define INTERNAL_SYSCALL_DECL(err) do { } while (0) + +#undef INTERNAL_SYSCALL_ERROR_P +#define INTERNAL_SYSCALL_ERROR_P(val, err) \ + ((unsigned int) (val) >= 0xfffff001u) + +#undef INTERNAL_SYSCALL_ERRNO +#define INTERNAL_SYSCALL_ERRNO(val, err) (-(val)) + #endif /* __ASSEMBLER__ */ #endif /* _BITS_SYSCALLS_H */ |
