Index: fusl/src/internal/i386/syscall.s |
diff --git a/fusl/src/internal/i386/syscall.s b/fusl/src/internal/i386/syscall.s |
new file mode 100644 |
index 0000000000000000000000000000000000000000..0ebf221842159ad2aeda5abc8753f9340abf1014 |
--- /dev/null |
+++ b/fusl/src/internal/i386/syscall.s |
@@ -0,0 +1,78 @@ |
+.hidden __sysinfo |
+ |
+# The calling convention for __vsyscall has the syscall number |
+# and 5 args arriving as: eax, edx, ecx, edi, esi, 4(%esp). |
+# This ensures that the inline asm in the C code never has to touch |
+# ebx or ebp (which are unavailable in PIC and frame-pointer-using |
+# code, respectively), and optimizes for size/simplicity in the caller. |
+ |
+.global __vsyscall |
+.hidden __vsyscall |
+.type __vsyscall,@function |
+__vsyscall: |
+ push %edi |
+ push %ebx |
+ mov %edx,%ebx |
+ mov %edi,%edx |
+ mov 12(%esp),%edi |
+ push %eax |
+ call 1f |
+2: mov %ebx,%edx |
+ pop %ebx |
+ pop %ebx |
+ pop %edi |
+ ret |
+ |
+1: mov (%esp),%eax |
+ add $[__sysinfo-2b],%eax |
+ mov (%eax),%eax |
+ test %eax,%eax |
+ jz 1f |
+ push %eax |
+ mov 8(%esp),%eax |
+ ret # tail call to kernel vsyscall entry |
+1: mov 4(%esp),%eax |
+ int $128 |
+ ret |
+ |
+# The __vsyscall6 entry point is used only for 6-argument syscalls. |
+# Instead of passing the 5th argument on the stack, a pointer to the |
+# 5th and 6th arguments is passed. This is ugly, but there are no |
+# register constraints the inline asm could use that would make it |
+# possible to pass two arguments on the stack. |
+ |
+.global __vsyscall6 |
+.hidden __vsyscall6 |
+.type __vsyscall6,@function |
+__vsyscall6: |
+ push %ebp |
+ push %eax |
+ mov 12(%esp), %ebp |
+ mov (%ebp), %eax |
+ mov 4(%ebp), %ebp |
+ push %eax |
+ mov 4(%esp),%eax |
+ call __vsyscall |
+ pop %ebp |
+ pop %ebp |
+ pop %ebp |
+ ret |
+ |
+.global __syscall |
+.hidden __syscall |
+.type __syscall,@function |
+__syscall: |
+ lea 24(%esp),%eax |
+ push %esi |
+ push %edi |
+ push %eax |
+ mov 16(%esp),%eax |
+ mov 20(%esp),%edx |
+ mov 24(%esp),%ecx |
+ mov 28(%esp),%edi |
+ mov 32(%esp),%esi |
+ call __vsyscall6 |
+ pop %edi |
+ pop %edi |
+ pop %esi |
+ ret |