From 453157595ee3c8daf017add9387b508224aa3f8f Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Wed, 25 Sep 2019 09:30:44 +0200 Subject: [PATCH] Correct some RISCV64 bits --- std/os/bits/linux/riscv64.zig | 38 ++++--- std/os/linux.zig | 2 +- std/os/linux/riscv64.zig | 2 + std/special/c.zig | 202 ++++++++++++++++++++-------------- 4 files changed, 141 insertions(+), 103 deletions(-) diff --git a/std/os/bits/linux/riscv64.zig b/std/os/bits/linux/riscv64.zig index 6f3fe2db22..e0c10ef7c0 100644 --- a/std/os/bits/linux/riscv64.zig +++ b/std/os/bits/linux/riscv64.zig @@ -298,25 +298,25 @@ pub const SYS_fspick = 433; pub const SYS_pidfd_open = 434; pub const SYS_clone3 = 435; -pub const O_CREAT = 0100; -pub const O_EXCL = 0200; -pub const O_NOCTTY = 0400; -pub const O_TRUNC = 01000; -pub const O_APPEND = 02000; -pub const O_NONBLOCK = 04000; -pub const O_DSYNC = 010000; -pub const O_SYNC = 04010000; -pub const O_RSYNC = 04010000; -pub const O_DIRECTORY = 0200000; -pub const O_NOFOLLOW = 0400000; -pub const O_CLOEXEC = 02000000; +pub const O_CREAT = 0o100; +pub const O_EXCL = 0o200; +pub const O_NOCTTY = 0o400; +pub const O_TRUNC = 0o1000; +pub const O_APPEND = 0o2000; +pub const O_NONBLOCK = 0o4000; +pub const O_DSYNC = 0o10000; +pub const O_SYNC = 0o4010000; +pub const O_RSYNC = 0o4010000; +pub const O_DIRECTORY = 0o200000; +pub const O_NOFOLLOW = 0o400000; +pub const O_CLOEXEC = 0o2000000; -pub const O_ASYNC = 020000; -pub const O_DIRECT = 040000; -pub const O_LARGEFILE = 0100000; -pub const O_NOATIME = 01000000; -pub const O_PATH = 010000000; -pub const O_TMPFILE = 020200000; +pub const O_ASYNC = 0o20000; +pub const O_DIRECT = 0o40000; +pub const O_LARGEFILE = 0o100000; +pub const O_NOATIME = 0o1000000; +pub const O_PATH = 0o10000000; +pub const O_TMPFILE = 0o20200000; pub const O_NDELAY = O_NONBLOCK; pub const F_DUPFD = 0; @@ -386,3 +386,5 @@ pub const Stat = extern struct { return self.ctim; } }; + +pub const Elf_Symndx = u32; diff --git a/std/os/linux.zig b/std/os/linux.zig index 47fc1841e9..375c7eba84 100644 --- a/std/os/linux.zig +++ b/std/os/linux.zig @@ -469,7 +469,7 @@ var vdso_clock_gettime = @ptrCast(?*const c_void, init_vdso_clock_gettime); const vdso_clock_gettime_ty = extern fn (i32, *timespec) usize; pub fn clock_gettime(clk_id: i32, tp: *timespec) usize { - if (VDSO_CGT_SYM.len != 0) { + if (@hasDecl(@This(), "VDSO_CGT_SYM")) { const ptr = @atomicLoad(?*const c_void, &vdso_clock_gettime, .Unordered); if (ptr) |fn_ptr| { const f = @ptrCast(vdso_clock_gettime_ty, fn_ptr); diff --git a/std/os/linux/riscv64.zig b/std/os/linux/riscv64.zig index 3f5053c973..7bfe0295d3 100644 --- a/std/os/linux/riscv64.zig +++ b/std/os/linux/riscv64.zig @@ -82,3 +82,5 @@ pub fn syscall6( : "memory" ); } + +pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; diff --git a/std/special/c.zig b/std/special/c.zig index 4d566a001b..f030dbe90b 100644 --- a/std/special/c.zig +++ b/std/special/c.zig @@ -182,10 +182,7 @@ comptime { @export("__stack_chk_fail", __stack_chk_fail, builtin.GlobalLinkage.Strong); } if (builtin.os == builtin.Os.linux) { - // TODO implement clone for riscv64 - if (builtin.arch != .riscv64) { - @export("clone", clone, builtin.GlobalLinkage.Strong); - } + @export("clone", clone, builtin.GlobalLinkage.Strong); } } extern fn __stack_chk_fail() noreturn { @@ -196,87 +193,124 @@ extern fn __stack_chk_fail() noreturn { // it causes a segfault in release mode. this is a workaround of calling it // across .o file boundaries. fix comptime @ptrCast of nakedcc functions. nakedcc fn clone() void { - if (builtin.arch == builtin.Arch.x86_64) { - asm volatile ( - \\ xor %%eax,%%eax - \\ mov $56,%%al // SYS_clone - \\ mov %%rdi,%%r11 - \\ mov %%rdx,%%rdi - \\ mov %%r8,%%rdx - \\ mov %%r9,%%r8 - \\ mov 8(%%rsp),%%r10 - \\ mov %%r11,%%r9 - \\ and $-16,%%rsi - \\ sub $8,%%rsi - \\ mov %%rcx,(%%rsi) - \\ syscall - \\ test %%eax,%%eax - \\ jnz 1f - \\ xor %%ebp,%%ebp - \\ pop %%rdi - \\ call *%%r9 - \\ mov %%eax,%%edi - \\ xor %%eax,%%eax - \\ mov $60,%%al // SYS_exit - \\ syscall - \\ hlt - \\1: ret - \\ - ); - } else if (builtin.arch == builtin.Arch.aarch64) { - // __clone(func, stack, flags, arg, ptid, tls, ctid) - // x0, x1, w2, x3, x4, x5, x6 + switch (builtin.arch) { + .x86_64 => { + asm volatile ( + \\ xor %%eax,%%eax + \\ mov $56,%%al // SYS_clone + \\ mov %%rdi,%%r11 + \\ mov %%rdx,%%rdi + \\ mov %%r8,%%rdx + \\ mov %%r9,%%r8 + \\ mov 8(%%rsp),%%r10 + \\ mov %%r11,%%r9 + \\ and $-16,%%rsi + \\ sub $8,%%rsi + \\ mov %%rcx,(%%rsi) + \\ syscall + \\ test %%eax,%%eax + \\ jnz 1f + \\ xor %%ebp,%%ebp + \\ pop %%rdi + \\ call *%%r9 + \\ mov %%eax,%%edi + \\ xor %%eax,%%eax + \\ mov $60,%%al // SYS_exit + \\ syscall + \\ hlt + \\1: ret + \\ + ); + }, + .aarch64 => { + // __clone(func, stack, flags, arg, ptid, tls, ctid) + // x0, x1, w2, x3, x4, x5, x6 - // syscall(SYS_clone, flags, stack, ptid, tls, ctid) - // x8, x0, x1, x2, x3, x4 - asm volatile ( - \\ // align stack and save func,arg - \\ and x1,x1,#-16 - \\ stp x0,x3,[x1,#-16]! - \\ - \\ // syscall - \\ uxtw x0,w2 - \\ mov x2,x4 - \\ mov x3,x5 - \\ mov x4,x6 - \\ mov x8,#220 // SYS_clone - \\ svc #0 - \\ - \\ cbz x0,1f - \\ // parent - \\ ret - \\ // child - \\1: ldp x1,x0,[sp],#16 - \\ blr x1 - \\ mov x8,#93 // SYS_exit - \\ svc #0 - ); - } else if (builtin.arch == builtin.Arch.arm) { - asm volatile ( - \\ stmfd sp!,{r4,r5,r6,r7} - \\ mov r7,#120 - \\ mov r6,r3 - \\ mov r5,r0 - \\ mov r0,r2 - \\ and r1,r1,#-16 - \\ ldr r2,[sp,#16] - \\ ldr r3,[sp,#20] - \\ ldr r4,[sp,#24] - \\ svc 0 - \\ tst r0,r0 - \\ beq 1f - \\ ldmfd sp!,{r4,r5,r6,r7} - \\ bx lr - \\ - \\1: mov r0,r6 - \\ bl 3f - \\2: mov r7,#1 - \\ svc 0 - \\ b 2b - \\3: bx r5 - ); - } else { - @compileError("Implement clone() for this arch."); + // syscall(SYS_clone, flags, stack, ptid, tls, ctid) + // x8, x0, x1, x2, x3, x4 + asm volatile ( + \\ // align stack and save func,arg + \\ and x1,x1,#-16 + \\ stp x0,x3,[x1,#-16]! + \\ + \\ // syscall + \\ uxtw x0,w2 + \\ mov x2,x4 + \\ mov x3,x5 + \\ mov x4,x6 + \\ mov x8,#220 // SYS_clone + \\ svc #0 + \\ + \\ cbz x0,1f + \\ // parent + \\ ret + \\ // child + \\1: ldp x1,x0,[sp],#16 + \\ blr x1 + \\ mov x8,#93 // SYS_exit + \\ svc #0 + ); + }, + .arm => { + asm volatile ( + \\ stmfd sp!,{r4,r5,r6,r7} + \\ mov r7,#120 + \\ mov r6,r3 + \\ mov r5,r0 + \\ mov r0,r2 + \\ and r1,r1,#-16 + \\ ldr r2,[sp,#16] + \\ ldr r3,[sp,#20] + \\ ldr r4,[sp,#24] + \\ svc 0 + \\ tst r0,r0 + \\ beq 1f + \\ ldmfd sp!,{r4,r5,r6,r7} + \\ bx lr + \\ + \\1: mov r0,r6 + \\ bl 3f + \\2: mov r7,#1 + \\ svc 0 + \\ b 2b + \\3: bx r5 + ); + }, + .riscv64 => { + // __clone(func, stack, flags, arg, ptid, tls, ctid) + // a0, a1, a2, a3, a4, a5, a6 + + // syscall(SYS_clone, flags, stack, ptid, tls, ctid) + // a7 a0, a1, a2, a3, a4 + asm volatile ( + \\ # Save func and arg to stack + \\ addi a1, a1, -16 + \\ sd a0, 0(a1) + \\ sd a3, 8(a1) + \\ + \\ # Call SYS_clone + \\ mv a0, a2 + \\ mv a2, a4 + \\ mv a3, a5 + \\ mv a4, a6 + \\ li a7, 220 # SYS_clone + \\ ecall + \\ + \\ beqz a0, 1f + \\ # Parent + \\ ret + \\ + \\ # Child + \\1: ld a1, 0(sp) + \\ ld a0, 8(sp) + \\ jalr a1 + \\ + \\ # Exit + \\ li a7, 93 # SYS_exit + \\ ecall + ); + }, + else => @compileError("Implement clone() for this arch."), } }