diff --git a/libc/Android.mk b/libc/Android.mk index 51cef8ad7..c66ec5936 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -261,6 +261,7 @@ libc_common_src_files := \ tzcode/strftime.c \ tzcode/strptime.c \ bionic/__set_errno.c \ + bionic/bionic_clone.c \ bionic/cpuacct.c \ bionic/arc4random.c \ bionic/basename.c \ @@ -361,7 +362,6 @@ libc_static_common_src_files := \ # ========================================================= ifeq ($(TARGET_ARCH),arm) libc_common_src_files += \ - bionic/bionic_clone.c \ arch-arm/bionic/__get_pc.S \ arch-arm/bionic/__get_sp.S \ arch-arm/bionic/_exit_with_stack_teardown.S \ @@ -451,7 +451,6 @@ endif # x86 ifeq ($(TARGET_ARCH),mips) libc_common_src_files += \ - bionic/bionic_clone.c \ arch-mips/bionic/__get_sp.S \ arch-mips/bionic/__get_tls.c \ arch-mips/bionic/__set_tls.c \ diff --git a/libc/arch-x86/bionic/clone.S b/libc/arch-x86/bionic/clone.S index 352d23c5c..54b6ef208 100644 --- a/libc/arch-x86/bionic/clone.S +++ b/libc/arch-x86/bionic/clone.S @@ -33,7 +33,7 @@ __pthread_clone: test %eax, %eax jns 1f - # an error occured, set errno and return -1 + # an error occurred, set errno and return -1 negl %eax call __set_errno orl $-1, %eax @@ -53,7 +53,60 @@ __pthread_clone: popl %ebx ret -/* XXX: TODO: Add __bionic_clone here - * See bionic/bionic_clone.c and arch-arm/bionic/clone.S - * for more details... + +/* + * int __bionic_clone(unsigned long clone_flags, + * void* newsp, + * int *parent_tidptr, + * void *new_tls, + * int *child_tidptr, + * int (*fn)(void *), + * void *arg); */ +.text +.globl __bionic_clone +.type __bionic_clone, @function +.align 4 +__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 + movl $__NR_clone, %eax + int $0x80 + test %eax, %eax + jns 1f + + # an error occurred, set errno and return -1 + negl %eax + call __set_errno + orl $-1, %eax + jmp 2f + +1: + jnz 2f + + # 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 + +2: + popl %edi + popl %esi + popl %ebx + ret diff --git a/libc/bionic/bionic_clone.c b/libc/bionic/bionic_clone.c index 6b2fa58f6..187b60df4 100644 --- a/libc/bionic/bionic_clone.c +++ b/libc/bionic/bionic_clone.c @@ -31,9 +31,6 @@ #include #include -/* WARNING: AT THE MOMENT, THIS IS ONLY SUPPORTED ON ARM - */ - extern int __bionic_clone(unsigned long clone_flags, void* newsp, int *parent_tidptr,