1#include <sys/linux-syscalls.h>
2
3.text
4
5/*
6 * int  __pthread_clone(int (*fn)(void*), void *tls, int flags,
7 *                      void *arg);
8 */
9.globl __pthread_clone
10.type __pthread_clone, @function
11.align 4
12__pthread_clone:
13        pushl   %ebx
14        pushl   %ecx
15        movl    16(%esp), %ecx
16
17        # save tls
18        movl    %ecx, %ebx
19        # 16-byte alignment on child stack
20        andl    $~15, %ecx
21
22        # insert arguments onto the child stack
23        movl    12(%esp), %eax
24        movl    %eax, -16(%ecx)
25        movl    24(%esp), %eax
26        movl    %eax, -12(%ecx)
27        movl    %ebx, -8(%ecx)
28
29        subl    $16, %ecx
30        movl    20(%esp), %ebx
31        movl    $__NR_clone, %eax
32        int     $0x80
33        test    %eax, %eax
34        jns     1f
35
36        # an error occurred, set errno and return -1
37        negl    %eax
38        call    __set_errno
39        orl     $-1, %eax
40        jmp     2f
41
421:
43        jnz     2f
44
45        # we're in the child thread now, call __thread_entry
46        # with the appropriate arguments on the child stack
47        # we already placed most of them
48        call    __thread_entry
49        hlt
50
512:
52        popl    %ecx
53        popl    %ebx
54        ret
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.text
67.globl __bionic_clone
68.type __bionic_clone, @function
69.align 4
70__bionic_clone:
71        pushl   %ebx
72        pushl   %esi
73        pushl   %edi
74
75        # insert arguments onto the child stack
76        movl    20(%esp), %ecx
77        andl    $~15, %ecx
78        movl    36(%esp), %eax
79        movl    %eax, -16(%ecx)
80        movl    40(%esp), %eax
81        movl    %eax, -12(%ecx)
82
83        subl    $16, %ecx
84        movl    16(%esp), %ebx
85        movl    24(%esp), %edx
86        movl    32(%esp), %esi
87        movl    28(%esp), %edi
88        movl    $__NR_clone, %eax
89        int     $0x80
90        test    %eax, %eax
91        jns     1f
92
93        # an error occurred, set errno and return -1
94        negl    %eax
95        call    __set_errno
96        orl     $-1, %eax
97        jmp     2f
98
991:
100        jnz     2f
101
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
1082:
109        popl    %edi
110        popl    %esi
111        popl    %ebx
112        ret
113