Commit 070ace4b22

LemonBoy <thatlemon@gmail.com>
2020-04-01 11:03:36
std: Fix more NetBSD bits
Fix some more libc definitions.
1 parent a5af78c
Changed files (4)
lib/std/c/netbsd.zig
@@ -10,36 +10,58 @@ pub const dl_iterate_phdr_callback = extern fn (info: *dl_phdr_info, size: usize
 pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
 
 pub extern "c" fn __fstat50(fd: fd_t, buf: *Stat) c_int;
+pub extern "c" fn __stat50(path: [*:0]const u8, buf: *Stat) c_int;
 pub extern "c" fn __clock_gettime50(clk_id: c_int, tp: *timespec) c_int;
 pub extern "c" fn __clock_getres50(clk_id: c_int, tp: *timespec) c_int;
 pub extern "c" fn __getdents30(fd: c_int, buf_ptr: [*]u8, nbytes: usize) c_int;
 pub extern "c" fn __sigaltstack14(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
+pub extern "c" fn __nanosleep50(rqtp: *const timespec, rmtp: ?*timespec) c_int;
+pub extern "c" fn __sigaction14(sig: c_int, noalias act: *const Sigaction, noalias oact: ?*Sigaction) c_int;
+pub extern "c" fn __sigprocmask14(how: c_int, noalias set: ?*const sigset_t, noalias oset: ?*sigset_t) c_int;
+pub extern "c" fn __socket30(domain: c_uint, sock_type: c_uint, protocol: c_uint) c_int;
+pub extern "c" fn __gettimeofday50(noalias tv: ?*timeval, noalias tz: ?*timezone) c_int;
+pub extern "c" fn __getrusage50(who: c_int, usage: *rusage) c_int;
+// instead of sched_yield
+pub extern "c" fn __libc_thr_yield() c_int;
 
 pub const pthread_mutex_t = extern struct {
-    ptm_magic: c_uint = 0x33330003,
-    ptm_errorcheck: padded_spin_t = 0,
-    ptm_unused: padded_spin_t = 0,
+    ptm_magic: u32 = 0x33330003,
+    ptm_errorcheck: padded_pthread_spin_t = 0,
+    ptm_ceiling: padded_pthread_spin_t = 0,
     ptm_owner: usize = 0,
     ptm_waiters: ?*u8 = null,
-    ptm_recursed: c_uint = 0,
+    ptm_recursed: u32 = 0,
     ptm_spare2: ?*c_void = null,
 };
+
 pub const pthread_cond_t = extern struct {
-    ptc_magic: c_uint = 0x55550005,
+    ptc_magic: u32 = 0x55550005,
     ptc_lock: pthread_spin_t = 0,
     ptc_waiters_first: ?*u8 = null,
     ptc_waiters_last: ?*u8 = null,
     ptc_mutex: ?*pthread_mutex_t = null,
     ptc_private: ?*c_void = null,
 };
-const pthread_spin_t = if (builtin.arch == .arm or .arch == .powerpc) c_int else u8;
-const padded_spin_t = switch (builtin.arch) {
-    .sparc, .sparcel, .sparcv9, .i386, .x86_64, .le64 => u32,
-    else => spin_t,
+
+const pthread_spin_t = switch (builtin.arch) {
+    .aarch64, .aarch64_be, .aarch64_32 => u8,
+    .mips, .mipsel, .mips64, .mips64el => u32,
+    .powerpc, .powerpc64, .powerpc64le => i32,
+    .i386, .x86_64 => u8,
+    .arm, .armeb, .thumb, .thumbeb => i32,
+    .sparc, .sparcel, .sparcv9 => u8,
+    .riscv32, .riscv64 => u32,
+    else => @compileError("undefined pthread_spin_t for this arch"),
+};
+
+const padded_pthread_spin_t = switch (builtin.arch) {
+    .i386, .x86_64 => u32,
+    .sparc, .sparcel, .sparcv9 => u32,
+    else => pthread_spin_t,
 };
 
 pub const pthread_attr_t = extern struct {
     pta_magic: u32,
-    pta_flags: c_int,
-    pta_private: *c_void,
+    pta_flags: i32,
+    pta_private: ?*c_void,
 };
lib/std/os/bits/linux.zig
@@ -813,13 +813,13 @@ pub const app_mask: sigset_t = [2]u32{ 0xfffffffc, 0x7fffffff } ++ [_]u32{0xffff
 pub const k_sigaction = if (is_mips)
     extern struct {
         flags: usize,
-        sigaction: ?extern fn (i32, *siginfo_t, *c_void) void,
+        sigaction: ?extern fn (i32, *siginfo_t, ?*c_void) void,
         mask: [4]u32,
         restorer: extern fn () void,
     }
 else
     extern struct {
-        sigaction: ?extern fn (i32, *siginfo_t, *c_void) void,
+        sigaction: ?extern fn (i32, *siginfo_t, ?*c_void) void,
         flags: usize,
         restorer: extern fn () void,
         mask: [2]u32,
lib/std/os/bits/netbsd.zig
@@ -1,12 +1,22 @@
 const std = @import("../../std.zig");
+const builtin = std.builtin;
 const maxInt = std.math.maxInt;
 
+pub const blkcnt_t = i64;
+pub const blksize_t = i32;
+pub const clock_t = u32;
+pub const dev_t = u64;
 pub const fd_t = i32;
-pub const pid_t = i32;
-pub const mode_t = u32;
+pub const gid_t = u32;
 pub const ino_t = u64;
+pub const mode_t = u32;
+pub const nlink_t = u32;
 pub const off_t = i64;
+pub const pid_t = i32;
 pub const socklen_t = u32;
+pub const time_t = i64;
+pub const uid_t = u32;
+pub const lwpid_t = i32;
 
 /// Renamed from `kevent` to `Kevent` to avoid conflict with function name.
 pub const Kevent = extern struct {
@@ -137,23 +147,20 @@ pub const msghdr_const = extern struct {
 /// in C, macros are used to hide the differences. Here we use
 /// methods to accomplish this.
 pub const Stat = extern struct {
-    dev: u64,
-    mode: u32,
+    dev: dev_t,
+    mode: mode_t,
     ino: ino_t,
-    nlink: usize,
-
-    uid: u32,
-    gid: u32,
-    rdev: u64,
-
+    nlink: nlink_t,
+    uid: uid_t,
+    gid: gid_t,
+    rdev: dev_t,
     atim: timespec,
     mtim: timespec,
     ctim: timespec,
     birthtim: timespec,
-
     size: off_t,
-    blocks: i64,
-    blksize: isize,
+    blocks: blkcnt_t,
+    blksize: blksize_t,
     flags: u32,
     gen: u32,
     __spare: [2]u32,
@@ -176,12 +183,14 @@ pub const timespec = extern struct {
     tv_nsec: isize,
 };
 
+pub const MAXNAMLEN = 511;
+
 pub const dirent = extern struct {
-    d_fileno: u64,
+    d_fileno: ino_t,
     d_reclen: u16,
     d_namlen: u16,
     d_type: u8,
-    d_name: [512]u8,
+    d_name: [MAXNAMLEN:0]u8,
 
     pub fn reclen(self: dirent) u16 {
         return self.d_reclen;
@@ -685,23 +694,74 @@ pub const winsize = extern struct {
 
 const NSIG = 32;
 
-pub const SIG_ERR = @intToPtr(extern fn (i32) void, maxInt(usize));
-pub const SIG_DFL = @intToPtr(extern fn (i32) void, 0);
-pub const SIG_IGN = @intToPtr(extern fn (i32) void, 1);
+pub const SIG_ERR = @intToPtr(?Sigaction.sigaction_fn, maxInt(usize));
+pub const SIG_DFL = @intToPtr(?Sigaction.sigaction_fn, 0);
+pub const SIG_IGN = @intToPtr(?Sigaction.sigaction_fn, 1);
 
 /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
 pub const Sigaction = extern struct {
+    pub const sigaction_fn = fn (i32, *siginfo_t, ?*c_void) callconv(.C) void;
     /// signal handler
-    __sigaction_u: extern union {
-        __sa_handler: extern fn (i32) void,
-        __sa_sigaction: extern fn (i32, *__siginfo, usize) void,
-    },
+    sigaction: ?sigaction_fn,
+    /// signal mask to apply
+    mask: sigset_t,
+    /// signal options
+    flags: u32,
+};
 
-    /// see signal options
-    sa_flags: u32,
+pub const sigval_t = extern union {
+    int: i32,
+    ptr: ?*c_void,
+};
 
-    /// signal mask to apply
-    sa_mask: sigset_t,
+pub const siginfo_t = extern union {
+    pad: [128]u8,
+    info: _ksiginfo,
+};
+
+pub const _ksiginfo = extern struct {
+    signo: i32,
+    code: i32,
+    errno: i32,
+    // 64bit architectures insert 4bytes of padding here, this is done by
+    // correctly aligning the reason field
+    reason: extern union {
+        rt: extern struct {
+            pid: pid_t,
+            uid: uid_t,
+            value: sigval_t,
+        },
+        child: extern struct {
+            pid: pid_t,
+            uid: uid_t,
+            status: i32,
+            utime: clock_t,
+            stime: clock_t,
+        },
+        fault: extern struct {
+            addr: ?*c_void,
+            trap: i32,
+            trap2: i32,
+            trap3: i32,
+        },
+        poll: extern struct {
+            band: i32,
+            fd: i32,
+        },
+        syscall: extern struct {
+            sysnum: i32,
+            retval: [2]i32,
+            @"error": i32,
+            args: [8]u64,
+        },
+        ptrace_state: extern struct {
+            pe_report_event: i32,
+            option: extern union {
+                pe_other_pid: pid_t,
+                pe_lwp: lwpid_t,
+            },
+        },
+    } align(@sizeOf(usize)),
 };
 
 pub const _SIG_WORDS = 4;
@@ -724,6 +784,34 @@ pub const sigset_t = extern struct {
     __bits: [_SIG_WORDS]u32,
 };
 
+pub const empty_sigset = sigset_t{ .__bits = [_]u32{0} ** _SIG_WORDS };
+
+// XXX x86_64 specific
+pub const mcontext_t = extern struct {
+    gregs: [26]u64,
+    mc_tlsbase: u64,
+    fpregs: [512]u8 align(8),
+};
+
+pub const REG_RBP = 12;
+pub const REG_RIP = 21;
+pub const REG_RSP = 24;
+
+pub const ucontext_t = extern struct {
+    flags: u32,
+    link: ?*ucontext_t,
+    sigmask: sigset_t,
+    stack: stack_t,
+    mcontext: mcontext_t,
+    __pad: [switch (builtin.arch) {
+        .i386 => 4,
+        .mips, .mipsel, .mips64, .mips64el => 14,
+        .arm, .armeb, .thumb, .thumbeb => 1,
+        .sparc, .sparcel, .sparcv9 => if (@sizeOf(usize) == 4) 43 else 8,
+        else => 0,
+    }]u32,
+};
+
 pub const EPERM = 1; // Operation not permitted
 pub const ENOENT = 2; // No such file or directory
 pub const ESRCH = 3; // No such process
lib/std/debug.zig
@@ -1666,7 +1666,11 @@ fn getDebugInfoAllocator() *mem.Allocator {
 }
 
 /// Whether or not the current target can print useful debug information when a segfault occurs.
-pub const have_segfault_handling_support = builtin.os.tag == .linux or builtin.os.tag == .windows;
+pub const have_segfault_handling_support = switch (builtin.os.tag) {
+    .linux, .netbsd => true,
+    .windows => true,
+    else => false,
+};
 pub const enable_segfault_handler: bool = if (@hasDecl(root, "enable_segfault_handler"))
     root.enable_segfault_handler
 else
@@ -1718,13 +1722,17 @@ fn resetSegfaultHandler() void {
     os.sigaction(os.SIGBUS, &act, null);
 }
 
-fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *const c_void) callconv(.C) noreturn {
+fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_void) callconv(.C) noreturn {
     // Reset to the default handler so that if a segfault happens in this handler it will crash
     // the process. Also when this handler returns, the original instruction will be repeated
     // and the resulting segfault will crash the process rather than continually dump stack traces.
     resetSegfaultHandler();
 
-    const addr = @ptrToInt(info.fields.sigfault.addr);
+    const addr = switch (builtin.os.tag) {
+        .linux => @ptrToInt(info.fields.sigfault.addr),
+        .netbsd => @ptrToInt(info.info.reason.fault.addr),
+        else => unreachable,
+    };
     switch (sig) {
         os.SIGSEGV => std.debug.warn("Segmentation fault at address 0x{x}\n", .{addr}),
         os.SIGILL => std.debug.warn("Illegal instruction at address 0x{x}\n", .{addr}),