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); 4ENTRY_PRIVATE(__bionic_clone) 5 pushl %ebx 6 .cfi_adjust_cfa_offset 4 7 .cfi_rel_offset ebx, 0 8 pushl %esi 9 .cfi_adjust_cfa_offset 4 10 .cfi_rel_offset esi, 0 11 pushl %edi 12 .cfi_adjust_cfa_offset 4 13 .cfi_rel_offset edi, 0 14 15 # 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 21 22 # 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'. 27 subl $16, %ecx 28 29 # Make the system call. 30 movl $__NR_clone, %eax 31 int $0x80 32 33 # Check result. 34 testl %eax, %eax 35 jz .L_bc_child 36 jg .L_bc_parent 37 38 # An error occurred, so set errno and return -1. 39 negl %eax 40 pushl %eax 41 call __set_errno_internal 42 addl $4, %esp 43 jmp .L_bc_return 44 45.L_bc_child: 46 # We don't want anyone to unwind past this point. 47 .cfi_undefined %eip 48 .cfi_undefined %ebp 49 call __start_thread 50 hlt 51 52.L_bc_parent: 53 # We're the parent; nothing to do. 54.L_bc_return: 55 popl %edi 56 .cfi_adjust_cfa_offset -4 57 .cfi_restore edi 58 popl %esi 59 .cfi_adjust_cfa_offset -4 60 .cfi_restore esi 61 popl %ebx 62 .cfi_adjust_cfa_offset -4 63 .cfi_restore ebx 64 ret 65END(__bionic_clone) 66