Update copyright notices with scripts/update-copyrights
[glibc.git] / sysdeps / unix / sysv / linux / sparc / sparc32 / clone.S
blobe007d5debc2010f6b70d9d114ffb66edfc2f4e97
1 /* Copyright (C) 1996-2014 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Richard Henderson (rth@tamu.edu).
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    <http://www.gnu.org/licenses/>.  */
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.  */
22 #include <asm/errno.h>
23 #include <asm/unistd.h>
24 #include <tcb-offsets.h>
25 #include <sysdep.h>
27 #define CLONE_VM        0x00000100
28 #define CLONE_THREAD    0x00010000
30 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
31              pid_t *ptid, void *tls, pid_t *ctid); */
33         .text
34 ENTRY (__clone)
35         save    %sp,-96,%sp
36         cfi_def_cfa_register(%fp)
37         cfi_window_save
38         cfi_register(%o7, %i7)
40         /* sanity check arguments */
41         orcc    %i0,%g0,%g2
42         be      .Leinval
43          orcc   %i1,%g0,%o1
44         be      .Leinval
45          mov    %i2,%o0
47         /* The child_stack is the top of the stack, allocate one
48            whole stack frame from that as this is what the kernel
49            expects.  */
50         sub     %o1, 96, %o1
51         mov     %i3, %g3
52         mov     %i2, %g4
54         /* ptid */
55         mov     %i4,%o2
56         /* tls */
57         mov     %i5,%o3
58         /* ctid */
59         ld      [%fp+92],%o4
61         /* Do the system call */
62         set     __NR_clone,%g1
63         ta      0x10
64         bcs     .Lerror
65          tst    %o1
66         bne     __thread_start
67          nop
68         jmpl    %i7 + 8, %g0
69          restore %o0,%g0,%o0
71 .Leinval:
72         mov     EINVAL, %o0
73 .Lerror:
74         call    HIDDEN_JUMPTARGET(__errno_location)
75          mov    %o0, %i0
76         st      %i0,[%o0]
77         jmpl    %i7 + 8, %g0
78          restore %g0,-1,%o0
79 END(__clone)
81         .type   __thread_start,@function
82 __thread_start:
83 #ifdef RESET_PID
84         sethi   %hi(CLONE_THREAD), %l0
85         andcc   %g4, %l0, %g0
86         bne     1f
87          andcc  %g4, CLONE_VM, %g0
88         bne,a   2f
89          mov    -1,%o0
90         set     __NR_getpid,%g1
91         ta      0x10
93         st      %o0,[%g7 + PID]
94         st      %o0,[%g7 + TID]
96 #endif
97         mov     %g0, %fp        /* terminate backtrace */
98         call    %g2
99          mov    %g3,%o0
100         call    HIDDEN_JUMPTARGET(_exit),0
101          nop
103         .size   __thread_start, .-__thread_start
105 weak_alias (__clone, clone)