]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/mips/clone.S
Update to LGPL v2.1.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / mips / clone.S
CommitLineData
69151eeb 1/* Copyright (C) 1996, 1997, 2000 Free Software Foundation, Inc.
f21acc89
UD
2 This file is part of the GNU C Library.
3 Contributed by Ralf Baechle <ralf@gnu.ai.mit.edu>, 1996.
4
5 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
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.
f21acc89
UD
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
41bdb6e2 13 Lesser General Public License for more details.
f21acc89 14
41bdb6e2
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. */
f21acc89
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 <sys/asm.h>
24#include <asm/unistd.h>
25#include <sysdep.h>
26#define _ERRNO_H 1
27#include <bits/errno.h>
28
44a202c0 29/* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg) */
f21acc89
UD
30
31 .text
44a202c0 32NESTED(__clone,4*SZREG,sp)
69151eeb 33#ifdef __PIC__
f21acc89
UD
34 .set noreorder
35 .cpload $25
36 .set reorder
44a202c0
AJ
37 subu sp,32
38 .cprestore 16
69151eeb 39#else
44a202c0 40 subu sp,32
69151eeb 41#endif
f21acc89
UD
42#ifdef PROF
43 .set noat
44 move $1,ra
45 jal _mcount
46 .set at
47#endif
48
44a202c0 49
f21acc89
UD
50 /* Sanity check arguments. */
51 li v0,EINVAL
44a202c0
AJ
52 beqz a0,error /* No NULL function pointers. */
53 beqz a1,error /* No NULL stack pointers. */
f21acc89 54
44a202c0
AJ
55 subu a1,32 /* Reserve argument save space. */
56 sw a0,0(a1) /* Save function pointer. */
57 sw a3,4(a1) /* Save argument pointer. */
69151eeb 58
f21acc89
UD
59
60 /* Do the system call */
f21acc89
UD
61 move a0,a2
62 li v0,__NR_clone
63 syscall
64
65 bnez a3,error
66 beqz v0,__thread_start
67
68 /* Successful return from the parent */
44a202c0 69 addiu sp,32
f21acc89
UD
70 ret
71
72 /* Something bad happened -- no child created */
73error:
44a202c0 74 addiu sp,32
b82f6af2 75#ifdef __PIC__
f21acc89
UD
76 la t9,__syscall_error
77 jr t9
78#else
79 j __syscall_error
80#endif
81 END(__clone)
82
83/* Load up the arguments to the function. Put this block of code in
84 its own function so that we can terminate the stack trace with our
c45c8be6 85 debug info. */
f21acc89 86
490a9ab7 87ENTRY(__thread_start)
44a202c0 88 /* cp is already loaded. */
490a9ab7 89 .cprestore 16
69151eeb 90 /* The stackframe has been created on entry of clone(). */
c45c8be6 91 /* Restore the arg for user's function. */
490a9ab7
AJ
92 lw t9,0(sp) /* Function pointer. */
93 lw a0,4(sp) /* Argument pointer. */
f21acc89 94
69151eeb 95 /* Call the user's function. */
f21acc89
UD
96 jalr t9
97
69151eeb 98 /* Call _exit rather than doing it inline for breakpoint purposes. */
f21acc89 99 move a0,v0
69151eeb
AJ
100#ifdef __PIC__
101 la t9,_exit
102 jalr t9
103#else
f21acc89 104 jal _exit
69151eeb 105#endif
f21acc89
UD
106 END(__thread_start)
107
108weak_alias(__clone, clone)