| ... | ... | @@ -60,7 +60,7 @@ comptime { |
| 60 | 60 | { |
| 61 | 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 | 64 | @export("clone", clone, builtin.GlobalLinkage.Strong); |
| 65 | 65 | } |
| 66 | 66 | } |
| ... | ... | @@ -72,32 +72,64 @@ extern fn __stack_chk_fail() noreturn { |
| 72 | 72 | // it causes a segfault in release mode. this is a workaround of calling it |
| 73 | 73 | // across .o file boundaries. fix comptime @ptrCast of nakedcc functions. |
| 74 | 74 | nakedcc fn clone() void { |
| 75 | | asm volatile ( |
| 76 | | \\ xor %%eax,%%eax |
| 77 | | \\ mov $56,%%al |
| 78 | | \\ mov %%rdi,%%r11 |
| 79 | | \\ mov %%rdx,%%rdi |
| 80 | | \\ mov %%r8,%%rdx |
| 81 | | \\ mov %%r9,%%r8 |
| 82 | | \\ mov 8(%%rsp),%%r10 |
| 83 | | \\ mov %%r11,%%r9 |
| 84 | | \\ and $-16,%%rsi |
| 85 | | \\ sub $8,%%rsi |
| 86 | | \\ mov %%rcx,(%%rsi) |
| 87 | | \\ syscall |
| 88 | | \\ test %%eax,%%eax |
| 89 | | \\ jnz 1f |
| 90 | | \\ xor %%ebp,%%ebp |
| 91 | | \\ pop %%rdi |
| 92 | | \\ call *%%r9 |
| 93 | | \\ mov %%eax,%%edi |
| 94 | | \\ xor %%eax,%%eax |
| 95 | | \\ mov $60,%%al |
| 96 | | \\ syscall |
| 97 | | \\ hlt |
| 98 | | \\1: ret |
| 99 | | \\ |
| 100 | | ); |
| 75 | if (builtin.arch == builtin.Arch.x86_64) { |
| 76 | asm volatile ( |
| 77 | \\ xor %%eax,%%eax |
| 78 | \\ mov $56,%%al // SYS_clone |
| 79 | \\ mov %%rdi,%%r11 |
| 80 | \\ mov %%rdx,%%rdi |
| 81 | \\ mov %%r8,%%rdx |
| 82 | \\ mov %%r9,%%r8 |
| 83 | \\ mov 8(%%rsp),%%r10 |
| 84 | \\ mov %%r11,%%r9 |
| 85 | \\ and $-16,%%rsi |
| 86 | \\ sub $8,%%rsi |
| 87 | \\ mov %%rcx,(%%rsi) |
| 88 | \\ syscall |
| 89 | \\ test %%eax,%%eax |
| 90 | \\ jnz 1f |
| 91 | \\ xor %%ebp,%%ebp |
| 92 | \\ pop %%rdi |
| 93 | \\ call *%%r9 |
| 94 | \\ mov %%eax,%%edi |
| 95 | \\ xor %%eax,%%eax |
| 96 | \\ mov $60,%%al // SYS_exit |
| 97 | \\ syscall |
| 98 | \\ hlt |
| 99 | \\1: ret |
| 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 | 135 | const math = @import("../math/index.zig"); |