about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/internal/i386/syscall.s21
-rw-r--r--src/internal/syscall.c11
-rw-r--r--src/internal/syscall_ret.c11
-rw-r--r--src/internal/x86_64/syscall.s14
-rw-r--r--src/linux/syscall.c19
-rw-r--r--src/thread/pthread_create.c4
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;