mirror of https://git.musl-libc.org/git/musl
Browse Source
with this patch, the syscallN() functions are no longer needed; a variadic syscall() macro allows syscalls with anywhere from 0 to 6 arguments to be made with a single macro name. also, manually casting each non-integer argument with (long) is no longer necessary; the casts are hidden in the macros. some source files which depended on being able to define the old macro SYSCALL_RETURNS_ERRNO have been modified to directly use __syscall() instead of syscall(). references to SYSCALL_SIGSET_SIZE and SYSCALL_LL have also been changed. x86_64 has not been tested, and may need a follow-up commit to fix any minor bugs/oversights.rs-1.0
26 changed files with 275 additions and 316 deletions
@ -1,167 +0,0 @@ |
|||
#ifndef _SYSCALL_H |
|||
#define _SYSCALL_H |
|||
|
|||
#include <sys/syscall.h> |
|||
|
|||
#define SYSCALL_LL(x) \ |
|||
((union { long long ll; long l[2]; }){ .ll = x }).l[0], \ |
|||
((union { long long ll; long l[2]; }){ .ll = x }).l[1] |
|||
|
|||
#define SYSCALL_SIGSET_SIZE 8 |
|||
|
|||
#if defined(SYSCALL_NORETURN) |
|||
static inline long __syscall_ret(unsigned long r) |
|||
{ |
|||
for(;;); |
|||
return 0; |
|||
} |
|||
#elif defined(SYSCALL_RETURN_ERRNO) |
|||
static inline long __syscall_ret(unsigned long r) |
|||
{ |
|||
return -r; |
|||
} |
|||
#else |
|||
extern long __syscall_ret(unsigned long); |
|||
#endif |
|||
|
|||
static inline long syscall0(long n) |
|||
{ |
|||
unsigned long ret; |
|||
__asm__ __volatile__ ("int $128" : "=a"(ret) : "a"(n) : "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
#ifndef __PIC__ |
|||
|
|||
static inline long syscall1(long n, long a1) |
|||
{ |
|||
unsigned long ret; |
|||
__asm__ __volatile__ ("int $128" : "=a"(ret) : "a"(n), "b"(a1) : "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
static inline long syscall2(long n, long a1, long a2) |
|||
{ |
|||
unsigned long ret; |
|||
__asm__ __volatile__ ("int $128" : "=a"(ret) : "a"(n), "b"(a1), "c"(a2) : "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
static inline long syscall3(long n, long a1, long a2, long a3) |
|||
{ |
|||
unsigned long ret; |
|||
__asm__ __volatile__ ("int $128" : "=a"(ret) : "a"(n), "b"(a1), "c"(a2), "d"(a3) : "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
static inline long syscall4(long n, long a1, long a2, long a3, long a4) |
|||
{ |
|||
unsigned long ret; |
|||
__asm__ __volatile__ ("int $128" : "=a"(ret) : "a"(n), "b"(a1), "c"(a2), "d"(a3), "S"(a4) : "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
static inline long syscall5(long n, long a1, long a2, long a3, long a4, long a5) |
|||
{ |
|||
unsigned long ret; |
|||
__asm__ __volatile__ ("int $128" : "=a"(ret) : "a"(n), "b"(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5) : "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
static inline long syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6) |
|||
{ |
|||
unsigned long ret; |
|||
__asm__ __volatile__ ("pushl %%ebp ; mov %%eax,%%ebp ; movl %1,%%eax ; int $128 ; popl %%ebp" |
|||
: "=a"(ret) : "i"(n), "b"(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5), "a"(a6) : "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
#else |
|||
|
|||
static inline long syscall1(long n, long a1) |
|||
{ |
|||
unsigned long ret; |
|||
__asm__ __volatile__ ("xchg %2,%%ebx ; int $128 ; xchg %2,%%ebx" |
|||
: "=a"(ret) : "a"(n), "r"(a1) : "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
static inline long syscall2(long n, long a1, long a2) |
|||
{ |
|||
unsigned long ret; |
|||
__asm__ __volatile__ ("xchg %2,%%ebx ; int $128 ; xchg %2,%%ebx" |
|||
: "=a"(ret) : "a"(n), "r"(a1), "c"(a2) : "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
static inline long syscall3(long n, long a1, long a2, long a3) |
|||
{ |
|||
unsigned long ret; |
|||
__asm__ __volatile__ ("xchg %2,%%ebx ; int $128 ; xchg %2,%%ebx" |
|||
: "=a"(ret) : "a"(n), "r"(a1), "c"(a2), "d"(a3) : "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
static inline long syscall4(long n, long a1, long a2, long a3, long a4) |
|||
{ |
|||
unsigned long ret; |
|||
__asm__ __volatile__ ("xchg %2,%%ebx ; int $128 ; xchg %2,%%ebx" |
|||
: "=a"(ret) : "a"(n), "r"(a1), "c"(a2), "d"(a3), "S"(a4) : "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
static inline long syscall5(long n, long a1, long a2, long a3, long a4, long a5) |
|||
{ |
|||
unsigned long ret; |
|||
__asm__ __volatile__ ("pushl %%ebx ; mov %%eax,%%ebx ; movl %1,%%eax ; int $128 ; popl %%ebx" |
|||
: "=a"(ret) : "i"(n), "a"(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5) : "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
#define syscall6(n,a1,a2,a3,a4,a5,a6) __syscall((n),(a1),(a2),(a3),(a4),(a5),(a6)) |
|||
|
|||
#endif |
|||
|
|||
#define __SC_socket 1 |
|||
#define __SC_bind 2 |
|||
#define __SC_connect 3 |
|||
#define __SC_listen 4 |
|||
#define __SC_accept 5 |
|||
#define __SC_getsockname 6 |
|||
#define __SC_getpeername 7 |
|||
#define __SC_socketpair 8 |
|||
#define __SC_send 9 |
|||
#define __SC_recv 10 |
|||
#define __SC_sendto 11 |
|||
#define __SC_recvfrom 12 |
|||
#define __SC_shutdown 13 |
|||
#define __SC_setsockopt 14 |
|||
#define __SC_getsockopt 15 |
|||
#define __SC_sendmsg 16 |
|||
#define __SC_recvmsg 17 |
|||
|
|||
|
|||
#define socketcall(nm, a, b, c, d, e, f) syscall2(__NR_socketcall, __SC_##nm, \ |
|||
(long)(long [6]){ (long)a, (long)b, (long)c, (long)d, (long)e, (long)f }) |
|||
|
|||
|
|||
#undef O_LARGEFILE |
|||
#define O_LARGEFILE 0100000 |
|||
|
|||
/* the following are needed for iso c functions to use */ |
|||
#define __syscall_open(filename, flags, mode) syscall3(__NR_open, (long)(filename), (flags)|O_LARGEFILE, (mode)) |
|||
#define __syscall_read(fd, buf, len) syscall3(__NR_read, (fd), (long)(buf), (len)) |
|||
#define __syscall_write(fd, buf, len) syscall3(__NR_write, (fd), (long)(buf), (len)) |
|||
#define __syscall_close(fd) syscall1(__NR_close, (fd)) |
|||
#define __syscall_fcntl(fd, cmd, arg) syscall3(__NR_fcntl64, (fd), (cmd), (long)(arg)) |
|||
#define __syscall_dup2(old, new) syscall2(__NR_dup2, (old), (new)) |
|||
#define __syscall_unlink(path) syscall1(__NR_unlink, (long)(path)) |
|||
#define __syscall_getpid() syscall0(__NR_getpid) |
|||
#define __syscall_kill(pid,sig) syscall2(__NR_kill, (pid), (sig)) |
|||
#define __syscall_sigaction(sig,new,old) syscall4(__NR_rt_sigaction, (sig), (long)(new), (long)(old), SYSCALL_SIGSET_SIZE) |
|||
#define __syscall_ioctl(fd,ioc,arg) syscall3(__NR_ioctl, (fd), (ioc), (long)(arg)) |
|||
#define __syscall_exit(code) syscall1(__NR_exit, code) |
|||
|
|||
long __syscall(long, ...); |
|||
|
|||
#endif |
|||
@ -1,113 +0,0 @@ |
|||
#ifndef _SYSCALL_H |
|||
#define _SYSCALL_H |
|||
|
|||
#include <sys/syscall.h> |
|||
|
|||
#define SYSCALL_LL(x) x, 0 |
|||
#define SYSCALL_SIGSET_SIZE 8 |
|||
|
|||
#if defined(SYSCALL_NORETURN) |
|||
static inline long __syscall_ret(unsigned long r) |
|||
{ |
|||
for(;;); |
|||
return 0; |
|||
} |
|||
#elif defined(SYSCALL_RETURN_ERRNO) |
|||
static inline long __syscall_ret(unsigned long r) |
|||
{ |
|||
return -r; |
|||
} |
|||
#else |
|||
extern long __syscall_ret(unsigned long); |
|||
#endif |
|||
|
|||
// 64: di, si, dx, r10, r8, r9
|
|||
// 32: ebx, ecx, edx, esi, edi, ebp
|
|||
|
|||
#define SYSCALL "syscall" |
|||
|
|||
static inline long syscall0(long n) |
|||
{ |
|||
unsigned long ret; |
|||
__asm__ __volatile__ (SYSCALL : "=a"(ret) : "a"(n) : "rcx", "r11", "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
static inline long syscall1(long n, long a1) |
|||
{ |
|||
unsigned long ret; |
|||
__asm__ __volatile__ (SYSCALL : "=a"(ret) : "a"(n), "D"(a1) : "rcx", "r11", "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
static inline long syscall2(long n, long a1, long a2) |
|||
{ |
|||
unsigned long ret; |
|||
__asm__ __volatile__ (SYSCALL : "=a"(ret) : "a"(n), "D"(a1), "S"(a2) |
|||
: "rcx", "r11", "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
static inline long syscall3(long n, long a1, long a2, long a3) |
|||
{ |
|||
unsigned long ret; |
|||
__asm__ __volatile__ (SYSCALL : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), |
|||
"d"(a3) : "rcx", "r11", "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
static inline long syscall4(long n, long a1, long a2, long a3, long a4) |
|||
{ |
|||
unsigned long ret; |
|||
register long r10 __asm__("r10") = a4; |
|||
__asm__ __volatile__ (SYSCALL : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), |
|||
"d"(a3), "r"(r10): "rcx", "r11", "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
static inline long syscall5(long n, long a1, long a2, long a3, long a4, |
|||
long a5) |
|||
{ |
|||
unsigned long ret; |
|||
register long r10 __asm__("r10") = a4; |
|||
register long r8 __asm__("r8") = a5; |
|||
__asm__ __volatile__ (SYSCALL : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), |
|||
"d"(a3), "r"(r10), "r"(r8) : "rcx", "r11", "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
static inline long syscall6(long n, long a1, long a2, long a3, long a4, |
|||
long a5, long a6) |
|||
{ |
|||
unsigned long ret; |
|||
register long r10 __asm__("r10") = a4; |
|||
register long r8 __asm__("r8") = a5; |
|||
register long r9 __asm__("r9") = a6; |
|||
__asm__ __volatile__ (SYSCALL : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), |
|||
"d"(a3), "r"(r10), "r"(r8), "r"(r9) : "rcx", "r11", "memory"); |
|||
return __syscall_ret(ret); |
|||
} |
|||
|
|||
#undef O_LARGEFILE |
|||
#define O_LARGEFILE 0100000 |
|||
|
|||
#define socketcall(nm, a, b, c, d, e, f) syscall6(__NR_##nm, \ |
|||
(long)a, (long)b, (long)c, (long)d, (long)e, (long)f) |
|||
|
|||
/* the following are needed for iso c functions to use */ |
|||
#define __syscall_open(filename, flags, mode) syscall3(__NR_open, (long)(filename), (flags)|O_LARGEFILE, (mode)) |
|||
#define __syscall_read(fd, buf, len) syscall3(__NR_read, (fd), (long)(buf), (len)) |
|||
#define __syscall_write(fd, buf, len) syscall3(__NR_write, (fd), (long)(buf), (len)) |
|||
#define __syscall_close(fd) syscall1(__NR_close, (fd)) |
|||
#define __syscall_fcntl(fd, cmd, arg) syscall3(__NR_fcntl, (fd), (cmd), (long)(arg)) |
|||
#define __syscall_dup2(old, new) syscall2(__NR_dup2, (old), (new)) |
|||
#define __syscall_unlink(path) syscall1(__NR_unlink, (long)(path)) |
|||
#define __syscall_getpid() syscall0(__NR_getpid) |
|||
#define __syscall_kill(pid,sig) syscall2(__NR_kill, (pid), (sig)) |
|||
#define __syscall_sigaction(sig,new,old) syscall4(__NR_rt_sigaction, (sig), (long)(new), (long)(old), SYSCALL_SIGSET_SIZE) |
|||
#define __syscall_ioctl(fd,ioc,arg) syscall3(__NR_ioctl, (fd), (ioc), (long)(arg)) |
|||
#define __syscall_exit(code) syscall1(__NR_exit, code) |
|||
|
|||
long __syscall(long, ...); |
|||
|
|||
#endif |
|||
@ -1,9 +1,8 @@ |
|||
#include <stdlib.h> |
|||
#define SYSCALL_NORETURN |
|||
#include "syscall.h" |
|||
|
|||
void _Exit(int ec) |
|||
{ |
|||
syscall1(__NR_exit_group, ec); |
|||
syscall1(__NR_exit, ec); |
|||
__syscall(__NR_exit_group, ec); |
|||
__syscall(__NR_exit, ec); |
|||
} |
|||
|
|||
@ -0,0 +1,32 @@ |
|||
#ifndef _SYSCALL_H |
|||
#define _SYSCALL_H |
|||
|
|||
/* This header is mostly useless leftover wrapper cruft */ |
|||
|
|||
#include <sys/syscall.h> |
|||
|
|||
#define syscall0 syscall |
|||
#define syscall1 syscall |
|||
#define syscall2 syscall |
|||
#define syscall3 syscall |
|||
#define syscall4 syscall |
|||
#define syscall5 syscall |
|||
#define syscall6 syscall |
|||
|
|||
#define socketcall __socketcall |
|||
|
|||
/* the following are needed for iso c functions to use */ |
|||
#define __syscall_open(filename, flags, mode) syscall(__NR_open, (filename), (flags)|0100000, (mode)) |
|||
#define __syscall_read(fd, buf, len) syscall(__NR_read, (fd), (buf), (len)) |
|||
#define __syscall_write(fd, buf, len) syscall(__NR_write, (fd), (buf), (len)) |
|||
#define __syscall_close(fd) syscall(__NR_close, (fd)) |
|||
#define __syscall_fcntl(fd, cmd, arg) syscall(__NR_fcntl, (fd), (cmd), (arg)) |
|||
#define __syscall_dup2(old, new) syscall(__NR_dup2, (old), (new)) |
|||
#define __syscall_unlink(path) syscall(__NR_unlink, (path)) |
|||
#define __syscall_getpid() syscall(__NR_getpid) |
|||
#define __syscall_kill(pid,sig) syscall(__NR_kill, (pid), (sig)) |
|||
#define __syscall_sigaction(sig,new,old) syscall(__NR_rt_sigaction, (sig), (new), (old), 8) |
|||
#define __syscall_ioctl(fd,ioc,arg) syscall(__NR_ioctl, (fd), (ioc), (arg)) |
|||
#define __syscall_exit(code) syscall(__NR_exit, code) |
|||
|
|||
#endif |
|||
@ -1,9 +1,8 @@ |
|||
#define SYSCALL_RETURN_ERRNO |
|||
#include "pthread_impl.h" |
|||
|
|||
void __wake(volatile int *addr, int cnt, int priv) |
|||
{ |
|||
if (priv) priv = 128; priv=0; |
|||
if (cnt<0) cnt = INT_MAX; |
|||
syscall3(__NR_futex, (long)addr, FUTEX_WAKE | priv, cnt); |
|||
__syscall(__NR_futex, (long)addr, FUTEX_WAKE | priv, cnt); |
|||
} |
|||
|
|||
@ -1,7 +1,6 @@ |
|||
#define SYSCALL_RETURN_ERRNO |
|||
#include "pthread_impl.h" |
|||
|
|||
int pthread_cancel(pthread_t t) |
|||
{ |
|||
return syscall3(__NR_tgkill, t->pid, t->tid, SIGCANCEL); |
|||
return pthread_kill(t, SIGCANCEL); |
|||
} |
|||
|
|||
@ -1,7 +1,6 @@ |
|||
#define SYSCALL_RETURN_ERRNO |
|||
#include "pthread_impl.h" |
|||
|
|||
int pthread_kill(pthread_t t, int sig) |
|||
{ |
|||
return syscall3(__NR_tgkill, t->pid, t->tid, sig); |
|||
return __syscall(__NR_tgkill, t->pid, t->tid, sig); |
|||
} |
|||
|
|||
@ -1,9 +1,8 @@ |
|||
#define SYSCALL_RETURN_ERRNO |
|||
#include <sys/time.h> |
|||
#include "syscall.h" |
|||
|
|||
int gettimeofday(struct timeval *tv, void *tz) |
|||
{ |
|||
syscall2(__NR_gettimeofday, (long)tv, 0); |
|||
__syscall(__NR_gettimeofday, tv, 0); |
|||
return 0; |
|||
} |
|||
|
|||
Loading…
Reference in new issue