Change _IO_stderr_/_IO_stdin_/_IO_stdout to compat symbols [BZ #31766]
[glibc.git] / sysdeps / unix / sysv / linux / mips / clone.S
blobeaa879fbe6bdb9a7afa0d79c6bf38117c1468375
1 /* Copyright (C) 1996-2024 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library.  If not, see
16    <https://www.gnu.org/licenses/>.  */
18 /* clone() is even more special than fork() as it mucks with stacks
19    and invokes a function in the right context after its all over.  */
21 #include <sys/asm.h>
22 #include <sysdep.h>
23 #define _ERRNO_H        1
24 #include <bits/errno.h>
25 #include <tls.h>
27 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
28              void *parent_tidptr, void *tls, void *child_tidptr) */
30         .text
31         .set            nomips16
32 #if _MIPS_SIM == _ABIO32
33 # define EXTRA_LOCALS 1
34 #else
35 # define EXTRA_LOCALS 0
36 #endif
37 LOCALSZ= 4
38 FRAMESZ= (((NARGSAVE+LOCALSZ)*SZREG)+ALSZ)&ALMASK
39 GPOFF= FRAMESZ-(1*SZREG)
40 NESTED(__clone,4*SZREG,sp)
41 #ifdef __PIC__
42         SETUP_GP
43 #endif
44         PTR_SUBU sp, FRAMESZ
45         cfi_adjust_cfa_offset (FRAMESZ)
46         SETUP_GP64_STACK (GPOFF, __clone)
47 #ifdef __PIC__
48         SAVE_GP (GPOFF)
49 #endif
50 #ifdef PROF
51         .set            noat
52         move            $1,ra
53         jal             _mcount
54         .set            at
55 #endif
57         /* Align stack to 8/16 bytes per the ABI.  */
58 #if _MIPS_SIM == _ABIO32
59         li              t0,-8
60 #else
61         li              t0,-16
62 #endif
63         and             a1,a1,t0
65         /* Sanity check arguments.  */
66         li              v0,EINVAL
67         beqz            a0,L(error)     /* No NULL function pointers.  */
68         beqz            a1,L(error)     /* No NULL stack pointers.  */
70         PTR_SUBU        a1,32           /* Reserve argument save space.  */
71         PTR_S           a0,0(a1)        /* Save function pointer.  */
72         PTR_S           a3,PTRSIZE(a1)  /* Save argument pointer.  */
73         LONG_S          a2,(PTRSIZE*2)(a1)      /* Save clone flags.  */
75         move            a0,a2
77         /* Shuffle in the last three arguments - arguments 5, 6, and 7 to
78            this function, but arguments 3, 4, and 5 to the syscall.  */
79 #if _MIPS_SIM == _ABIO32
80         PTR_L           a2,(FRAMESZ+PTRSIZE+PTRSIZE+16)(sp)
81         PTR_S           a2,16(sp)
82         PTR_L           a2,(FRAMESZ+16)(sp)
83         PTR_L           a3,(FRAMESZ+PTRSIZE+16)(sp)
84 #else
85         move            a2,a4
86         move            a3,a5
87         move            a4,a6
88 #endif
90         /* Do the system call */
91         li              v0,__NR_clone
92         cfi_endproc
93         syscall
95         bnez            a3,L(error)
96         beqz            v0,L(thread_start)
98         /* Successful return from the parent */
99         cfi_startproc
100         cfi_adjust_cfa_offset (FRAMESZ)
101         SETUP_GP64_STACK_CFI (GPOFF)
102         cfi_remember_state
103         RESTORE_GP64_STACK
104         PTR_ADDU        sp, FRAMESZ
105         cfi_adjust_cfa_offset (-FRAMESZ)
106         ret
108         /* Something bad happened -- no child created */
109 L(error):
110         cfi_restore_state
111 #ifdef __PIC__
112         PTR_LA          t9,__syscall_error
113         RESTORE_GP64_STACK
114         PTR_ADDU        sp, FRAMESZ
115         cfi_adjust_cfa_offset (-FRAMESZ)
116         jr              t9
117 #else
118         RESTORE_GP64_STACK
119         PTR_ADDU        sp, FRAMESZ
120         cfi_adjust_cfa_offset (-FRAMESZ)
121         j               __syscall_error
122 #endif
123         END(__clone)
125 /* Load up the arguments to the function.  Put this block of code in
126    its own function so that we can terminate the stack trace with our
127    debug info.  */
129 ENTRY(__thread_start)
130 L(thread_start):
131         cfi_undefined ($31)
132         /* cp is already loaded.  */
133         SAVE_GP (GPOFF)
134         /* The stackframe has been created on entry of clone().  */
136         /* Restore the arg for user's function.  */
137         PTR_L           t9,0(sp)        /* Function pointer.  */
138         PTR_L           a0,PTRSIZE(sp)  /* Argument pointer.  */
140         /* Call the user's function.  */
141         jal             t9
143         move            a0,v0
144         li              v0,__NR_exit
145         syscall
147         END(__thread_start)
149 libc_hidden_def (__clone)
150 weak_alias (__clone, clone)