| ... | @@ -60,7 +60,7 @@ comptime { | ... | @@ -60,7 +60,7 @@ comptime { |
| 60 | { | 60 | { |
| 61 | @export("__stack_chk_fail", __stack_chk_fail, builtin.GlobalLinkage.Strong); | 61 | @export("__stack_chk_fail", __stack_chk_fail, builtin.GlobalLinkage.Strong); |
| 62 | } | 62 | } |
| 63 | if (builtin.os == builtin.Os.linux and builtin.arch == builtin.Arch.x86_64) { | 63 | if (builtin.os == builtin.Os.linux) { |
| 64 | @export("clone", clone, builtin.GlobalLinkage.Strong); | 64 | @export("clone", clone, builtin.GlobalLinkage.Strong); |
| 65 | } | 65 | } |
| 66 | } | 66 | } |
| ... | @@ -72,32 +72,64 @@ extern fn __stack_chk_fail() noreturn { | ... | @@ -72,32 +72,64 @@ extern fn __stack_chk_fail() noreturn { |
| 72 | // it causes a segfault in release mode. this is a workaround of calling it | 72 | // it causes a segfault in release mode. this is a workaround of calling it |
| 73 | // across .o file boundaries. fix comptime @ptrCast of nakedcc functions. | 73 | // across .o file boundaries. fix comptime @ptrCast of nakedcc functions. |
| 74 | nakedcc fn clone() void { | 74 | nakedcc fn clone() void { |
| 75 | asm volatile ( | 75 | if (builtin.arch == builtin.Arch.x86_64) { |
| 76 | \\ xor %%eax,%%eax | 76 | asm volatile ( |
| 77 | \\ mov $56,%%al | 77 | \\ xor %%eax,%%eax |
| 78 | \\ mov %%rdi,%%r11 | 78 | \\ mov $56,%%al // SYS_clone |
| 79 | \\ mov %%rdx,%%rdi | 79 | \\ mov %%rdi,%%r11 |
| 80 | \\ mov %%r8,%%rdx | 80 | \\ mov %%rdx,%%rdi |
| 81 | \\ mov %%r9,%%r8 | 81 | \\ mov %%r8,%%rdx |
| 82 | \\ mov 8(%%rsp),%%r10 | 82 | \\ mov %%r9,%%r8 |
| 83 | \\ mov %%r11,%%r9 | 83 | \\ mov 8(%%rsp),%%r10 |
| 84 | \\ and $-16,%%rsi | 84 | \\ mov %%r11,%%r9 |
| 85 | \\ sub $8,%%rsi | 85 | \\ and $-16,%%rsi |
| 86 | \\ mov %%rcx,(%%rsi) | 86 | \\ sub $8,%%rsi |
| 87 | \\ syscall | 87 | \\ mov %%rcx,(%%rsi) |
| 88 | \\ test %%eax,%%eax | 88 | \\ syscall |
| 89 | \\ jnz 1f | 89 | \\ test %%eax,%%eax |
| 90 | \\ xor %%ebp,%%ebp | 90 | \\ jnz 1f |
| 91 | \\ pop %%rdi | 91 | \\ xor %%ebp,%%ebp |
| 92 | \\ call *%%r9 | 92 | \\ pop %%rdi |
| 93 | \\ mov %%eax,%%edi | 93 | \\ call *%%r9 |
| 94 | \\ xor %%eax,%%eax | 94 | \\ mov %%eax,%%edi |
| 95 | \\ mov $60,%%al | 95 | \\ xor %%eax,%%eax |
| 96 | \\ syscall | 96 | \\ mov $60,%%al // SYS_exit |
| 97 | \\ hlt | 97 | \\ syscall |
| 98 | \\1: ret | 98 | \\ hlt |
| 99 | \\ | 99 | \\1: ret |
| 100 | ); | 100 | \\ |
| | 101 | ); |
| | 102 | } else if (builtin.arch == builtin.Arch.aarch64v8) { |
| | 103 | // __clone(func, stack, flags, arg, ptid, tls, ctid) |
| | 104 | // x0, x1, w2, x3, x4, x5, x6 |
| | 105 | |
| | 106 | // syscall(SYS_clone, flags, stack, ptid, tls, ctid) |
| | 107 | // x8, x0, x1, x2, x3, x4 |
| | 108 | asm volatile ( |
| | 109 | \\ // align stack and save func,arg |
| | 110 | \\ and x1,x1,#-16 |
| | 111 | \\ stp x0,x3,[x1,#-16]! |
| | 112 | \\ |
| | 113 | \\ // syscall |
| | 114 | \\ uxtw x0,w2 |
| | 115 | \\ mov x2,x4 |
| | 116 | \\ mov x3,x5 |
| | 117 | \\ mov x4,x6 |
| | 118 | \\ mov x8,#220 // SYS_clone |
| | 119 | \\ svc #0 |
| | 120 | \\ |
| | 121 | \\ cbz x0,1f |
| | 122 | \\ // parent |
| | 123 | \\ ret |
| | 124 | \\ // child |
| | 125 | \\1: ldp x1,x0,[sp],#16 |
| | 126 | \\ blr x1 |
| | 127 | \\ mov x8,#93 // SYS_exit |
| | 128 | \\ svc #0 |
| | 129 | ); |
| | 130 | } else { |
| | 131 | @compileError("Implement clone() for this arch."); |
| | 132 | } |
| 101 | } | 133 | } |
| 102 | | 134 | |
| 103 | const math = @import("../math/index.zig"); | 135 | const math = @import("../math/index.zig"); |