diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/internal/i386/syscall.s | 21 | ||||
-rw-r--r-- | src/internal/syscall.c | 11 | ||||
-rw-r--r-- | src/internal/syscall_ret.c | 11 | ||||
-rw-r--r-- | src/internal/x86_64/syscall.s | 14 | ||||
-rw-r--r-- | src/linux/syscall.c | 19 | ||||
-rw-r--r-- | src/thread/pthread_create.c | 4 |
6 files changed, 67 insertions, 13 deletions
diff --git a/src/internal/i386/syscall.s b/src/internal/i386/syscall.s new file mode 100644 index 00000000..5b19a1b8 --- /dev/null +++ b/src/internal/i386/syscall.s @@ -0,0 +1,21 @@ +.global __syscall +.type __syscall,%function +__syscall: + pushl %ebx + pushl %esi + pushl %edi + pushl %ebp + movl 20(%esp),%eax + movl 24(%esp),%ebx + movl 28(%esp),%ecx + movl 32(%esp),%edx + movl 36(%esp),%esi + movl 40(%esp),%edi + movl 44(%esp),%ebp + int $128 + popl %ebp + popl %edi + popl %esi + popl %ebx + ret +.size __syscall,.-__syscall diff --git a/src/internal/syscall.c b/src/internal/syscall.c index 4f159e0b..e69de29b 100644 --- a/src/internal/syscall.c +++ b/src/internal/syscall.c @@ -1,11 +0,0 @@ -#include <errno.h> -#include <unistd.h> - -long __syscall_ret(unsigned long r) -{ - if (r >= (unsigned long)-1 - 4096) { - errno = -(long)r; - return -1; - } - return (long)r; -} diff --git a/src/internal/syscall_ret.c b/src/internal/syscall_ret.c new file mode 100644 index 00000000..4f159e0b --- /dev/null +++ b/src/internal/syscall_ret.c @@ -0,0 +1,11 @@ +#include <errno.h> +#include <unistd.h> + +long __syscall_ret(unsigned long r) +{ + if (r >= (unsigned long)-1 - 4096) { + errno = -(long)r; + return -1; + } + return (long)r; +} diff --git a/src/internal/x86_64/syscall.s b/src/internal/x86_64/syscall.s new file mode 100644 index 00000000..7bec7291 --- /dev/null +++ b/src/internal/x86_64/syscall.s @@ -0,0 +1,14 @@ +.global __syscall +.type __syscall,%function +__syscall: +di,si,dx,cx,r8,r9 + movq %rdi,%rax + movq %rsi,%rdi + movq %rdx,%rsi + movq %rcx,%rdx + movq %r8,%r10 + movq %r9,%r8 + movq 8(%rsp),%r9 + syscall + ret +.size __syscall,.-__syscall diff --git a/src/linux/syscall.c b/src/linux/syscall.c new file mode 100644 index 00000000..15355609 --- /dev/null +++ b/src/linux/syscall.c @@ -0,0 +1,19 @@ +#include "syscall.h" +#include <stdarg.h> + +#undef syscall + +long syscall(long n, ...) +{ + va_list ap; + long a,b,c,d,e,f; + va_start(ap, n); + a=va_arg(ap, long); + b=va_arg(ap, long); + c=va_arg(ap, long); + d=va_arg(ap, long); + e=va_arg(ap, long); + f=va_arg(ap, long); + va_end(ap); + return __syscall_ret(__syscall(n,a,b,c,d,e,f)); +} diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c index 7494a486..fccfa191 100644 --- a/src/thread/pthread_create.c +++ b/src/thread/pthread_create.c @@ -91,7 +91,7 @@ static void rsyscall_handler(int sig, siginfo_t *si, void *ctx) return; } - if (syscall6(rs.nr, rs.arg[0], rs.arg[1], rs.arg[2], + if (__syscall(rs.nr, rs.arg[0], rs.arg[1], rs.arg[2], rs.arg[3], rs.arg[4], rs.arg[5]) < 0 && !rs.err) rs.err=errno; a_inc(&rs.cnt); @@ -140,7 +140,7 @@ static int rsyscall(int nr, long a, long b, long c, long d, long e, long f) while((i=rs.cnt)) __wait(&rs.cnt, 0, i, 1); if (rs.err) errno = rs.err, ret = -1; - else ret = syscall6(nr, a, b, c, d, e, f); + else ret = __syscall(nr, a, b, c, d, e, f); UNLOCK(&rs.lock); return ret; |