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/Android.mk b/libc/Android.mk
index 51cef8a..c66ec59 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -261,6 +261,7 @@
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 @@
# =========================================================
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 @@
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 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
diff --git a/libc/bionic/bionic_clone.c b/libc/bionic/bionic_clone.c
index 6b2fa58..187b60d 100644
--- a/libc/bionic/bionic_clone.c
+++ b/libc/bionic/bionic_clone.c
@@ -31,9 +31,6 @@
#include <stdarg.h>
#include <stdio.h>
-/* WARNING: AT THE MOMENT, THIS IS ONLY SUPPORTED ON ARM
- */
-
extern int __bionic_clone(unsigned long clone_flags,
void* newsp,
int *parent_tidptr,