__bionic_clone.S revision fff3c0fdcf2a6f4301a238628fbf8182780a1612
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
9fff3c0fdcf2a6f4301a238628fbf8182780a1612Elliott Hughes        # Align 'child_stack' to 16 bytes.
1022d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    20(%esp), %ecx
1122d366cc09383956dc264ed4641572e609392eeeJin Wei        andl    $~15, %ecx
1222d366cc09383956dc264ed4641572e609392eeeJin Wei
1399c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        # Copy 'fn' and 'arg' onto the child stack
1499c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        movl    36(%esp), %eax   # Read 'fn'.
1599c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        movl    %eax, -16(%ecx)  # Write 'fn'.
1699c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        movl    40(%esp), %eax   # Read 'arg'.
1799c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        movl    %eax, -12(%ecx)  # Write 'arg'.
1822d366cc09383956dc264ed4641572e609392eeeJin Wei        subl    $16, %ecx
19b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes
2099c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        # Make the system call.
2122d366cc09383956dc264ed4641572e609392eeeJin Wei        movl    $__NR_clone, %eax
2299c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        movl    16(%esp), %ebx  # flags
2399c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        #movl   %ecx, %ecx      # child stack (already there)
2499c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        movl    24(%esp), %edx  # parent_tid
2599c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        movl    28(%esp), %esi  # tls
2699c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        movl    32(%esp), %edi  # child_tid
2722d366cc09383956dc264ed4641572e609392eeeJin Wei        int     $0x80
28b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes
2999c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        # Check result.
30b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        cmpl    $0, %eax
31fff3c0fdcf2a6f4301a238628fbf8182780a1612Elliott Hughes        je      .L_bc_child
32fff3c0fdcf2a6f4301a238628fbf8182780a1612Elliott Hughes        jg      .L_bc_parent
3322d366cc09383956dc264ed4641572e609392eeeJin Wei
3499c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes        # An error occurred, so set errno and return -1.
3522d366cc09383956dc264ed4641572e609392eeeJin Wei        negl    %eax
36b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        pushl   %eax
3722d366cc09383956dc264ed4641572e609392eeeJin Wei        call    __set_errno
38b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        addl    $4, %esp
3922d366cc09383956dc264ed4641572e609392eeeJin Wei        orl     $-1, %eax
40fff3c0fdcf2a6f4301a238628fbf8182780a1612Elliott Hughes        jmp     .L_bc_return
4122d366cc09383956dc264ed4641572e609392eeeJin Wei
42fff3c0fdcf2a6f4301a238628fbf8182780a1612Elliott Hughes.L_bc_child:
4322d366cc09383956dc264ed4641572e609392eeeJin Wei        call    __bionic_clone_entry
4422d366cc09383956dc264ed4641572e609392eeeJin Wei        hlt
4522d366cc09383956dc264ed4641572e609392eeeJin Wei
46fff3c0fdcf2a6f4301a238628fbf8182780a1612Elliott Hughes.L_bc_parent:
47b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes        # we're the parent; nothing to do.
48fff3c0fdcf2a6f4301a238628fbf8182780a1612Elliott Hughes.L_bc_return:
4922d366cc09383956dc264ed4641572e609392eeeJin Wei        popl    %edi
5022d366cc09383956dc264ed4641572e609392eeeJin Wei        popl    %esi
5122d366cc09383956dc264ed4641572e609392eeeJin Wei        popl    %ebx
5222d366cc09383956dc264ed4641572e609392eeeJin Wei        ret
53bdff26df2749d8d66e5d4eb5a2ecf4a9ff50fad2Elliott HughesEND(__bionic_clone)
54954cf0d4e2669f91194b45f484152e47efa4f6c7Elliott Hughes.hidden __bionic_clone
55