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