]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/alpha/clone.S
2002-11-06 Roland McGrath <roland@redhat.com>
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / alpha / clone.S
CommitLineData
b5ce64ef 1/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
3c7b2587
UD
2 This file is part of the GNU C Library.
3 Contributed by Richard Henderson <rth@tamu.edu>, 1996.
3b0174d0 4
3c7b2587 5 The GNU C Library is free software; you can redistribute it and/or
3214b89b
AJ
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.
3b0174d0 9
3c7b2587
UD
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
3214b89b 13 Lesser General Public License for more details.
3b0174d0 14
3214b89b
AJ
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. */
3b0174d0
UD
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 <sysdep.h>
81e25b60 24#define _ERRNO_H 1
405916ef 25#include <bits/errno.h>
3b0174d0 26
b5ce64ef 27/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg) */
3b0174d0
UD
28
29 .text
30ENTRY(__clone)
dd4b8913 31#ifdef PROF
18a702a8 32 ldgp gp,0(pv)
3c7b2587 33 .set noat
dd4b8913
UD
34 lda AT, _mcount
35 jsr AT, (AT), _mcount
3c7b2587 36 .set at
3b0174d0 37 .prologue 1
18a702a8
RH
38#else
39 .prologue 0
40#endif
3b0174d0
UD
41
42 /* Sanity check arguments. */
3b0174d0
UD
43 ldiq v0,EINVAL
44 beq a0,$error /* no NULL function pointers */
45 beq a1,$error /* no NULL stack pointers */
3b0174d0 46
0f85544d
UD
47 /* Save the fn ptr and arg on the new stack. */
48 subq a1,16,a1
49 stq a0,0(a1)
50 stq a3,8(a1)
51
3b0174d0 52 /* Do the system call */
3b0174d0
UD
53 mov a2,a0
54 ldiq v0,__NR_clone
55 call_pal PAL_callsys
56
57 bne a3,$error
58 beq v0,thread_start
59
60 /* Successful return from the parent */
3b0174d0
UD
61 ret
62
63 /* Something bad happened -- no child created */
64$error:
73bc8117 65#ifndef PROF
3b0174d0
UD
66 br gp,1f
671: ldgp gp,0(gp)
73bc8117 68#endif
3b0174d0
UD
69 jmp zero,__syscall_error
70
71 END(__clone)
72
73/* Load up the arguments to the function. Put this block of code in
74 its own function so that we can terminate the stack trace with our
b5ce64ef 75 debug info. */
3b0174d0
UD
76
77 .ent thread_start
78thread_start:
79 .frame fp,0,zero,0
80 mov zero,fp
81 .prologue 0
82
0f85544d
UD
83 /* Load up the arguments. */
84 ldq pv,0(sp)
85 ldq a0,8(sp)
86 addq sp,16,sp
87
3b0174d0
UD
88 /* Call the user's function */
89 jsr ra,(pv)
90 ldgp gp,0(ra)
91
92 /* Call _exit rather than doing it inline for breakpoint purposes */
93 mov v0,a0
94 jsr ra,_exit
95
b5ce64ef
UD
96 /* Die horribly. */
97 halt
98
3b0174d0
UD
99 .end thread_start
100
101weak_alias(__clone, clone)