__bionic_clone.S revision 99c393dff33e0a5d3838c16dc7878f32ac3da971
14cdde5f12364079a2b55fa4fc4ed53364cb8465dElliott Hughes#include <asm/unistd.h> 2bdff26df2749d8d66e5d4eb5a2ecf4a9ff50fad2Elliott Hughes#include <machine/asm.h> 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 470b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott 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); 5bdff26df2749d8d66e5d4eb5a2ecf4a9ff50fad2Elliott HughesENTRY(__bionic_clone) 622d366cc09383956dc264ed4641572e609392eeeJin Wei pushl %ebx 722d366cc09383956dc264ed4641572e609392eeeJin Wei pushl %esi 822d366cc09383956dc264ed4641572e609392eeeJin Wei pushl %edi 922d366cc09383956dc264ed4641572e609392eeeJin Wei 1099c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes # Align child stack. 1122d366cc09383956dc264ed4641572e609392eeeJin Wei movl 20(%esp), %ecx 1222d366cc09383956dc264ed4641572e609392eeeJin Wei andl $~15, %ecx 1322d366cc09383956dc264ed4641572e609392eeeJin Wei 1499c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes # Copy 'fn' and 'arg' onto the child stack 1599c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes movl 36(%esp), %eax # Read 'fn'. 1699c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes movl %eax, -16(%ecx) # Write 'fn'. 1799c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes movl 40(%esp), %eax # Read 'arg'. 1899c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes movl %eax, -12(%ecx) # Write 'arg'. 1922d366cc09383956dc264ed4641572e609392eeeJin Wei subl $16, %ecx 20b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes 2199c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes # Make the system call. 2222d366cc09383956dc264ed4641572e609392eeeJin Wei movl $__NR_clone, %eax 2399c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes movl 16(%esp), %ebx # flags 2499c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes #movl %ecx, %ecx # child stack (already there) 2599c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes movl 24(%esp), %edx # parent_tid 2699c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes movl 28(%esp), %esi # tls 2799c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes movl 32(%esp), %edi # child_tid 2822d366cc09383956dc264ed4641572e609392eeeJin Wei int $0x80 29b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes 3099c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes # Check result. 31b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes cmpl $0, %eax 32b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes je bc_child 33b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes jg bc_parent 3422d366cc09383956dc264ed4641572e609392eeeJin Wei 3599c393dff33e0a5d3838c16dc7878f32ac3da971Elliott Hughes # An error occurred, so set errno and return -1. 3622d366cc09383956dc264ed4641572e609392eeeJin Wei negl %eax 37b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes pushl %eax 3822d366cc09383956dc264ed4641572e609392eeeJin Wei call __set_errno 39b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes addl $4, %esp 4022d366cc09383956dc264ed4641572e609392eeeJin Wei orl $-1, %eax 41b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes jmp bc_return 4222d366cc09383956dc264ed4641572e609392eeeJin Wei 43b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughesbc_child: 4422d366cc09383956dc264ed4641572e609392eeeJin Wei call __bionic_clone_entry 4522d366cc09383956dc264ed4641572e609392eeeJin Wei hlt 4622d366cc09383956dc264ed4641572e609392eeeJin Wei 47b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughesbc_parent: 48b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughes # we're the parent; nothing to do. 49b6032515a058fb02c8c4152c9f055bb3bd462ae2Elliott Hughesbc_return: 5022d366cc09383956dc264ed4641572e609392eeeJin Wei popl %edi 5122d366cc09383956dc264ed4641572e609392eeeJin Wei popl %esi 5222d366cc09383956dc264ed4641572e609392eeeJin Wei popl %ebx 5322d366cc09383956dc264ed4641572e609392eeeJin Wei ret 54bdff26df2749d8d66e5d4eb5a2ecf4a9ff50fad2Elliott HughesEND(__bionic_clone) 55