Elliott Hughes | 851e68a | 2014-02-19 16:53:20 -0800 | [diff] [blame^] | 1 | #include <private/bionic_asm.h> |
The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 2 | |
Elliott Hughes | 70b24b1 | 2013-11-15 11:51:07 -0800 | [diff] [blame] | 3 | // pid_t __bionic_clone(int flags, void* child_stack, pid_t* parent_tid, void* tls, pid_t* child_tid, int (*fn)(void*), void* arg); |
Elliott Hughes | bdff26d | 2013-02-11 17:08:16 -0800 | [diff] [blame] | 4 | ENTRY(__bionic_clone) |
Jin Wei | 22d366c | 2012-08-08 15:15:16 +0800 | [diff] [blame] | 5 | pushl %ebx |
| 6 | pushl %esi |
| 7 | pushl %edi |
| 8 | |
Elliott Hughes | 99c393d | 2013-11-26 16:20:50 -0800 | [diff] [blame] | 9 | # Align child stack. |
Jin Wei | 22d366c | 2012-08-08 15:15:16 +0800 | [diff] [blame] | 10 | movl 20(%esp), %ecx |
| 11 | andl $~15, %ecx |
Jin Wei | 22d366c | 2012-08-08 15:15:16 +0800 | [diff] [blame] | 12 | |
Elliott Hughes | 99c393d | 2013-11-26 16:20:50 -0800 | [diff] [blame] | 13 | # Copy 'fn' and 'arg' onto the child stack |
| 14 | movl 36(%esp), %eax # Read 'fn'. |
| 15 | movl %eax, -16(%ecx) # Write 'fn'. |
| 16 | movl 40(%esp), %eax # Read 'arg'. |
| 17 | movl %eax, -12(%ecx) # Write 'arg'. |
Jin Wei | 22d366c | 2012-08-08 15:15:16 +0800 | [diff] [blame] | 18 | subl $16, %ecx |
Elliott Hughes | b603251 | 2013-02-12 23:02:33 -0800 | [diff] [blame] | 19 | |
Elliott Hughes | 99c393d | 2013-11-26 16:20:50 -0800 | [diff] [blame] | 20 | # Make the system call. |
Jin Wei | 22d366c | 2012-08-08 15:15:16 +0800 | [diff] [blame] | 21 | movl $__NR_clone, %eax |
Elliott Hughes | 99c393d | 2013-11-26 16:20:50 -0800 | [diff] [blame] | 22 | movl 16(%esp), %ebx # flags |
| 23 | #movl %ecx, %ecx # child stack (already there) |
| 24 | movl 24(%esp), %edx # parent_tid |
| 25 | movl 28(%esp), %esi # tls |
| 26 | movl 32(%esp), %edi # child_tid |
Jin Wei | 22d366c | 2012-08-08 15:15:16 +0800 | [diff] [blame] | 27 | int $0x80 |
Elliott Hughes | b603251 | 2013-02-12 23:02:33 -0800 | [diff] [blame] | 28 | |
Elliott Hughes | 99c393d | 2013-11-26 16:20:50 -0800 | [diff] [blame] | 29 | # Check result. |
Elliott Hughes | b603251 | 2013-02-12 23:02:33 -0800 | [diff] [blame] | 30 | cmpl $0, %eax |
| 31 | je bc_child |
| 32 | jg bc_parent |
Jin Wei | 22d366c | 2012-08-08 15:15:16 +0800 | [diff] [blame] | 33 | |
Elliott Hughes | 99c393d | 2013-11-26 16:20:50 -0800 | [diff] [blame] | 34 | # An error occurred, so set errno and return -1. |
Jin Wei | 22d366c | 2012-08-08 15:15:16 +0800 | [diff] [blame] | 35 | negl %eax |
Elliott Hughes | b603251 | 2013-02-12 23:02:33 -0800 | [diff] [blame] | 36 | pushl %eax |
Jin Wei | 22d366c | 2012-08-08 15:15:16 +0800 | [diff] [blame] | 37 | call __set_errno |
Elliott Hughes | b603251 | 2013-02-12 23:02:33 -0800 | [diff] [blame] | 38 | addl $4, %esp |
Jin Wei | 22d366c | 2012-08-08 15:15:16 +0800 | [diff] [blame] | 39 | orl $-1, %eax |
Elliott Hughes | b603251 | 2013-02-12 23:02:33 -0800 | [diff] [blame] | 40 | jmp bc_return |
Jin Wei | 22d366c | 2012-08-08 15:15:16 +0800 | [diff] [blame] | 41 | |
Elliott Hughes | b603251 | 2013-02-12 23:02:33 -0800 | [diff] [blame] | 42 | bc_child: |
Jin Wei | 22d366c | 2012-08-08 15:15:16 +0800 | [diff] [blame] | 43 | call __bionic_clone_entry |
| 44 | hlt |
| 45 | |
Elliott Hughes | b603251 | 2013-02-12 23:02:33 -0800 | [diff] [blame] | 46 | bc_parent: |
| 47 | # we're the parent; nothing to do. |
| 48 | bc_return: |
Jin Wei | 22d366c | 2012-08-08 15:15:16 +0800 | [diff] [blame] | 49 | popl %edi |
| 50 | popl %esi |
| 51 | popl %ebx |
| 52 | ret |
Elliott Hughes | bdff26d | 2013-02-11 17:08:16 -0800 | [diff] [blame] | 53 | END(__bionic_clone) |