NEWS: Add advisories.
[glibc.git] / sysdeps / unix / sysv / linux / x86_64 / clone3.S
blob5a2d42234e0cb16c56fe4a16e81a95ebd7b0c176
1 /* The clone3 syscall wrapper.  Linux/x86-64 version.
2    Copyright (C) 2021-2024 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
19 /* clone3() is even more special than fork() as it mucks with stacks
20    and invokes a function in the right context after its all over.  */
22 #include <sysdep.h>
24 /* The userland implementation is:
25    int clone3 (struct clone_args *cl_args, size_t size,
26                int (*func)(void *arg), void *arg);
27    the kernel entry is:
28    int clone3 (struct clone_args *cl_args, size_t size);
30    The parameters are passed in registers from userland:
31    rdi: cl_args
32    rsi: size
33    rdx: func
34    rcx: arg
36    The kernel expects:
37    rax: system call number
38    rdi: cl_args
39    rsi: size  */
41         .text
42 ENTRY (__clone3)
43         /* Sanity check arguments.  */
44         movl    $-EINVAL, %eax
45         test    %RDI_LP, %RDI_LP        /* No NULL cl_args pointer.  */
46         jz      SYSCALL_ERROR_LABEL
47         test    %RDX_LP, %RDX_LP        /* No NULL function pointer.  */
48         jz      SYSCALL_ERROR_LABEL
50         /* Save the cl_args pointer in R8 which is preserved by the
51            syscall.  */
52         mov     %RCX_LP, %R8_LP
54         /* Do the system call.  */
55         movl    $SYS_ify(clone3), %eax
57         /* End FDE now, because in the child the unwind info will be
58            wrong.  */
59         cfi_endproc
60         syscall
62         test    %RAX_LP, %RAX_LP
63         jl      SYSCALL_ERROR_LABEL
64         jz      L(thread_start)
66         ret
68 L(thread_start):
69         cfi_startproc
70         /* Clearing frame pointer is insufficient, use CFI.  */
71         cfi_undefined (rip)
72         /* Clear the frame pointer.  The ABI suggests this be done, to mark
73            the outermost frame obviously.  */
74         xorl    %ebp, %ebp
76         /* Set up arguments for the function call.  */
77         mov     %R8_LP, %RDI_LP /* Argument.  */
78         call    *%rdx           /* Call function.  */
79         /* Call exit with return value from function call. */
80         movq    %rax, %rdi
81         movl    $SYS_ify(exit), %eax
82         syscall
83         cfi_endproc
85         cfi_startproc
86 PSEUDO_END (__clone3)
88 libc_hidden_def (__clone3)
89 weak_alias (__clone3, clone3)