| ... | ... | @@ -182,10 +182,7 @@ comptime { |
| 182 | 182 | @export("__stack_chk_fail", __stack_chk_fail, builtin.GlobalLinkage.Strong); |
| 183 | 183 | } |
| 184 | 184 | if (builtin.os == builtin.Os.linux) { |
| 185 | | // TODO implement clone for riscv64 |
| 186 | | if (builtin.arch != .riscv64) { |
| 187 | | @export("clone", clone, builtin.GlobalLinkage.Strong); |
| 188 | | } |
| 185 | @export("clone", clone, builtin.GlobalLinkage.Strong); |
| 189 | 186 | } |
| 190 | 187 | } |
| 191 | 188 | extern fn __stack_chk_fail() noreturn { |
| ... | ... | @@ -196,87 +193,124 @@ extern fn __stack_chk_fail() noreturn { |
| 196 | 193 | // it causes a segfault in release mode. this is a workaround of calling it |
| 197 | 194 | // across .o file boundaries. fix comptime @ptrCast of nakedcc functions. |
| 198 | 195 | nakedcc fn clone() void { |
| 199 | | if (builtin.arch == builtin.Arch.x86_64) { |
| 200 | | asm volatile ( |
| 201 | | \\ xor %%eax,%%eax |
| 202 | | \\ mov $56,%%al // SYS_clone |
| 203 | | \\ mov %%rdi,%%r11 |
| 204 | | \\ mov %%rdx,%%rdi |
| 205 | | \\ mov %%r8,%%rdx |
| 206 | | \\ mov %%r9,%%r8 |
| 207 | | \\ mov 8(%%rsp),%%r10 |
| 208 | | \\ mov %%r11,%%r9 |
| 209 | | \\ and $-16,%%rsi |
| 210 | | \\ sub $8,%%rsi |
| 211 | | \\ mov %%rcx,(%%rsi) |
| 212 | | \\ syscall |
| 213 | | \\ test %%eax,%%eax |
| 214 | | \\ jnz 1f |
| 215 | | \\ xor %%ebp,%%ebp |
| 216 | | \\ pop %%rdi |
| 217 | | \\ call *%%r9 |
| 218 | | \\ mov %%eax,%%edi |
| 219 | | \\ xor %%eax,%%eax |
| 220 | | \\ mov $60,%%al // SYS_exit |
| 221 | | \\ syscall |
| 222 | | \\ hlt |
| 223 | | \\1: ret |
| 224 | | \\ |
| 225 | | ); |
| 226 | | } else if (builtin.arch == builtin.Arch.aarch64) { |
| 227 | | // __clone(func, stack, flags, arg, ptid, tls, ctid) |
| 228 | | // x0, x1, w2, x3, x4, x5, x6 |
| 229 | | |
| 230 | | // syscall(SYS_clone, flags, stack, ptid, tls, ctid) |
| 231 | | // x8, x0, x1, x2, x3, x4 |
| 232 | | asm volatile ( |
| 233 | | \\ // align stack and save func,arg |
| 234 | | \\ and x1,x1,#-16 |
| 235 | | \\ stp x0,x3,[x1,#-16]! |
| 236 | | \\ |
| 237 | | \\ // syscall |
| 238 | | \\ uxtw x0,w2 |
| 239 | | \\ mov x2,x4 |
| 240 | | \\ mov x3,x5 |
| 241 | | \\ mov x4,x6 |
| 242 | | \\ mov x8,#220 // SYS_clone |
| 243 | | \\ svc #0 |
| 244 | | \\ |
| 245 | | \\ cbz x0,1f |
| 246 | | \\ // parent |
| 247 | | \\ ret |
| 248 | | \\ // child |
| 249 | | \\1: ldp x1,x0,[sp],#16 |
| 250 | | \\ blr x1 |
| 251 | | \\ mov x8,#93 // SYS_exit |
| 252 | | \\ svc #0 |
| 253 | | ); |
| 254 | | } else if (builtin.arch == builtin.Arch.arm) { |
| 255 | | asm volatile ( |
| 256 | | \\ stmfd sp!,{r4,r5,r6,r7} |
| 257 | | \\ mov r7,#120 |
| 258 | | \\ mov r6,r3 |
| 259 | | \\ mov r5,r0 |
| 260 | | \\ mov r0,r2 |
| 261 | | \\ and r1,r1,#-16 |
| 262 | | \\ ldr r2,[sp,#16] |
| 263 | | \\ ldr r3,[sp,#20] |
| 264 | | \\ ldr r4,[sp,#24] |
| 265 | | \\ svc 0 |
| 266 | | \\ tst r0,r0 |
| 267 | | \\ beq 1f |
| 268 | | \\ ldmfd sp!,{r4,r5,r6,r7} |
| 269 | | \\ bx lr |
| 270 | | \\ |
| 271 | | \\1: mov r0,r6 |
| 272 | | \\ bl 3f |
| 273 | | \\2: mov r7,#1 |
| 274 | | \\ svc 0 |
| 275 | | \\ b 2b |
| 276 | | \\3: bx r5 |
| 277 | | ); |
| 278 | | } else { |
| 279 | | @compileError("Implement clone() for this arch."); |
| 196 | switch (builtin.arch) { |
| 197 | .x86_64 => { |
| 198 | asm volatile ( |
| 199 | \\ xor %%eax,%%eax |
| 200 | \\ mov $56,%%al // SYS_clone |
| 201 | \\ mov %%rdi,%%r11 |
| 202 | \\ mov %%rdx,%%rdi |
| 203 | \\ mov %%r8,%%rdx |
| 204 | \\ mov %%r9,%%r8 |
| 205 | \\ mov 8(%%rsp),%%r10 |
| 206 | \\ mov %%r11,%%r9 |
| 207 | \\ and $-16,%%rsi |
| 208 | \\ sub $8,%%rsi |
| 209 | \\ mov %%rcx,(%%rsi) |
| 210 | \\ syscall |
| 211 | \\ test %%eax,%%eax |
| 212 | \\ jnz 1f |
| 213 | \\ xor %%ebp,%%ebp |
| 214 | \\ pop %%rdi |
| 215 | \\ call *%%r9 |
| 216 | \\ mov %%eax,%%edi |
| 217 | \\ xor %%eax,%%eax |
| 218 | \\ mov $60,%%al // SYS_exit |
| 219 | \\ syscall |
| 220 | \\ hlt |
| 221 | \\1: ret |
| 222 | \\ |
| 223 | ); |
| 224 | }, |
| 225 | .aarch64 => { |
| 226 | // __clone(func, stack, flags, arg, ptid, tls, ctid) |
| 227 | // x0, x1, w2, x3, x4, x5, x6 |
| 228 | |
| 229 | // syscall(SYS_clone, flags, stack, ptid, tls, ctid) |
| 230 | // x8, x0, x1, x2, x3, x4 |
| 231 | asm volatile ( |
| 232 | \\ // align stack and save func,arg |
| 233 | \\ and x1,x1,#-16 |
| 234 | \\ stp x0,x3,[x1,#-16]! |
| 235 | \\ |
| 236 | \\ // syscall |
| 237 | \\ uxtw x0,w2 |
| 238 | \\ mov x2,x4 |
| 239 | \\ mov x3,x5 |
| 240 | \\ mov x4,x6 |
| 241 | \\ mov x8,#220 // SYS_clone |
| 242 | \\ svc #0 |
| 243 | \\ |
| 244 | \\ cbz x0,1f |
| 245 | \\ // parent |
| 246 | \\ ret |
| 247 | \\ // child |
| 248 | \\1: ldp x1,x0,[sp],#16 |
| 249 | \\ blr x1 |
| 250 | \\ mov x8,#93 // SYS_exit |
| 251 | \\ svc #0 |
| 252 | ); |
| 253 | }, |
| 254 | .arm => { |
| 255 | asm volatile ( |
| 256 | \\ stmfd sp!,{r4,r5,r6,r7} |
| 257 | \\ mov r7,#120 |
| 258 | \\ mov r6,r3 |
| 259 | \\ mov r5,r0 |
| 260 | \\ mov r0,r2 |
| 261 | \\ and r1,r1,#-16 |
| 262 | \\ ldr r2,[sp,#16] |
| 263 | \\ ldr r3,[sp,#20] |
| 264 | \\ ldr r4,[sp,#24] |
| 265 | \\ svc 0 |
| 266 | \\ tst r0,r0 |
| 267 | \\ beq 1f |
| 268 | \\ ldmfd sp!,{r4,r5,r6,r7} |
| 269 | \\ bx lr |
| 270 | \\ |
| 271 | \\1: mov r0,r6 |
| 272 | \\ bl 3f |
| 273 | \\2: mov r7,#1 |
| 274 | \\ svc 0 |
| 275 | \\ b 2b |
| 276 | \\3: bx r5 |
| 277 | ); |
| 278 | }, |
| 279 | .riscv64 => { |
| 280 | // __clone(func, stack, flags, arg, ptid, tls, ctid) |
| 281 | // a0, a1, a2, a3, a4, a5, a6 |
| 282 | |
| 283 | // syscall(SYS_clone, flags, stack, ptid, tls, ctid) |
| 284 | // a7 a0, a1, a2, a3, a4 |
| 285 | asm volatile ( |
| 286 | \\ # Save func and arg to stack |
| 287 | \\ addi a1, a1, -16 |
| 288 | \\ sd a0, 0(a1) |
| 289 | \\ sd a3, 8(a1) |
| 290 | \\ |
| 291 | \\ # Call SYS_clone |
| 292 | \\ mv a0, a2 |
| 293 | \\ mv a2, a4 |
| 294 | \\ mv a3, a5 |
| 295 | \\ mv a4, a6 |
| 296 | \\ li a7, 220 # SYS_clone |
| 297 | \\ ecall |
| 298 | \\ |
| 299 | \\ beqz a0, 1f |
| 300 | \\ # Parent |
| 301 | \\ ret |
| 302 | \\ |
| 303 | \\ # Child |
| 304 | \\1: ld a1, 0(sp) |
| 305 | \\ ld a0, 8(sp) |
| 306 | \\ jalr a1 |
| 307 | \\ |
| 308 | \\ # Exit |
| 309 | \\ li a7, 93 # SYS_exit |
| 310 | \\ ecall |
| 311 | ); |
| 312 | }, |
| 313 | else => @compileError("Implement clone() for this arch."), |
| 280 | 314 | } |
| 281 | 315 | } |
| 282 | 316 | |