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 .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 call __start_thread 49 hlt 50 51 .L_bc_parent: 52 # We're the parent; nothing to do. 53 .L_bc_return: 54 popl %edi 55 .cfi_adjust_cfa_offset -4 56 .cfi_restore edi 57 popl %esi 58 .cfi_adjust_cfa_offset -4 59 .cfi_restore esi 60 popl %ebx 61 .cfi_adjust_cfa_offset -4 62 .cfi_restore ebx 63 ret 64 END(__bionic_clone) 65 .hidden __bionic_clone 66