Home | History | Annotate | Download | only in bionic
      1 #include <private/bionic_asm.h>
      2 
      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);
      4 ENTRY(__bionic_clone)
      5         pushl   %ebx
      6         pushl   %esi
      7         pushl   %edi
      8 
      9         # Load system call arguments into registers.
     10         movl    16(%esp), %ebx   # flags
     11         movl    20(%esp), %ecx   # child_stack
     12         movl    24(%esp), %edx   # parent_tid
     13         movl    28(%esp), %esi   # tls
     14         movl    32(%esp), %edi   # child_tid
     15 
     16         # Copy 'fn' and 'arg' onto the child stack
     17         movl    36(%esp), %eax   # Read 'fn'.
     18         movl    %eax, -16(%ecx)  # Write 'fn'.
     19         movl    40(%esp), %eax   # Read 'arg'.
     20         movl    %eax, -12(%ecx)  # Write 'arg'.
     21         subl    $16, %ecx
     22 
     23         # Make the system call.
     24         movl    $__NR_clone, %eax
     25         int     $0x80
     26 
     27         # Check result.
     28         testl    %eax, %eax
     29         jz      .L_bc_child
     30         jg      .L_bc_parent
     31 
     32         # An error occurred, so set errno and return -1.
     33         negl    %eax
     34         pushl   %eax
     35         call    __set_errno_internal
     36         addl    $4, %esp
     37         jmp     .L_bc_return
     38 
     39 .L_bc_child:
     40         # We don't want anyone to unwind past this point.
     41         .cfi_undefined %eip
     42         call    __start_thread
     43         hlt
     44 
     45 .L_bc_parent:
     46         # We're the parent; nothing to do.
     47 .L_bc_return:
     48         popl    %edi
     49         popl    %esi
     50         popl    %ebx
     51         ret
     52 END(__bionic_clone)
     53 .hidden __bionic_clone
     54