summaryrefslogtreecommitdiffstats
path: root/libc/arch-x86/bionic/__bionic_clone.S
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2013-11-19 13:31:58 -0800
committerElliott Hughes <enh@google.com>2013-11-19 14:08:54 -0800
commit36d6188f8cd8b948fb797f11d9620d63d0c2215a (patch)
tree86b3162cac031151b2ae44b4d554fce4f9456147 /libc/arch-x86/bionic/__bionic_clone.S
parent318e86ed887e04e593f3db9b84b402d5501ced9b (diff)
downloadbionic-36d6188f8cd8b948fb797f11d9620d63d0c2215a.zip
bionic-36d6188f8cd8b948fb797f11d9620d63d0c2215a.tar.gz
bionic-36d6188f8cd8b948fb797f11d9620d63d0c2215a.tar.bz2
Clean up forking and cloning.
The kernel now maintains the pthread_internal_t::tid field for us, and __clone was only used in one place so let's inline it so we don't have to leave such a dangerous function lying around. Also rename files to match their content and remove some useless #includes. Change-Id: I24299fb4a940e394de75f864ee36fdabbd9438f9
Diffstat (limited to 'libc/arch-x86/bionic/__bionic_clone.S')
-rw-r--r--libc/arch-x86/bionic/__bionic_clone.S54
1 files changed, 54 insertions, 0 deletions
diff --git a/libc/arch-x86/bionic/__bionic_clone.S b/libc/arch-x86/bionic/__bionic_clone.S
new file mode 100644
index 0000000..eb9f545
--- /dev/null
+++ b/libc/arch-x86/bionic/__bionic_clone.S
@@ -0,0 +1,54 @@
+#include <asm/unistd.h>
+#include <machine/asm.h>
+
+// pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg);
+ENTRY(__bionic_clone)
+ pushl %ebx
+ pushl %esi
+ pushl %edi
+
+ # insert arguments onto the child stack
+ movl 20(%esp), %ecx
+ andl $~15, %ecx
+ movl 36(%esp), %eax
+ movl %eax, -16(%ecx)
+ movl 40(%esp), %eax
+ movl %eax, -12(%ecx)
+
+ subl $16, %ecx
+ movl 16(%esp), %ebx
+ movl 24(%esp), %edx
+ movl 32(%esp), %esi
+ movl 28(%esp), %edi
+
+ # make system call
+ movl $__NR_clone, %eax
+ int $0x80
+
+ cmpl $0, %eax
+ je bc_child
+ jg bc_parent
+
+ # an error occurred, set errno and return -1
+ negl %eax
+ pushl %eax
+ call __set_errno
+ addl $4, %esp
+ orl $-1, %eax
+ jmp bc_return
+
+bc_child:
+ # we're in the child now, call __bionic_clone_entry
+ # with the appropriate arguments on the child stack
+ # we already placed most of them
+ call __bionic_clone_entry
+ hlt
+
+bc_parent:
+ # we're the parent; nothing to do.
+bc_return:
+ popl %edi
+ popl %esi
+ popl %ebx
+ ret
+END(__bionic_clone)