Update copyright notices with scripts/update-copyrights
[glibc.git] / sysdeps / unix / sysv / linux / x86_64 / clone.S
blob0508730d8311b3ec7247e92a0c5de1e0c37eddb7
1 /* Copyright (C) 2001-2014 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <http://www.gnu.org/licenses/>.  */
18 /* clone() is even more special than fork() as it mucks with stacks
19    and invokes a function in the right context after its all over.  */
21 #include <sysdep.h>
22 #define _ERRNO_H        1
23 #include <bits/errno.h>
24 #include <asm-syntax.h>
26 #define CLONE_VM        0x00000100
27 #define CLONE_THREAD    0x00010000
29 /* The userland implementation is:
30    int clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg),
31    the kernel entry is:
32    int clone (long flags, void *child_stack).
34    The parameters are passed in register and on the stack from userland:
35    rdi: fn
36    rsi: child_stack
37    rdx: flags
38    rcx: arg
39    r8d: TID field in parent
40    r9d: thread pointer
41 %esp+8: TID field in child
43    The kernel expects:
44    rax: system call number
45    rdi: flags
46    rsi: child_stack
47    rdx: TID field in parent
48    r10: TID field in child
49    r8:  thread pointer  */
52         .text
53 ENTRY (__clone)
54         /* Sanity check arguments.  */
55         movq    $-EINVAL,%rax
56         testq   %rdi,%rdi               /* no NULL function pointers */
57         jz      SYSCALL_ERROR_LABEL
58         testq   %rsi,%rsi               /* no NULL stack pointers */
59         jz      SYSCALL_ERROR_LABEL
61         /* Insert the argument onto the new stack.  */
62         subq    $16,%rsi
63         movq    %rcx,8(%rsi)
65         /* Save the function pointer.  It will be popped off in the
66            child in the ebx frobbing below.  */
67         movq    %rdi,0(%rsi)
69         /* Do the system call.  */
70         movq    %rdx, %rdi
71         movq    %r8, %rdx
72         movq    %r9, %r8
73         mov     8(%rsp), %R10_LP
74         movl    $SYS_ify(clone),%eax
76         /* End FDE now, because in the child the unwind info will be
77            wrong.  */
78         cfi_endproc;
79         syscall
81         testq   %rax,%rax
82         jl      SYSCALL_ERROR_LABEL
83         jz      L(thread_start)
85         ret
87 L(thread_start):
88         cfi_startproc;
89         /* Clearing frame pointer is insufficient, use CFI.  */
90         cfi_undefined (rip);
91         /* Clear the frame pointer.  The ABI suggests this be done, to mark
92            the outermost frame obviously.  */
93         xorl    %ebp, %ebp
95 #ifdef RESET_PID
96         testq   $CLONE_THREAD, %rdi
97         jne     1f
98         testq   $CLONE_VM, %rdi
99         movl    $-1, %eax
100         jne     2f
101         movl    $SYS_ify(getpid), %eax
102         syscall
103 2:      movl    %eax, %fs:PID
104         movl    %eax, %fs:TID
106 #endif
108         /* Set up arguments for the function call.  */
109         popq    %rax            /* Function to call.  */
110         popq    %rdi            /* Argument.  */
111         call    *%rax
112         /* Call exit with return value from function call. */
113         movq    %rax, %rdi
114         call    HIDDEN_JUMPTARGET (_exit)
115         cfi_endproc;
117         cfi_startproc;
118 PSEUDO_END (__clone)
120 weak_alias (__clone, clone)