1851e68a2402fa414544e66650e09dfdaac813e51Elliott Hughes#include <private/bionic_asm.h>
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
370b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes// pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg);
4bdff26df2749d8d66e5d4eb5a2ecf4a9ff50fad2Elliott HughesENTRY(__bionic_clone)
522d366cc09383956dc264ed4641572e609392eeeJin Wei        pushl   %ebx
622d366cc09383956dc264ed4641572e609392eeeJin Wei        pushl   %esi
722d366cc09383956dc264ed4641572e609392eeeJin Wei        pushl   %edi
822d366cc09383956dc264ed4641572e609392eeeJin Wei
90d236aa3f1e6d31b0c729448ae9d3ed1cad23fb4Elliott Hughes        # Load system call arguments into registers.
100d236aa3f1e6d31b0c729448ae9d3ed1cad23fb4Elliott Hughes        movl    16(%esp), %ebx   # flags
110d236aa3f1e6d31b0c729448ae9d3ed1cad23fb4Elliott Hughes        movl    20(%esp), %ecx   # child_stack
120d236aa3f1e6d31b0c729448ae9d3ed1cad23fb4Elliott Hughes        movl    24(%esp), %edx   # parent_tid
130d236aa3f1e6d31b0c729448ae9d3ed1cad23fb4Elliott Hughes        movl    28(%esp), %esi   # tls
140d236aa3f1e6d31b0c729448ae9d3ed1cad23fb4Elliott Hughes        movl    32(%esp), %edi   # child_tid
1522d366cc09383956dc264ed4641572e609392eeeJin Wei
1699c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        # Copy 'fn' and 'arg' onto the child stack
1799c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        movl    36(%esp), %eax   # Read 'fn'.
1899c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        movl    %eax, -16(%ecx)  # Write 'fn'.
1999c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        movl    40(%esp), %eax   # Read 'arg'.
2099c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        movl    %eax, -12(%ecx)  # Write 'arg'.
2122d366cc09383956dc264ed4641572e609392eeeJin Wei        subl    $16, %ecx
22b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes
2399c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        # Make the system call.
2422d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    $__NR_clone, %eax
2522d366cc09383956dc264ed4641572e609392eeeJin Wei        int     $0x80
26b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes
2799c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        # Check result.
28aeb3016f8132689d1b49d30056005b667e3d2d0eElliott Hughes        testl    %eax, %eax
29aeb3016f8132689d1b49d30056005b667e3d2d0eElliott Hughes        jz      .L_bc_child
30fff3c0fdcf2a6f4301a238628fbf8182780a1612Elliott Hughes        jg      .L_bc_parent
3122d366cc09383956dc264ed4641572e609392eeeJin Wei
3299c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        # An error occurred, so set errno and return -1.
3322d366cc09383956dc264ed4641572e609392eeeJin Wei        negl    %eax
34b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        pushl   %eax
357efad83d430f4d824f2aaa75edea5106f6ff8aaeElliott Hughes        call    __set_errno_internal
36b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        addl    $4, %esp
37fff3c0fdcf2a6f4301a238628fbf8182780a1612Elliott Hughes        jmp     .L_bc_return
3822d366cc09383956dc264ed4641572e609392eeeJin Wei
39fff3c0fdcf2a6f4301a238628fbf8182780a1612Elliott Hughes.L_bc_child:
40ee9d5bdd950bb05549bddc614c3c5ce9d10a5b08Elliott Hughes        # We don't want anyone to unwind past this point.
41ee9d5bdd950bb05549bddc614c3c5ce9d10a5b08Elliott Hughes        .cfi_undefined %eip
42ebc8cd117a562f387c52ed4e1aeba0fb21f33194Elliott Hughes        call    __start_thread
4322d366cc09383956dc264ed4641572e609392eeeJin Wei        hlt
4422d366cc09383956dc264ed4641572e609392eeeJin Wei
45fff3c0fdcf2a6f4301a238628fbf8182780a1612Elliott Hughes.L_bc_parent:
46aeb3016f8132689d1b49d30056005b667e3d2d0eElliott Hughes        # We're the parent; nothing to do.
47fff3c0fdcf2a6f4301a238628fbf8182780a1612Elliott Hughes.L_bc_return:
4822d366cc09383956dc264ed4641572e609392eeeJin Wei        popl    %edi
4922d366cc09383956dc264ed4641572e609392eeeJin Wei        popl    %esi
5022d366cc09383956dc264ed4641572e609392eeeJin Wei        popl    %ebx
5122d366cc09383956dc264ed4641572e609392eeeJin Wei        ret
52bdff26df2749d8d66e5d4eb5a2ecf4a9ff50fad2Elliott HughesEND(__bionic_clone)
53954cf0d4e2669f91194b45f484152e47efa4f6c7Elliott Hughes.hidden __bionic_clone
54