@@ -118,9 +118,6 @@ pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize,
118
118
);
119
119
}
120
120
121
- // NOTE: The o32 calling convention requires the callee to reserve 16 bytes for
122
- // the first four arguments even though they're passed in $a0-$a3.
123
-
124
121
pub fn syscall6 (
125
122
number : SYS ,
126
123
arg1 : usize ,
@@ -175,10 +172,44 @@ pub fn syscall7(
175
172
);
176
173
}
177
174
178
- const CloneFn = * const fn (arg : usize ) callconv (.C ) u8 ;
179
-
180
- /// This matches the libc clone function.
181
- pub extern fn clone (func : CloneFn , stack : usize , flags : u32 , arg : usize , ptid : * i32 , tls : usize , ctid : * i32 ) usize ;
175
+ pub fn clone () callconv (.Naked ) usize {
176
+ // __clone(func, stack, flags, arg, ptid, tls, ctid)
177
+ // 3, 4, 5, 6, 7, 8, 9
178
+ //
179
+ // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
180
+ // 2 4, 5, 6, 7, 8
181
+ asm volatile (
182
+ \\ # Save function pointer and argument pointer on new thread stack
183
+ \\ and $5, $5, -16
184
+ \\ dsubu $5, $5, 16
185
+ \\ sd $4, 0($5)
186
+ \\ sd $7, 8($5)
187
+ \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
188
+ \\ move $4, $6
189
+ \\ move $6, $8
190
+ \\ move $7, $9
191
+ \\ move $8, $10
192
+ \\ li $2, 5055 # SYS_clone
193
+ \\ syscall
194
+ \\ beq $7, $0, 1f
195
+ \\ nop
196
+ \\ jr $ra
197
+ \\ dsubu $2, $0, $2
198
+ \\1:
199
+ \\ beq $2, $0, 1f
200
+ \\ nop
201
+ \\ jr $ra
202
+ \\ nop
203
+ \\1:
204
+ \\ ld $25, 0($sp)
205
+ \\ ld $4, 8($sp)
206
+ \\ jalr $25
207
+ \\ nop
208
+ \\ move $4, $2
209
+ \\ li $2, 5058 # SYS_exit
210
+ \\ syscall
211
+ );
212
+ }
182
213
183
214
pub fn restore () callconv (.Naked ) noreturn {
184
215
asm volatile (
0 commit comments