]>
Commit | Line | Data |
---|---|---|
5f72b005 | 1 | /* Wrapper around clone system call. C-SKY ABIV2 version. |
04277e02 | 2 | Copyright (C) 2018-2019 Free Software Foundation, Inc. |
5f72b005 MH |
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 | |
16 | License along with the GNU C Library. If not, see | |
17 | <http://www.gnu.org/licenses/>. */ | |
18 | ||
19 | /* clone() is even more special than fork() as it mucks with stacks | |
20 | and invokes a function in the right context after its all over. */ | |
21 | ||
22 | #include <sysdep.h> | |
23 | #define _ERRNO_H 1 | |
24 | #include <bits/errno.h> | |
25 | ||
26 | /* int clone (int (*fn) (void *arg), void *child_stack, int flags, void *arg, | |
27 | pid_t *ptid, struct user_desc *tls, pid_t *ctid) */ | |
28 | ||
29 | .text | |
30 | ENTRY (__clone) | |
31 | /* Sanity check arguments. */ | |
32 | cmpnei a0, 0 /* No NULL function pointers. */ | |
33 | bf __error_arg | |
34 | cmpnei a1, 0 /* No NULL stack pointers. */ | |
35 | bf __error_arg | |
36 | ||
37 | subi a1, 8 | |
38 | stw a0, (a1, 0) /* Insert the function into the new stack. */ | |
39 | stw a3, (a1, 4) /* Insert the args into the new stack. */ | |
40 | ||
41 | mov t1, r7 /* Save r7. */ | |
42 | mov t2, r4 /* Save r4. */ | |
43 | ||
44 | /* The syscall expects the args to be in different slots. */ | |
45 | mov a0, a2 | |
46 | ldw a2, (sp, 0) | |
47 | ldw a3, (sp, 8) | |
48 | ldw r4, (sp, 4) | |
49 | lrw r7, __NR_clone | |
50 | trap 0 | |
51 | ||
52 | mov r7, t1 /* Restore r7. */ | |
53 | mov r4, t2 /* Restore r4. */ | |
54 | btsti a0, 31 /* Check if return is less than zero. */ | |
55 | bt __do_syscall_error | |
56 | cmpnei a0, 0 | |
57 | bf __child | |
58 | rts | |
59 | ||
60 | __error_arg: | |
61 | lrw a0, -EINVAL | |
62 | ||
63 | __do_syscall_error: | |
64 | #ifdef __PIC__ | |
65 | subi sp, 8 | |
66 | stw gb, (sp, 0) | |
67 | stw r15, (sp, 4) | |
68 | grs gb, .Lgetpc | |
69 | .Lgetpc: | |
70 | lrw t0, .Lgetpc@GOTPC | |
71 | addu gb, gb, t0 | |
72 | lrw t0, __syscall_error@PLT | |
73 | ldr.w t0, (gb, t0 << 0) | |
74 | jsr t0 | |
75 | ldw gb, (sp, 0) | |
76 | ldw r15, (sp, 4) | |
77 | addi sp, 8 | |
78 | #else | |
79 | jmpi __syscall_error | |
80 | #endif /* __PIC__ */ | |
81 | rts | |
82 | PSEUDO_END (__clone) | |
83 | ||
84 | __child: | |
85 | ldw a0, (sp, 4) /* Restore args from new sp. */ | |
86 | ldw a1, (sp, 0) /* Restore function from new sp. */ | |
87 | addi sp, 8 | |
88 | jsr a1 | |
89 | ||
90 | /* exit */ | |
91 | lrw r7, __NR_exit | |
92 | trap 0 | |
93 | ||
94 | libc_hidden_def (__clone) | |
95 | weak_alias (__clone, clone) |