Implement clone() C library function properly.

Only provide an implementation for ARM at the moment, since
it requires specific assembly fragments (the standard syscall
stubs cannot be used because the child returns in a different
stack).
diff --git a/libc/arch-arm/bionic/clone.S b/libc/arch-arm/bionic/clone.S
index 791c73d..9c25053 100644
--- a/libc/arch-arm/bionic/clone.S
+++ b/libc/arch-arm/bionic/clone.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 The Android Open Source Project
+ * Copyright (C) 2008-2010 The Android Open Source Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,48 +27,102 @@
  */
 #include <sys/linux-syscalls.h>
 
-	.text
-	.type __pthread_clone, #function
-	.global __pthread_clone
-	.align 4
-    
-__pthread_clone:
-	@ insert the args onto the new stack
-	str     r0, [r1, #-4]
-	str     r3, [r1, #-8]
+    .text
+    .type __pthread_clone, #function
+    .global __pthread_clone
+    .align 4
+    .fnstart
 
-	@ do the system call
-	@ get flags
-	
+__pthread_clone:
+    @ insert the args onto the new stack
+    str     r0, [r1, #-4]
+    str     r3, [r1, #-8]
+
+    @ do the system call
+    @ get flags
+
     mov     r0, r2
-	
+
     @ new sp is already in r1
 
 #if __ARM_EABI__
     stmfd   sp!, {r4, r7}
     ldr     r7, =__NR_clone
-	swi     #0
+    swi     #0
 #else
-	swi     #__NR_clone
+    swi     #__NR_clone
 #endif
 
-	movs    r0, r0
+    movs    r0, r0
 #if __ARM_EABI__
     ldmnefd sp!, {r4, r7}
 #endif
-	blt     __error
-	bxne    lr
+    blt     __error
+    bxne    lr
 
 
-	@ pick the function arg and call address off the stack and jump
-	@ to the C __thread_entry function which does some setup and then
-	@ calls the thread's start function
+    @ pick the function arg and call address off the stack and jump
+    @ to the C __thread_entry function which does some setup and then
+    @ calls the thread's start function
 
-	ldr     r0, [sp, #-4]
-	ldr     r1, [sp, #-8]
-	mov     r2, sp			@ __thread_entry needs the TLS pointer
-	b       __thread_entry
+    ldr     r0, [sp, #-4]
+    ldr     r1, [sp, #-8]
+    mov     r2, sp			@ __thread_entry needs the TLS pointer
+    b       __thread_entry
 
 __error:
-	mov     r0, #-1
-	bx      lr
+    mov     r0, #-1
+    bx      lr
+    .fnend
+
+
+    #
+    # This function is defined as:
+    #
+    #   pid_t  __bionic_clone( int  flags, void *child_stack,
+    #                          pid_t *pid, void *tls, pid_t *ctid,
+    #                          int  (*fn)(void *), void* arg );
+    #
+    # NOTE: This is not the same signature than the GLibc
+    #       __clone function here !! Placing 'fn' and 'arg'
+    #       at the end of the parameter list makes the
+    #       implementation much simpler.
+    #
+    .type __bionic_clone, #function
+    .globl __bionic_clone
+    .align 4
+    .fnstart
+
+__bionic_clone:
+    mov     ip, sp
+    .save   {r4, r5, r6, r7}
+
+    # save registers to parent stack
+    stmfd   sp!, {r4, r5, r6, r7}
+
+    # load extra parameters
+    ldmfd   ip, {r4, r5, r6}
+
+    # store 'fn' and 'arg' to the child stack
+    str     r5, [r1, #-4]
+    str     r6, [r1, #-8]
+
+    # system call
+    ldr     r7, =__NR_clone
+    swi     #0
+    movs    r0, r0
+    beq     1f
+
+    # in parent, reload saved registers
+    # then either exit or error
+    #
+    ldmfd   sp!, {r4, r5, r6, r7}
+    bxne    lr
+    b       __set_syscall_errno
+
+1:  # in the child - pick arguments
+    ldr    r0, [sp, #-4]
+    ldr    r1, [sp, #-8]
+    b      __bionic_clone_entry
+
+    .fnend
diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk
index 706cb0c..5f416e8 100644
--- a/libc/arch-arm/syscalls.mk
+++ b/libc/arch-arm/syscalls.mk
@@ -4,7 +4,7 @@
 syscall_src += arch-arm/syscalls/_exit_thread.S
 syscall_src += arch-arm/syscalls/__fork.S
 syscall_src += arch-arm/syscalls/waitid.S
-syscall_src += arch-arm/syscalls/__clone.S
+syscall_src += arch-arm/syscalls/__sys_clone.S
 syscall_src += arch-arm/syscalls/execve.S
 syscall_src += arch-arm/syscalls/setuid.S
 syscall_src += arch-arm/syscalls/getuid.S
diff --git a/libc/arch-arm/syscalls/__clone.S b/libc/arch-arm/syscalls/__clone.S
deleted file mode 100644
index 650e2c0..0000000
--- a/libc/arch-arm/syscalls/__clone.S
+++ /dev/null
@@ -1,19 +0,0 @@
-/* autogenerated by gensyscalls.py */
-#include <sys/linux-syscalls.h>
-
-    .text
-    .type __clone, #function
-    .globl __clone
-    .align 4
-    .fnstart
-
-__clone:
-    .save   {r4, r7}
-    stmfd   sp!, {r4, r7}
-    ldr     r7, =__NR_clone
-    swi     #0
-    ldmfd   sp!, {r4, r7}
-    movs    r0, r0
-    bxpl    lr
-    b       __set_syscall_errno
-    .fnend
diff --git a/libc/arch-arm/syscalls/__sys_clone.S b/libc/arch-arm/syscalls/__sys_clone.S
new file mode 100644
index 0000000..9fe2641
--- /dev/null
+++ b/libc/arch-arm/syscalls/__sys_clone.S
@@ -0,0 +1,21 @@
+/* autogenerated by gensyscalls.py */
+#include <sys/linux-syscalls.h>
+
+    .text
+    .type __sys_clone, #function
+    .globl __sys_clone
+    .align 4
+    .fnstart
+
+__sys_clone:
+    mov     ip, sp
+    .save   {r4, r5, r6, r7}
+    stmfd   sp!, {r4, r5, r6, r7}
+    ldmfd   ip, {r4, r5, r6}
+    ldr     r7, =__NR_clone
+    swi     #0
+    ldmfd   sp!, {r4, r5, r6, r7}
+    movs    r0, r0
+    bxpl    lr
+    b       __set_syscall_errno
+    .fnend