enable clone system call for x86

Add __bionic_clone function for x86, which will be
used for clone system call.

Change-Id: I889dc9bf4b7ebb4358476e17e6f3233e26491f4d
Signed-off-by: Jin Wei <wei.a.jin@intel.com>
Signed-off-by: Xiaokang Qin <xiaokang.qin@intel.com>
Signed-off-by: Beare, Bruce J <bruce.j.beare@intel.com>
Signed-off-by: Jack Ren <jack.ren@intel.com>
Author-tracking-BZ: 51414
diff --git a/libc/arch-x86/bionic/clone.S b/libc/arch-x86/bionic/clone.S
index 352d23c..54b6ef2 100644
--- a/libc/arch-x86/bionic/clone.S
+++ b/libc/arch-x86/bionic/clone.S
@@ -33,7 +33,7 @@
         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 @@
         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