__bionic_clone.S revision b6032515a058fb02c8c4152c9f055bb3bd462ae2
1bdff26df2749d8d66e5d4eb5a2ecf4a9ff50fad2Elliott Hughes#include <machine/asm.h>
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/linux-syscalls.h>
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
45e3fc43ddeada547a155c6f561a12ff0b16e02d3Elliott Hughes// int  __pthread_clone(int (*fn)(void*), void* tls, int flags, void* arg);
5bdff26df2749d8d66e5d4eb5a2ecf4a9ff50fad2Elliott HughesENTRY(__pthread_clone)
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        pushl   %ebx
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        pushl   %ecx
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        movl    16(%esp), %ecx
9cb08204053a285951b1907ef14a832f16a1a4679Jack Ren
10cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        # save tls
11cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        movl    %ecx, %ebx
12cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        # 16-byte alignment on child stack
13cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        andl    $~15, %ecx
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        # insert arguments onto the child stack
161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        movl    12(%esp), %eax
17cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        movl    %eax, -16(%ecx)
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        movl    24(%esp), %eax
19cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        movl    %eax, -12(%ecx)
20cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        movl    %ebx, -8(%ecx)
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
22e480fc83b2887388d469eb3bf58c86c610f5b082Jack Ren        subl    $16, %ecx
23cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        movl    20(%esp), %ebx
24b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes
25b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        # make system call
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        movl    $__NR_clone, %eax
271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        int     $0x80
28b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes
29b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        cmpl    $0, %eax
30b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        je      pc_child
31b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        jg      pc_parent
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3322d366cc09383956dc264ed4641572e609392eeeJin Wei        # an error occurred, set errno and return -1
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        negl    %eax
35b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        pushl   %eax
361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        call    __set_errno
37b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        addl    $4, %esp
381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        orl     $-1, %eax
39b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        jmp     pc_return
401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
41b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughespc_child:
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        # we're in the child thread now, call __thread_entry
431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        # with the appropriate arguments on the child stack
441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        # we already placed most of them
45cb08204053a285951b1907ef14a832f16a1a4679Jack Ren        call    __thread_entry
461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        hlt
471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
48b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughespc_parent:
49b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        # we're the parent; nothing to do.
50b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughespc_return:
511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        popl    %ecx
521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        popl    %ebx
531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project        ret
54bdff26df2749d8d66e5d4eb5a2ecf4a9ff50fad2Elliott HughesEND(__pthread_clone)
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 */
66bdff26df2749d8d66e5d4eb5a2ecf4a9ff50fad2Elliott HughesENTRY(__bionic_clone)
6722d366cc09383956dc264ed4641572e609392eeeJin Wei        pushl   %ebx
6822d366cc09383956dc264ed4641572e609392eeeJin Wei        pushl   %esi
6922d366cc09383956dc264ed4641572e609392eeeJin Wei        pushl   %edi
7022d366cc09383956dc264ed4641572e609392eeeJin Wei
7122d366cc09383956dc264ed4641572e609392eeeJin Wei        # insert arguments onto the child stack
7222d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    20(%esp), %ecx
7322d366cc09383956dc264ed4641572e609392eeeJin Wei        andl    $~15, %ecx
7422d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    36(%esp), %eax
7522d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    %eax, -16(%ecx)
7622d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    40(%esp), %eax
7722d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    %eax, -12(%ecx)
7822d366cc09383956dc264ed4641572e609392eeeJin Wei
7922d366cc09383956dc264ed4641572e609392eeeJin Wei        subl    $16, %ecx
8022d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    16(%esp), %ebx
8122d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    24(%esp), %edx
8222d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    32(%esp), %esi
8322d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    28(%esp), %edi
84b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes
85b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        # make system call
8622d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    $__NR_clone, %eax
8722d366cc09383956dc264ed4641572e609392eeeJin Wei        int     $0x80
88b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes
89b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        cmpl    $0, %eax
90b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        je      bc_child
91b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        jg      bc_parent
9222d366cc09383956dc264ed4641572e609392eeeJin Wei
9322d366cc09383956dc264ed4641572e609392eeeJin Wei        # an error occurred, set errno and return -1
9422d366cc09383956dc264ed4641572e609392eeeJin Wei        negl    %eax
95b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        pushl   %eax
9622d366cc09383956dc264ed4641572e609392eeeJin Wei        call    __set_errno
97b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        addl    $4, %esp
9822d366cc09383956dc264ed4641572e609392eeeJin Wei        orl     $-1, %eax
99b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        jmp     bc_return
10022d366cc09383956dc264ed4641572e609392eeeJin Wei
101b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughesbc_child:
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
108b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughesbc_parent:
109b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        # we're the parent; nothing to do.
110b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughesbc_return:
11122d366cc09383956dc264ed4641572e609392eeeJin Wei        popl    %edi
11222d366cc09383956dc264ed4641572e609392eeeJin Wei        popl    %esi
11322d366cc09383956dc264ed4641572e609392eeeJin Wei        popl    %ebx
11422d366cc09383956dc264ed4641572e609392eeeJin Wei        ret
115bdff26df2749d8d66e5d4eb5a2ecf4a9ff50fad2Elliott HughesEND(__bionic_clone)
116