diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:03:48 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2008-12-17 18:03:48 -0800 |
commit | 4e468ed2eb86a2406e14f1eca82072ee501d05fd (patch) | |
tree | 4e05b3c66eef86531e464521a3bf96a1864d4bf5 /libc/arch-x86/bionic/clone.S | |
parent | a27d2baa0c1a2ec70f47ea9199b1dd6762c8a349 (diff) | |
download | bionic-4e468ed2eb86a2406e14f1eca82072ee501d05fd.zip bionic-4e468ed2eb86a2406e14f1eca82072ee501d05fd.tar.gz bionic-4e468ed2eb86a2406e14f1eca82072ee501d05fd.tar.bz2 |
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'libc/arch-x86/bionic/clone.S')
-rw-r--r-- | libc/arch-x86/bionic/clone.S | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/libc/arch-x86/bionic/clone.S b/libc/arch-x86/bionic/clone.S new file mode 100644 index 0000000..361808d --- /dev/null +++ b/libc/arch-x86/bionic/clone.S @@ -0,0 +1,50 @@ +#include <sys/linux-syscalls.h> + +.text + +/* + * int __pthread_clone(int (*fn)(void*), void *tls, int flags, + * void *arg); + */ +.globl __pthread_clone +.type __pthread_clone, @function +.align 4 +__pthread_clone: + pushl %ebx + pushl %ecx + movl 16(%esp), %ecx + movl 20(%esp), %ebx + + # insert arguments onto the child stack + movl 12(%esp), %eax + movl %eax, -12(%ecx) + movl 24(%esp), %eax + movl %eax, -8(%ecx) + lea (%ecx), %eax + movl %eax, -4(%ecx) + + movl $__NR_clone, %eax + int $0x80 + test %eax, %eax + jns 1f + + # an error occured, set errno and return -1 + negl %eax + call __set_errno + orl $-1, %eax + jmp 2f + +1: + jnz 2f + + # we're in the child thread now, call __thread_entry + # with the appropriate arguments on the child stack + # we already placed most of them + subl $16, %esp + jmp __thread_entry + hlt + +2: + popl %ecx + popl %ebx + ret |