From 6e2622661cdf9dd48cf962e5d6902324b15468c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Marie?= Date: Wed, 23 Dec 2020 12:39:20 +0000 Subject: [PATCH] openbsd: implement segfault handling on openbsd x86_64 --- lib/std/debug.zig | 5 +++- lib/std/os/bits/openbsd.zig | 54 +++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/lib/std/debug.zig b/lib/std/debug.zig index e93143c598..7284237cb2 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -1696,7 +1696,7 @@ fn getDebugInfoAllocator() *mem.Allocator { pub const have_segfault_handling_support = switch (builtin.os.tag) { .linux, .netbsd => true, .windows => true, - .freebsd => @hasDecl(os, "ucontext_t"), + .freebsd, .openbsd => @hasDecl(os, "ucontext_t"), else => false, }; pub const enable_segfault_handler: bool = if (@hasDecl(root, "enable_segfault_handler")) @@ -1760,6 +1760,7 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_v .linux => @ptrToInt(info.fields.sigfault.addr), .freebsd => @ptrToInt(info.addr), .netbsd => @ptrToInt(info.info.reason.fault.addr), + .openbsd => @ptrToInt(info.data.fault.addr), else => unreachable, }; @@ -1786,10 +1787,12 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_v const ip = switch (builtin.os.tag) { .linux, .netbsd => @intCast(usize, ctx.mcontext.gregs[os.REG_RIP]), .freebsd => @intCast(usize, ctx.mcontext.rip), + .openbsd => @intCast(usize, ctx.sc_rip), else => unreachable, }; const bp = switch (builtin.os.tag) { .linux, .netbsd => @intCast(usize, ctx.mcontext.gregs[os.REG_RBP]), + .openbsd => @intCast(usize, ctx.sc_rbp), .freebsd => @intCast(usize, ctx.mcontext.rbp), else => unreachable, }; diff --git a/lib/std/os/bits/openbsd.zig b/lib/std/os/bits/openbsd.zig index a9ab929a42..c84a6de01a 100644 --- a/lib/std/os/bits/openbsd.zig +++ b/lib/std/os/bits/openbsd.zig @@ -809,6 +809,60 @@ comptime { std.debug.assert(@sizeOf(siginfo_t) == 136); } +pub usingnamespace switch (builtin.arch) { + .x86_64 => struct { + pub const ucontext_t = extern struct { + sc_rdi: c_long, + sc_rsi: c_long, + sc_rdx: c_long, + sc_rcx: c_long, + sc_r8: c_long, + sc_r9: c_long, + sc_r10: c_long, + sc_r11: c_long, + sc_r12: c_long, + sc_r13: c_long, + sc_r14: c_long, + sc_r15: c_long, + sc_rbp: c_long, + sc_rbx: c_long, + sc_rax: c_long, + sc_gs: c_long, + sc_fs: c_long, + sc_es: c_long, + sc_ds: c_long, + sc_trapno: c_long, + sc_err: c_long, + sc_rip: c_long, + sc_cs: c_long, + sc_rflags: c_long, + sc_rsp: c_long, + sc_ss: c_long, + + sc_fpstate: fxsave64, + __sc_unused: c_int, + sc_mask: c_int, + sc_cookie: c_long, + }; + + pub const fxsave64 = packed struct { + fx_fcw: u16, + fx_fsw: u16, + fx_ftw: u8, + fx_unused1: u8, + fx_fop: u16, + fx_rip: u64, + fx_rdp: u64, + fx_mxcsr: u32, + fx_mxcsr_mask: u32, + fx_st: [8][2]u64, + fx_xmm: [16][2]u64, + fx_unused3: [96]u8, + }; + }, + else => struct {}, +}; + pub const sigset_t = c_uint; pub const empty_sigset: sigset_t = 0;