1 #include <private/bionic_asm.h> 2 3 // pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg); 4 ENTRY(__bionic_clone) 5 pushl %ebx 6 pushl %esi 7 pushl %edi 8 9 # Load system call arguments into registers. 10 movl 16(%esp), %ebx # flags 11 movl 20(%esp), %ecx # child_stack 12 movl 24(%esp), %edx # parent_tid 13 movl 28(%esp), %esi # tls 14 movl 32(%esp), %edi # child_tid 15 16 # Copy 'fn' and 'arg' onto the child stack 17 movl 36(%esp), %eax # Read 'fn'. 18 movl %eax, -16(%ecx) # Write 'fn'. 19 movl 40(%esp), %eax # Read 'arg'. 20 movl %eax, -12(%ecx) # Write 'arg'. 21 subl $16, %ecx 22 23 # Make the system call. 24 movl $__NR_clone, %eax 25 int $0x80 26 27 # Check result. 28 testl %eax, %eax 29 jz .L_bc_child 30 jg .L_bc_parent 31 32 # An error occurred, so set errno and return -1. 33 negl %eax 34 pushl %eax 35 call __set_errno_internal 36 addl $4, %esp 37 jmp .L_bc_return 38 39 .L_bc_child: 40 # We don't want anyone to unwind past this point. 41 .cfi_undefined %eip 42 call __start_thread 43 hlt 44 45 .L_bc_parent: 46 # We're the parent; nothing to do. 47 .L_bc_return: 48 popl %edi 49 popl %esi 50 popl %ebx 51 ret 52 END(__bionic_clone) 53 .hidden __bionic_clone 54