| ... | @@ -118,9 +118,6 @@ pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize, | ... | @@ -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 | pub fn syscall6( | 121 | pub fn syscall6( |
| 125 | number: SYS, | 122 | number: SYS, |
| 126 | arg1: usize, | 123 | arg1: usize, |
| ... | @@ -175,10 +172,44 @@ pub fn syscall7( | ... | @@ -175,10 +172,44 @@ pub fn syscall7( |
| 175 | ); | 172 | ); |
| 176 | } | 173 | } |
| 177 | | 174 | |
| 178 | const CloneFn = *const fn (arg: usize) callconv(.C) u8; | 175 | pub fn clone() callconv(.Naked) usize { |
| 179 | | 176 | // __clone(func, stack, flags, arg, ptid, tls, ctid) |
| 180 | /// This matches the libc clone function. | 177 | // 3, 4, 5, 6, 7, 8, 9 |
| 181 | pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; | 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 | pub fn restore() callconv(.Naked) noreturn { | 214 | pub fn restore() callconv(.Naked) noreturn { |
| 184 | asm volatile ( | 215 | asm volatile ( |