__bionic_clone.S revision 7efad83d430f4d824f2aaa75edea5106f6ff8aae
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