NULL terminate backtrace by zero'ing out %fp. Store away flags, func_ptr,
[kopensolaris-gnu/glibc.git] / sysdeps / unix / sysv / linux / sparc / sparc64 / clone.S
1 /* Copyright (C) 1997, 2000 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Richard Henderson (rth@tamu.edu).
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, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 /* clone() is even more special than fork() as it mucks with stacks
21    and invokes a function in the right context after its all over.  */
22
23 #include <asm/errno.h>
24 #include <asm/unistd.h>
25
26 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
27
28         .text
29         .align  4
30         .globl  __clone
31         .type   __clone,@function
32
33 __clone:
34         save    %sp, -192, %sp
35
36         /* sanity check arguments */
37         brz,pn  %i0, 99f
38          mov    %i0, %l0                /* save fn */
39         brz,pn  %i1, 99f
40          mov    %i3, %l3                /* save arg */
41
42         /* Do the system call */
43         sub     %i1, 0x7ff, %o1
44         mov     %i2, %o0
45         set     __NR_clone, %g1
46         ta      0x6d
47         bcs,pn  %xcc, 99f
48          nop
49         brnz,pn %o1, __thread_start
50          mov    %o0, %i0
51         ret
52          restore
53 99:
54 #ifndef _LIBC_REENTRANT
55 #ifdef PIC
56         call    1f
57         sethi   %hi(_GLOBAL_OFFSET_TABLE_-(99b-.)), %l7
58 1:      or      %l7, %lo(_GLOBAL_OFFSET_TABLE_-(99b-.)), %l7
59         add     %l7, %o7, %l7
60         set     EINVAL, %i0
61         sethi   %hi(errno), %g2
62         or      %g2, %lo(errno), %g2
63         st      %i0, [%l7+%g2]
64 #else
65         sethi   %hi(errno), %g2
66         set     EINVAL, %i0
67         st      %i0, [%g2+%lo(errno)]
68 #endif
69 #else
70         call    __errno_location
71          nop
72         st      %i0, [%o0]
73 #endif
74         ret
75          restore %g0,-1,%o0
76         .size __clone, .-__clone
77
78         .type __thread_start,@function
79 __thread_start:
80         mov     %g0, %fp        /* terminate backtrace */
81         sub     %sp, 6*8, %sp   /* provide arg storage */
82         call    %l0
83          mov    %l3,%o0
84         call    _exit,0
85          nop
86         .size __thread_start, .-__thread_start
87
88 weak_alias(__clone, clone)