1 #include <asm/unistd.h> 2 #include <machine/asm.h> 3 4 // int __pthread_clone(void* (*fn)(void*), void* tls, int flags, void* arg); 5 ENTRY(__pthread_clone) 6 pushl %ebx 7 pushl %ecx 8 movl 16(%esp), %ecx 9 10 # save tls 11 movl %ecx, %ebx 12 # 16-byte alignment on child stack 13 andl $~15, %ecx 14 15 # insert arguments onto the child stack 16 movl 12(%esp), %eax 17 movl %eax, -16(%ecx) 18 movl 24(%esp), %eax 19 movl %eax, -12(%ecx) 20 movl %ebx, -8(%ecx) 21 22 subl $16, %ecx 23 movl 20(%esp), %ebx 24 25 # make system call 26 movl $__NR_clone, %eax 27 int $0x80 28 29 cmpl $0, %eax 30 je pc_child 31 jg pc_parent 32 33 # an error occurred, set errno and return -1 34 negl %eax 35 pushl %eax 36 call __set_errno 37 addl $4, %esp 38 orl $-1, %eax 39 jmp pc_return 40 41 pc_child: 42 # we're in the child thread now, call __thread_entry 43 # with the appropriate arguments on the child stack 44 # we already placed most of them 45 call __thread_entry 46 hlt 47 48 pc_parent: 49 # we're the parent; nothing to do. 50 pc_return: 51 popl %ecx 52 popl %ebx 53 ret 54 END(__pthread_clone) 55 56 57 /* 58 * int __bionic_clone(unsigned long clone_flags, 59 * void* newsp, 60 * int *parent_tidptr, 61 * void *new_tls, 62 * int *child_tidptr, 63 * int (*fn)(void *), 64 * void *arg); 65 */ 66 ENTRY(__bionic_clone) 67 pushl %ebx 68 pushl %esi 69 pushl %edi 70 71 # insert arguments onto the child stack 72 movl 20(%esp), %ecx 73 andl $~15, %ecx 74 movl 36(%esp), %eax 75 movl %eax, -16(%ecx) 76 movl 40(%esp), %eax 77 movl %eax, -12(%ecx) 78 79 subl $16, %ecx 80 movl 16(%esp), %ebx 81 movl 24(%esp), %edx 82 movl 32(%esp), %esi 83 movl 28(%esp), %edi 84 85 # make system call 86 movl $__NR_clone, %eax 87 int $0x80 88 89 cmpl $0, %eax 90 je bc_child 91 jg bc_parent 92 93 # an error occurred, set errno and return -1 94 negl %eax 95 pushl %eax 96 call __set_errno 97 addl $4, %esp 98 orl $-1, %eax 99 jmp bc_return 100 101 bc_child: 102 # we're in the child now, call __bionic_clone_entry 103 # with the appropriate arguments on the child stack 104 # we already placed most of them 105 call __bionic_clone_entry 106 hlt 107 108 bc_parent: 109 # we're the parent; nothing to do. 110 bc_return: 111 popl %edi 112 popl %esi 113 popl %ebx 114 ret 115 END(__bionic_clone) 116