11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/linux-syscalls.h>
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project.text
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * int  __pthread_clone(int (*fn)(void*), void *tls, int flags,
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *                      void *arg);
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project.globl __pthread_clone
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project.type __pthread_clone, @function
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project.align 4
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__pthread_clone:
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        pushl   %ebx
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        pushl   %ecx
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        movl    16(%esp), %ecx
16cb08204053a285951b1907ef14a832f16a1a4679Jack Ren
17cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        # save tls
18cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        movl    %ecx, %ebx
19cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        # 16-byte alignment on child stack
20cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        andl    $~15, %ecx
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        # insert arguments onto the child stack
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        movl    12(%esp), %eax
24cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        movl    %eax, -16(%ecx)
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        movl    24(%esp), %eax
26cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        movl    %eax, -12(%ecx)
27cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        movl    %ebx, -8(%ecx)
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
29e480fc83b2887388d469eb3bf58c86c610f5b082Jack Ren        subl    $16, %ecx
30cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        movl    20(%esp), %ebx
311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        movl    $__NR_clone, %eax
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        int     $0x80
331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        test    %eax, %eax
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        jns     1f
351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3622d366cc09383956dc264ed4641572e609392eeeJin Wei        # an error occurred, set errno and return -1
371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        negl    %eax
381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        call    __set_errno
391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        orl     $-1, %eax
401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        jmp     2f
411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project1:
431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        jnz     2f
441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        # we're in the child thread now, call __thread_entry
461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        # with the appropriate arguments on the child stack
471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        # we already placed most of them
48cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        call    __thread_entry
491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        hlt
501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project2:
521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        popl    %ecx
531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        popl    %ebx
541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        ret
5597cf7f3394780d524038fc083e2c134031b54728David 'Digit' Turner
5622d366cc09383956dc264ed4641572e609392eeeJin Wei
5722d366cc09383956dc264ed4641572e609392eeeJin Wei/*
5822d366cc09383956dc264ed4641572e609392eeeJin Wei * int  __bionic_clone(unsigned long clone_flags,
5922d366cc09383956dc264ed4641572e609392eeeJin Wei *                     void*         newsp,
6022d366cc09383956dc264ed4641572e609392eeeJin Wei *                     int           *parent_tidptr,
6122d366cc09383956dc264ed4641572e609392eeeJin Wei *                     void          *new_tls,
6222d366cc09383956dc264ed4641572e609392eeeJin Wei *                     int           *child_tidptr,
6322d366cc09383956dc264ed4641572e609392eeeJin Wei *                     int           (*fn)(void *),
6422d366cc09383956dc264ed4641572e609392eeeJin Wei *                     void          *arg);
6516984423bc67cd334d74b585bac2c01e44583624Bruce Beare */
6622d366cc09383956dc264ed4641572e609392eeeJin Wei.text
6722d366cc09383956dc264ed4641572e609392eeeJin Wei.globl __bionic_clone
6822d366cc09383956dc264ed4641572e609392eeeJin Wei.type __bionic_clone, @function
6922d366cc09383956dc264ed4641572e609392eeeJin Wei.align 4
7022d366cc09383956dc264ed4641572e609392eeeJin Wei__bionic_clone:
7122d366cc09383956dc264ed4641572e609392eeeJin Wei        pushl   %ebx
7222d366cc09383956dc264ed4641572e609392eeeJin Wei        pushl   %esi
7322d366cc09383956dc264ed4641572e609392eeeJin Wei        pushl   %edi
7422d366cc09383956dc264ed4641572e609392eeeJin Wei
7522d366cc09383956dc264ed4641572e609392eeeJin Wei        # insert arguments onto the child stack
7622d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    20(%esp), %ecx
7722d366cc09383956dc264ed4641572e609392eeeJin Wei        andl    $~15, %ecx
7822d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    36(%esp), %eax
7922d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    %eax, -16(%ecx)
8022d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    40(%esp), %eax
8122d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    %eax, -12(%ecx)
8222d366cc09383956dc264ed4641572e609392eeeJin Wei
8322d366cc09383956dc264ed4641572e609392eeeJin Wei        subl    $16, %ecx
8422d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    16(%esp), %ebx
8522d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    24(%esp), %edx
8622d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    32(%esp), %esi
8722d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    28(%esp), %edi
8822d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    $__NR_clone, %eax
8922d366cc09383956dc264ed4641572e609392eeeJin Wei        int     $0x80
9022d366cc09383956dc264ed4641572e609392eeeJin Wei        test    %eax, %eax
9122d366cc09383956dc264ed4641572e609392eeeJin Wei        jns     1f
9222d366cc09383956dc264ed4641572e609392eeeJin Wei
9322d366cc09383956dc264ed4641572e609392eeeJin Wei        # an error occurred, set errno and return -1
9422d366cc09383956dc264ed4641572e609392eeeJin Wei        negl    %eax
9522d366cc09383956dc264ed4641572e609392eeeJin Wei        call    __set_errno
9622d366cc09383956dc264ed4641572e609392eeeJin Wei        orl     $-1, %eax
9722d366cc09383956dc264ed4641572e609392eeeJin Wei        jmp     2f
9822d366cc09383956dc264ed4641572e609392eeeJin Wei
9922d366cc09383956dc264ed4641572e609392eeeJin Wei1:
10022d366cc09383956dc264ed4641572e609392eeeJin Wei        jnz     2f
10122d366cc09383956dc264ed4641572e609392eeeJin Wei
10222d366cc09383956dc264ed4641572e609392eeeJin Wei        # we're in the child now, call __bionic_clone_entry
10322d366cc09383956dc264ed4641572e609392eeeJin Wei        # with the appropriate arguments on the child stack
10422d366cc09383956dc264ed4641572e609392eeeJin Wei        # we already placed most of them
10522d366cc09383956dc264ed4641572e609392eeeJin Wei        call    __bionic_clone_entry
10622d366cc09383956dc264ed4641572e609392eeeJin Wei        hlt
10722d366cc09383956dc264ed4641572e609392eeeJin Wei
10822d366cc09383956dc264ed4641572e609392eeeJin Wei2:
10922d366cc09383956dc264ed4641572e609392eeeJin Wei        popl    %edi
11022d366cc09383956dc264ed4641572e609392eeeJin Wei        popl    %esi
11122d366cc09383956dc264ed4641572e609392eeeJin Wei        popl    %ebx
11222d366cc09383956dc264ed4641572e609392eeeJin Wei        ret
113