]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libc/sysdeps/linux/sparc/clone.S
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libc / sysdeps / linux / sparc / clone.S
1 /* Copyright (C) 1996, 1997, 1998, 2000, 2003, 2004, 2007
2    Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Richard Henderson (rth@tamu.edu).
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 /* clone() is even more special than fork() as it mucks with stacks
22    and invokes a function in the right context after its all over.  */
23
24 #include <asm/errno.h>
25 #include <asm/unistd.h>
26 #include <tcb-offsets.h>
27 #include <sysdep.h>
28
29 #define CLONE_VM        0x00000100
30 #define CLONE_THREAD    0x00010000
31
32 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
33              pid_t *ptid, void *tls, pid_t *ctid); */
34
35         .text
36 ENTRY (__clone)
37         save    %sp,-96,%sp
38         cfi_def_cfa_register(%fp)
39         cfi_window_save
40         cfi_register(%o7, %i7)
41
42         /* sanity check arguments */
43         orcc    %i0,%g0,%g2
44         be      .Leinval
45          orcc   %i1,%g0,%o1
46         be      .Leinval
47          mov    %i2,%o0
48
49         /* The child_stack is the top of the stack, allocate one
50            whole stack frame from that as this is what the kernel
51            expects.  */
52         sub     %o1, 96, %o1
53         mov     %i3, %g3
54         mov     %i2, %g4
55
56         /* ptid */
57         mov     %i4,%o2
58         /* tls */
59         mov     %i5,%o3
60         /* ctid */
61         ld      [%fp+92],%o4
62
63         /* Do the system call */
64         set     __NR_clone,%g1
65         ta      0x10
66         bcs     .Lerror
67          tst    %o1
68         bne     __thread_start
69          nop
70         jmpl    %i7 + 8, %g0
71          restore %o0,%g0,%o0
72
73 .Leinval:
74         mov     EINVAL, %o0
75 .Lerror:
76         call    __errno_location
77          mov    %o0, %i0
78         st      %i0,[%o0]
79         jmpl    %i7 + 8, %g0
80          restore %g0,-1,%o0
81 END(__clone)
82
83         .type   __thread_start,@function
84 __thread_start:
85 #ifdef RESET_PID
86         sethi   %hi(CLONE_THREAD), %l0
87         andcc   %g4, %l0, %g0
88         bne     1f
89          andcc  %g4, CLONE_VM, %g0
90         bne,a   2f
91          mov    -1,%o0
92         set     __NR_getpid,%g1
93         ta      0x10
94 2:
95         st      %o0,[%g7 + PID]
96         st      %o0,[%g7 + TID]
97 1:
98 #endif
99         mov     %g0, %fp        /* terminate backtrace */
100         call    %g2
101          mov    %g3,%o0
102         call    exit,0
103          nop
104
105         .size   __thread_start, .-__thread_start
106
107 weak_alias (__clone, clone)