summaryrefslogtreecommitdiffstats
path: root/libc/arch-x86/bionic/clone.S
blob: 361808ded560ade0ad9c4f311b6cfd0e022db1a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <sys/linux-syscalls.h>

.text

/*
 * int  __pthread_clone(int (*fn)(void*), void *tls, int flags,
 *                      void *arg);
 */
.globl __pthread_clone
.type __pthread_clone, @function
.align 4
__pthread_clone:
        pushl   %ebx
        pushl   %ecx
        movl    16(%esp), %ecx
        movl    20(%esp), %ebx

        # insert arguments onto the child stack
        movl    12(%esp), %eax
        movl    %eax, -12(%ecx)
        movl    24(%esp), %eax
        movl    %eax, -8(%ecx)
        lea     (%ecx), %eax
        movl    %eax, -4(%ecx)

        movl    $__NR_clone, %eax
        int     $0x80
        test    %eax, %eax
        jns     1f

        # an error occured, set errno and return -1
        negl    %eax
        call    __set_errno
        orl     $-1, %eax
        jmp     2f

1:
        jnz     2f

        # we're in the child thread now, call __thread_entry
        # with the appropriate arguments on the child stack
        # we already placed most of them
        subl    $16, %esp
        jmp     __thread_entry
        hlt

2:
        popl    %ecx
        popl    %ebx
        ret