summaryrefslogtreecommitdiffstats
path: root/libc/arch-x86/bionic/vfork.S
diff options
context:
space:
mode:
Diffstat (limited to 'libc/arch-x86/bionic/vfork.S')
-rw-r--r--libc/arch-x86/bionic/vfork.S30
1 files changed, 30 insertions, 0 deletions
diff --git a/libc/arch-x86/bionic/vfork.S b/libc/arch-x86/bionic/vfork.S
new file mode 100644
index 0000000..53910ab
--- /dev/null
+++ b/libc/arch-x86/bionic/vfork.S
@@ -0,0 +1,30 @@
+#include <sys/linux-syscalls.h>
+
+#ifndef __NR_vfork
+#define __NR_vfork 190
+#endif
+
+
+ .text
+ .type vfork, @function
+ .globl vfork
+ .align 4
+
+/* Get rid of the stack modifications (popl/ret) after vfork() success.
+ * vfork is VERY sneaky. One has to be very careful about what can be done
+ * between a successful vfork and a a subsequent execve()
+ */
+
+vfork:
+ /* grab the return address */
+ popl %ecx
+ movl $__NR_vfork, %eax
+ int $0x80
+ cmpl $-129, %eax
+ jb 1f
+ negl %eax
+ pushl %eax
+ call __set_errno
+ orl $-1, %eax
+1:
+ jmp *%ecx