blob: 1a6f6425932d78e13f0d570897610380ded199c3 [file] [log] [blame]
Elliott Hughes851e68a2014-02-19 16:53:20 -08001#include <private/bionic_asm.h>
The Android Open Source Project1dc9e472009-03-03 19:28:35 -08002
Elliott Hughes70b24b12013-11-15 11:51:07 -08003// pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg);
Elliott Hughesbdff26d2013-02-11 17:08:16 -08004ENTRY(__bionic_clone)
Jin Wei22d366c2012-08-08 15:15:16 +08005 pushl %ebx
Christopher Ferris605ee812015-04-13 14:20:11 -07006 .cfi_adjust_cfa_offset 4
7 .cfi_rel_offset ebx, 0
Jin Wei22d366c2012-08-08 15:15:16 +08008 pushl %esi
Christopher Ferris605ee812015-04-13 14:20:11 -07009 .cfi_adjust_cfa_offset 4
10 .cfi_rel_offset esi, 0
Jin Wei22d366c2012-08-08 15:15:16 +080011 pushl %edi
Christopher Ferris605ee812015-04-13 14:20:11 -070012 .cfi_adjust_cfa_offset 4
13 .cfi_rel_offset edi, 0
Jin Wei22d366c2012-08-08 15:15:16 +080014
Elliott Hughes0d236aa2014-05-09 14:42:16 -070015 # Load system call arguments into registers.
16 movl 16(%esp), %ebx # flags
17 movl 20(%esp), %ecx # child_stack
18 movl 24(%esp), %edx # parent_tid
19 movl 28(%esp), %esi # tls
20 movl 32(%esp), %edi # child_tid
Jin Wei22d366c2012-08-08 15:15:16 +080021
Elliott Hughes99c393d2013-11-26 16:20:50 -080022 # Copy 'fn' and 'arg' onto the child stack
23 movl 36(%esp), %eax # Read 'fn'.
24 movl %eax, -16(%ecx) # Write 'fn'.
25 movl 40(%esp), %eax # Read 'arg'.
26 movl %eax, -12(%ecx) # Write 'arg'.
Jin Wei22d366c2012-08-08 15:15:16 +080027 subl $16, %ecx
Elliott Hughesb6032512013-02-12 23:02:33 -080028
Elliott Hughes99c393d2013-11-26 16:20:50 -080029 # Make the system call.
Jin Wei22d366c2012-08-08 15:15:16 +080030 movl $__NR_clone, %eax
31 int $0x80
Elliott Hughesb6032512013-02-12 23:02:33 -080032
Elliott Hughes99c393d2013-11-26 16:20:50 -080033 # Check result.
Elliott Hughesaeb30162014-06-05 12:28:14 -070034 testl %eax, %eax
35 jz .L_bc_child
Elliott Hughesfff3c0f2014-05-09 12:16:20 -070036 jg .L_bc_parent
Jin Wei22d366c2012-08-08 15:15:16 +080037
Elliott Hughes99c393d2013-11-26 16:20:50 -080038 # An error occurred, so set errno and return -1.
Jin Wei22d366c2012-08-08 15:15:16 +080039 negl %eax
Elliott Hughesb6032512013-02-12 23:02:33 -080040 pushl %eax
Elliott Hughes011e1112014-09-08 15:25:01 -070041 call __set_errno_internal
Elliott Hughesb6032512013-02-12 23:02:33 -080042 addl $4, %esp
Elliott Hughesfff3c0f2014-05-09 12:16:20 -070043 jmp .L_bc_return
Jin Wei22d366c2012-08-08 15:15:16 +080044
Elliott Hughesfff3c0f2014-05-09 12:16:20 -070045.L_bc_child:
Elliott Hughesee9d5bd2014-05-30 11:15:32 -070046 # We don't want anyone to unwind past this point.
47 .cfi_undefined %eip
Elliott Hughesebc8cd12014-06-06 15:18:54 -070048 call __start_thread
Jin Wei22d366c2012-08-08 15:15:16 +080049 hlt
50
Elliott Hughesfff3c0f2014-05-09 12:16:20 -070051.L_bc_parent:
Elliott Hughesaeb30162014-06-05 12:28:14 -070052 # We're the parent; nothing to do.
Elliott Hughesfff3c0f2014-05-09 12:16:20 -070053.L_bc_return:
Jin Wei22d366c2012-08-08 15:15:16 +080054 popl %edi
Christopher Ferris605ee812015-04-13 14:20:11 -070055 .cfi_adjust_cfa_offset -4
56 .cfi_restore edi
Jin Wei22d366c2012-08-08 15:15:16 +080057 popl %esi
Christopher Ferris605ee812015-04-13 14:20:11 -070058 .cfi_adjust_cfa_offset -4
59 .cfi_restore esi
Jin Wei22d366c2012-08-08 15:15:16 +080060 popl %ebx
Christopher Ferris605ee812015-04-13 14:20:11 -070061 .cfi_adjust_cfa_offset -4
62 .cfi_restore ebx
Jin Wei22d366c2012-08-08 15:15:16 +080063 ret
Elliott Hughesbdff26d2013-02-11 17:08:16 -080064END(__bionic_clone)
Elliott Hughes954cf0d2014-05-08 19:00:23 -070065.hidden __bionic_clone