authorgravatar for shawn@git.icuShawn Landden <shawn@git.icu> 2018-08-30 02:45:10+00:00
committergravatar for shawn@git.icuShawn Landden <shawn@git.icu> 2018-09-08 03:52:28+00:00
logcba0d76fbcbaf4e45a277a36fc7f0be0b60c7e14
tree4cfbc58238f06950a703b2d5edd856aed88ed342
parentf8808edff479426a04685ac6f2b487376eaab65a

clone() on arm64


2 files changed, 60 insertions(+), 28 deletions(-)

std/os/linux/arm64.zig+1-1
...@@ -366,7 +366,7 @@ pub fn syscall6(...@@ -366,7 +366,7 @@ pub fn syscall6(
366}366}
367367
368/// This matches the libc clone function.368/// This matches the libc clone function.
369pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: usize, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;369pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
370370
371pub const msghdr = extern struct {371pub const msghdr = extern struct {
372 msg_name: *u8,372 msg_name: *u8,
std/special/builtin.zig+59-27
...@@ -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 it72// 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.
74nakedcc fn clone() void {74nakedcc fn clone() void {
75 asm volatile (75 if (builtin.arch == builtin.Arch.x86_64) {
76 \\ xor %%eax,%%eax76 asm volatile (
77 \\ mov $56,%%al77 \\ xor %%eax,%%eax
78 \\ mov %%rdi,%%r1178 \\ mov $56,%%al // SYS_clone
79 \\ mov %%rdx,%%rdi79 \\ mov %%rdi,%%r11
80 \\ mov %%r8,%%rdx80 \\ mov %%rdx,%%rdi
81 \\ mov %%r9,%%r881 \\ mov %%r8,%%rdx
82 \\ mov 8(%%rsp),%%r1082 \\ mov %%r9,%%r8
83 \\ mov %%r11,%%r983 \\ mov 8(%%rsp),%%r10
84 \\ and $-16,%%rsi84 \\ mov %%r11,%%r9
85 \\ sub $8,%%rsi85 \\ and $-16,%%rsi
86 \\ mov %%rcx,(%%rsi)86 \\ sub $8,%%rsi
87 \\ syscall87 \\ mov %%rcx,(%%rsi)
88 \\ test %%eax,%%eax88 \\ syscall
89 \\ jnz 1f89 \\ test %%eax,%%eax
90 \\ xor %%ebp,%%ebp90 \\ jnz 1f
91 \\ pop %%rdi91 \\ xor %%ebp,%%ebp
92 \\ call *%%r992 \\ pop %%rdi
93 \\ mov %%eax,%%edi93 \\ call *%%r9
94 \\ xor %%eax,%%eax94 \\ mov %%eax,%%edi
95 \\ mov $60,%%al95 \\ xor %%eax,%%eax
96 \\ syscall96 \\ mov $60,%%al // SYS_exit
97 \\ hlt97 \\ syscall
98 \\1: ret98 \\ 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}
102134
103const math = @import("../math/index.zig");135const math = @import("../math/index.zig");