]>
Commit | Line | Data |
---|---|---|
706074a5 UD |
1 | /* Copyright (C) 1996 Free Software Foundation, Inc. |
2 | Contributed by Andreas Schwab (schwab@issan.informatik.uni-dortmund.de) | |
3 | ||
4 | The GNU C Library is free software; you can redistribute it and/or | |
5 | modify it under the terms of the GNU Library General Public License as | |
6 | published by the Free Software Foundation; either version 2 of the | |
7 | License, or (at your option) any later version. | |
8 | ||
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 | Library General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU Library General Public | |
15 | License along with the GNU C Library; see the file COPYING.LIB. If | |
16 | not, write to the Free Software Foundation, Inc., 675 Mass Ave, | |
17 | Cambridge, MA 02139, USA. */ | |
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> | |
11336c16 | 23 | #define _ERRNO_H 1 |
706074a5 UD |
24 | #include <errnos.h> |
25 | ||
26 | /* int clone (int (*fn) (), void *child_stack, int flags, int nargs, ...) */ | |
27 | ||
28 | .text | |
29 | ENTRY (__clone) | |
0d204b0a | 30 | |
706074a5 UD |
31 | /* Sanity check arguments. */ |
32 | movel #-EINVAL, %d0 | |
33 | movel 4(%sp), %a0 /* no NULL function pointers */ | |
34 | tstl %a0 | |
35 | jeq syscall_error | |
36 | movel 8(%sp), %a1 /* no NULL stack pointers */ | |
37 | tstl %a1 | |
38 | jeq syscall_error | |
39 | movel 16(%sp), %d1 /* no negative argument counts */ | |
40 | jmi syscall_error | |
41 | ||
42 | /* Allocate space on the new stack and copy args over */ | |
43 | movel %d1, %d0 | |
44 | negl %d0 | |
45 | lea (%a1,%d0.l*4), %a1 | |
46 | jeq 2f | |
47 | 1: movel 16(%sp,%d1.l*4), -4(%a1,%d1.l*4) | |
48 | subql #1, %d1 | |
49 | jne 1b | |
50 | 2: | |
51 | ||
52 | /* Do the system call */ | |
53 | exg %d2, %a1 /* save %d2 and get stack pointer */ | |
54 | movel 12(%sp), %d1 /* get flags */ | |
55 | movel #SYS_ify (clone), %d0 | |
56 | trap #0 | |
57 | exg %d2, %a1 /* restore %d2 */ | |
58 | ||
59 | tstl %d0 | |
60 | jmi syscall_error | |
61 | jeq thread_start | |
62 | ||
63 | rts | |
64 | ||
706074a5 UD |
65 | thread_start: |
66 | subl %fp, %fp /* terminate the stack frame */ | |
67 | jsr (%a0) | |
68 | movel %d0, -(%sp) | |
6ed0492f UD |
69 | jbsr JUMPTARGET (_exit) |
70 | ||
0d204b0a | 71 | PSEUDO_END (__clone) |
706074a5 UD |
72 | |
73 | weak_alias (__clone, clone) |