]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/powerpc/powerpc64/clone.S
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / powerpc / powerpc64 / clone.S
CommitLineData
cfc91acd 1/* Wrapper around clone system call. PowerPC64 version.
d614a753 2 Copyright (C) 1997-2020 Free Software Foundation, Inc.
cfc91acd
RM
3 This file is part of the GNU C Library.
4
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.
9
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.
14
15 You should have received a copy of the GNU Lesser General Public
59ba27a6 16 License along with the GNU C Library; if not, see
5a82c748 17 <https://www.gnu.org/licenses/>. */
cfc91acd
RM
18
19#include <sysdep.h>
20#define _ERRNO_H 1
21#include <bits/errno.h>
cfc91acd
RM
22
23/* This is the only really unusual system call in PPC linux, but not
24 because of any weirdness in the system call itself; because of
25 all the freaky stuff we have to do to make the call useful. */
26
27/* int [r3] clone(int (*fn)(void *arg) [r3], void *child_stack [r4],
4fba8a3b
RM
28 int flags [r5], void *arg [r6], void *parent_tid [r7],
29 void *tls [r8], void *child_tid [r9]); */
cfc91acd 30
2d67d91a 31ENTRY (__clone)
865d953f 32 CALL_MCOUNT 7
cfc91acd
RM
33
34 /* Check for child_stack == NULL || fn == NULL. */
35 cmpdi cr0,r4,0
a2eae4cc 36 cmpdi cr1,r3,0
cfc91acd
RM
37 cror cr0*4+eq,cr1*4+eq,cr0*4+eq
38 beq- cr0,L(badargs)
39
8b8a692c 40 /* Save some regs in the "red zone". */
8b8a692c 41 std r29,-24(r1)
8b8a692c
UW
42 std r30,-16(r1)
43 std r31,-8(r1)
8b8a692c 44 cfi_offset(r29,-24)
8b8a692c
UW
45 cfi_offset(r30,-16)
46 cfi_offset(r31,-8)
cfc91acd
RM
47
48 /* Set up stack frame for child. */
49 clrrdi r4,r4,4
50 li r0,0
8b8a692c 51 stdu r0,-FRAME_MIN_SIZE_PARM(r4)
cfc91acd
RM
52
53 /* Save fn, args, stack across syscall. */
bebff237 54 mr r30,r3 /* Function in r30. */
bebff237 55 mr r29,r5 /* Flags in r29. */
cfc91acd
RM
56 mr r31,r6 /* Argument in r31. */
57
bebff237
AM
58 /* 'flags' argument is first parameter to clone syscall.
59 Second is the stack pointer, already in r4. */
cfc91acd 60 mr r3,r5
8464c2a1 61 /* Move the parent_tid, child_tid and tls arguments. */
4fba8a3b
RM
62 mr r5,r7
63 mr r6,r8
64 mr r7,r9
cfc91acd 65
97d901a6
RM
66 /* End FDE now, because in the child the unwind info will be
67 wrong. */
68 cfi_endproc
69
cfc91acd
RM
70 /* Do the call. */
71 DO_CALL(SYS_ify(clone))
72
73 /* Check for child process. */
74 cmpdi cr1,r3,0
75 crandc cr1*4+eq,cr1*4+eq,cr0*4+so
76 bne- cr1,L(parent) /* The '-' is to minimise the race. */
77
8b8a692c 78 std r2,FRAME_TOC_SAVE(r1)
cfc91acd 79 /* Call procedure. */
d31beafa 80 PPC64_LOAD_FUNCPTR r30
cfc91acd
RM
81 mr r3,r31
82 bctrl
8b8a692c 83 ld r2,FRAME_TOC_SAVE(r1)
3f823e87
AZ
84
85 DO_CALL(SYS_ify(exit))
bebff237
AM
86 /* We won't ever get here but provide a nop so that the linker
87 will insert a toc adjusting stub if necessary. */
88 nop
cfc91acd 89
bebff237
AM
90L(badargs):
91 cfi_startproc
92 li r3,EINVAL
93 TAIL_CALL_SYSCALL_ERROR
94
cfc91acd
RM
95L(parent):
96 /* Parent. Restore registers & return. */
8b8a692c 97 cfi_offset(r29,-24)
8b8a692c
UW
98 cfi_offset(r30,-16)
99 cfi_offset(r31,-8)
8b8a692c 100 ld r29,-24(r1)
8b8a692c
UW
101 ld r30,-16(r1)
102 ld r31,-8(r1)
bebff237 103 cfi_restore(r29)
bebff237
AM
104 cfi_restore(r30)
105 cfi_restore(r31)
8464c2a1 106
bebff237 107 PSEUDO_RET
97d901a6 108
2d67d91a 109END (__clone)
cfc91acd 110
9ff72da4 111libc_hidden_def (__clone)
2d67d91a 112weak_alias (__clone, clone)