authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-11-08 16:32:54+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-11-20 08:38:10+01:00
log4e2a4e194bb07d08927410012a5a19bbe443c9f2
treee4da48b041e61e32b7cc34b1838e145f2872edd6
parent73be59433f36f5a8f5c7fa7bbffcb8eb17b1735d

std: Use correct clone() stub

The previous clone() definition was written for 32bit PPC targets, trying to execute it on a PPC64 machine lead to countless crashes. Use the clone() definition kindly lifted from Musl libc.

1 files changed, 49 insertions(+), 40 deletions(-)

lib/std/special/c.zig+49-40
...@@ -386,6 +386,11 @@ fn clone() callconv(.Naked) void {...@@ -386,6 +386,11 @@ fn clone() callconv(.Naked) void {
386 );386 );
387 },387 },
388 .arm => {388 .arm => {
389 // __clone(func, stack, flags, arg, ptid, tls, ctid)
390 // r0, r1, r2, r3, +0, +4, +8
391
392 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
393 // r7 r0, r1, r2, r3, r4
389 asm volatile (394 asm volatile (
390 \\ stmfd sp!,{r4,r5,r6,r7}395 \\ stmfd sp!,{r4,r5,r6,r7}
391 \\ mov r7,#120396 \\ mov r7,#120
...@@ -445,6 +450,11 @@ fn clone() callconv(.Naked) void {...@@ -445,6 +450,11 @@ fn clone() callconv(.Naked) void {
445 );450 );
446 },451 },
447 .mips, .mipsel => {452 .mips, .mipsel => {
453 // __clone(func, stack, flags, arg, ptid, tls, ctid)
454 // 3, 4, 5, 6, 7, 8, 9
455
456 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
457 // 2 4, 5, 6, 7, 8
448 asm volatile (458 asm volatile (
449 \\ # Save function pointer and argument pointer on new thread stack459 \\ # Save function pointer and argument pointer on new thread stack
450 \\ and $5, $5, -8460 \\ and $5, $5, -8
...@@ -465,12 +475,14 @@ fn clone() callconv(.Naked) void {...@@ -465,12 +475,14 @@ fn clone() callconv(.Naked) void {
465 \\ addu $sp, $sp, 16475 \\ addu $sp, $sp, 16
466 \\ jr $ra476 \\ jr $ra
467 \\ subu $2, $0, $2477 \\ subu $2, $0, $2
468 \\1: beq $2, $0, 1f478 \\1:
479 \\ beq $2, $0, 1f
469 \\ nop480 \\ nop
470 \\ addu $sp, $sp, 16481 \\ addu $sp, $sp, 16
471 \\ jr $ra482 \\ jr $ra
472 \\ nop483 \\ nop
473 \\1: lw $25, 0($sp)484 \\1:
485 \\ lw $25, 0($sp)
474 \\ lw $4, 4($sp)486 \\ lw $4, 4($sp)
475 \\ jalr $25487 \\ jalr $25
476 \\ nop488 \\ nop
...@@ -480,51 +492,48 @@ fn clone() callconv(.Naked) void {...@@ -480,51 +492,48 @@ fn clone() callconv(.Naked) void {
480 );492 );
481 },493 },
482 .powerpc64, .powerpc64le => {494 .powerpc64, .powerpc64le => {
495 // __clone(func, stack, flags, arg, ptid, tls, ctid)
496 // 3, 4, 5, 6, 7, 8, 9
497
498 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
499 // 0 3, 4, 5, 6, 7
483 asm volatile (500 asm volatile (
484 \\ # store non-volatile regs r30, r31 on stack in order to put our
485 \\ # start func and its arg there
486 \\ stwu 30, -16(1)
487 \\ stw 31, 4(1)
488 \\ # save r3 (func) into r30, and r6(arg) into r31
489 \\ mr 30, 3
490 \\ mr 31, 6
491 \\ # create initial stack frame for new thread501 \\ # create initial stack frame for new thread
492 \\ clrrwi 4, 4, 4502 \\ clrrdi 4, 4, 4
493 \\ li 0, 0503 \\ li 0, 0
494 \\ stwu 0, -16(4)504 \\ stdu 0,-32(4)
495 \\ #move c into first arg505 \\
496 \\ mr 3, 5506 \\ # save fn and arg to child stack
497 \\ mr 5, 7507 \\ std 3, 8(4)
498 \\ mr 6, 8508 \\ std 6, 16(4)
499 \\ mr 7, 9509 \\
500 \\ # move syscall number into r0510 \\ # shuffle args into correct registers and call SYS_clone
501 \\ li 0, 120511 \\ mr 3, 5
512 \\ #mr 4, 4
513 \\ mr 5, 7
514 \\ mr 6, 8
515 \\ mr 7, 9
516 \\ li 0, 120 # SYS_clone = 120
502 \\ sc517 \\ sc
503 \\ # check for syscall error518 \\
504 \\ bns+ 1f # jump to label 1 if no summary overflow.519 \\ # if error, negate return (errno)
505 \\ #else520 \\ bns+ 1f
506 \\ neg 3, 3 #negate the result (errno)521 \\ neg 3, 3
522 \\
507 \\1:523 \\1:
508 \\ # compare sc result with 0524 \\ # if we're the parent, return
509 \\ cmpwi cr7, 3, 0525 \\ cmpwi cr7, 3, 0
510 \\ # if not 0, jump to end526 \\ bnelr cr7
511 \\ bne cr7, 2f527 \\
512 \\ #else: we're the child528 \\ # we're the child. call fn(arg)
513 \\ #call funcptr: move arg (d) into r3529 \\ ld 3, 16(1)
514 \\ mr 3, 31530 \\ ld 12, 8(1)
515 \\ #move r30 (funcptr) into CTR reg531 \\ mtctr 12
516 \\ mtctr 30
517 \\ # call CTR reg
518 \\ bctrl532 \\ bctrl
519 \\ # mov SYS_exit into r0 (the exit param is already in r3)533 \\
520 \\ li 0, 1534 \\ # call SYS_exit. exit code is already in r3 from fn return value
535 \\ li 0, 1 # SYS_exit = 1
521 \\ sc536 \\ sc
522 \\2:
523 \\ # restore stack
524 \\ lwz 30, 0(1)
525 \\ lwz 31, 4(1)
526 \\ addi 1, 1, 16
527 \\ blr
528 );537 );
529 },538 },
530 .sparcv9 => {539 .sparcv9 => {