malloc/Makefile: Split and sort tests
[glibc.git] / sysdeps / unix / sysv / linux / x86_64 / clone.S
blobd0adc21c850632aea23aab6a0ce9426ea303334d
1 /* Copyright (C) 2001-2024 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    <https://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 /* The userland implementation is:
27    int clone (int (*fn)(void *arg), void *child_stack, int flags,
28               void *arg, pid_t *parent_tid, void *tls, pid_t *child_tid);
29    the kernel entry is:
30    int clone (long flags, void *child_stack, pid_t *parent_tid,
31               pid_t *child_tid, void *tls);
33    The parameters are passed in register and on the stack from userland:
34    rdi: fn
35    rsi: child_stack
36    rdx: flags
37    rcx: arg
38     r8: TID field in parent
39     r9: thread pointer
40 %rsp+8: TID field in child
42    The kernel expects:
43    rax: system call number
44    rdi: flags
45    rsi: child_stack
46    rdx: TID field in parent
47    r10: TID field in child
48    r8:  thread pointer  */
51         .text
52 ENTRY (__clone)
53         /* Sanity check arguments.  */
54         movq    $-EINVAL,%rax
55         testq   %rdi,%rdi               /* no NULL function pointers */
56         jz      SYSCALL_ERROR_LABEL
58         /* Align stack to 16 bytes per the x86-64 psABI.  */
59         andq    $-16, %rsi
60         jz      SYSCALL_ERROR_LABEL     /* no NULL stack pointers */
62         /* Insert the argument onto the new stack.  */
63         movq    %rcx,-8(%rsi)
65         subq    $16,%rsi
67         /* Save the function pointer.  It will be popped off in the
68            child.  */
69         movq    %rdi,0(%rsi)
71         /* Do the system call.  */
72         movq    %rdx, %rdi
73         movq    %r8, %rdx
74         movq    %r9, %r8
75         mov     8(%rsp), %R10_LP
76         movl    $SYS_ify(clone),%eax
78         /* End FDE now, because in the child the unwind info will be
79            wrong.  */
80         cfi_endproc;
81         syscall
83         testq   %rax,%rax
84         jl      SYSCALL_ERROR_LABEL
85         jz      L(thread_start)
87         ret
89 L(thread_start):
90         cfi_startproc;
91         /* Clearing frame pointer is insufficient, use CFI.  */
92         cfi_undefined (rip);
93         /* Clear the frame pointer.  The ABI suggests this be done, to mark
94            the outermost frame obviously.  */
95         xorl    %ebp, %ebp
97         /* Set up arguments for the function call.  */
98         popq    %rax            /* Function to call.  */
99         popq    %rdi            /* Argument.  */
100         call    *%rax
101         /* Call exit with return value from function call. */
102         movq    %rax, %rdi
103         movl    $SYS_ify(exit), %eax
104         syscall
105         cfi_endproc;
107         cfi_startproc;
108 PSEUDO_END (__clone)
110 libc_hidden_def (__clone)
111 weak_alias (__clone, clone)