diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index b10b582dc2..f4ca9cd6dd 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -6,6 +6,26 @@ const native_arch = builtin.target.cpu.arch; const maxInt = std.math.maxInt; const iovec_const = std.os.iovec_const; +const arch_bits = switch (native_arch) { + .aarch64 => @import("darwin/aarch64.zig"), + .x86_64 => @import("darwin/x86_64.zig"), + else => struct {}, +}; + +pub const ucontext_t = extern struct { + onstack: c_int, + sigmask: sigset_t, + stack: stack_t, + link: ?*ucontext_t, + mcsize: u64, + mcontext: *mcontext_t, +}; + +pub const mcontext_t = extern struct { + es: arch_bits.exception_state, + ss: arch_bits.thread_state, +}; + extern "c" fn __error() *c_int; pub extern "c" fn NSVersionOfRunTimeLibrary(library_name: [*:0]const u8) u32; pub extern "c" fn _NSGetExecutablePath(buf: [*:0]u8, bufsize: *u32) c_int; @@ -478,51 +498,6 @@ pub const SIG = struct { pub const USR2 = 31; }; -pub const ucontext_t = extern struct { - onstack: c_int, - sigmask: sigset_t, - stack: stack_t, - link: ?*ucontext_t, - mcsize: u64, - mcontext: *mcontext_t, -}; - -pub const exception_state = extern struct { - trapno: u16, - cpu: u16, - err: u32, - faultvaddr: u64, -}; - -pub const thread_state = extern struct { - rax: u64, - rbx: u64, - rcx: u64, - rdx: u64, - rdi: u64, - rsi: u64, - rbp: u64, - rsp: u64, - r8: u64, - r9: u64, - r10: u64, - r11: u64, - r12: u64, - r13: u64, - r14: u64, - r15: u64, - rip: u64, - rflags: u64, - cs: u64, - fs: u64, - gs: u64, -}; - -pub const mcontext_t = extern struct { - es: exception_state, - ss: thread_state, -}; - pub const siginfo_t = extern struct { signo: c_int, errno: c_int, diff --git a/lib/std/c/darwin/aarch64.zig b/lib/std/c/darwin/aarch64.zig new file mode 100644 index 0000000000..70153b5dfb --- /dev/null +++ b/lib/std/c/darwin/aarch64.zig @@ -0,0 +1,18 @@ +// See C headers in +// lib/libc/include/aarch64-macos.12-gnu/mach/arm/_structs.h + +pub const exception_state = extern struct { + far: u64, // Virtual Fault Address + esr: u32, // Exception syndrome + exception: u32, // Number of arm exception taken +}; + +pub const thread_state = extern struct { + regs: [29]u64, // General purpose registers + fp: u64, // Frame pointer x29 + lr: u64, // Link register x30 + sp: u64, // Stack pointer x31 + pc: u64, // Program counter + cpsr: u32, // Current program status register + __pad: u32, +}; diff --git a/lib/std/c/darwin/x86_64.zig b/lib/std/c/darwin/x86_64.zig new file mode 100644 index 0000000000..a7f2c509c7 --- /dev/null +++ b/lib/std/c/darwin/x86_64.zig @@ -0,0 +1,30 @@ +pub const exception_state = extern struct { + trapno: u16, + cpu: u16, + err: u32, + faultvaddr: u64, +}; + +pub const thread_state = extern struct { + rax: u64, + rbx: u64, + rcx: u64, + rdx: u64, + rdi: u64, + rsi: u64, + rbp: u64, + rsp: u64, + r8: u64, + r9: u64, + r10: u64, + r11: u64, + r12: u64, + r13: u64, + r14: u64, + r15: u64, + rip: u64, + rflags: u64, + cs: u64, + fs: u64, + gs: u64, +}; diff --git a/lib/std/debug.zig b/lib/std/debug.zig index caf7c44bc2..135d2017e3 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -1601,9 +1601,13 @@ 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 = switch (native_os) { - .linux, .netbsd, .solaris => true, - .macos => native_arch == .x86_64, - .windows => true, + .linux, + .macos, + .netbsd, + .solaris, + .windows, + => true, + .freebsd, .openbsd => @hasDecl(os.system, "ucontext_t"), else => false, }; @@ -1717,9 +1721,15 @@ fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const any }, .aarch64 => { const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr)); - const ip = @intCast(usize, ctx.mcontext.pc); + const ip = switch (native_os) { + .macos => @intCast(usize, ctx.mcontext.ss.pc), + else => @intCast(usize, ctx.mcontext.pc), + }; // x29 is the ABI-designated frame pointer - const bp = @intCast(usize, ctx.mcontext.regs[29]); + const bp = switch (native_os) { + .macos => @intCast(usize, ctx.mcontext.ss.fp), + else => @intCast(usize, ctx.mcontext.regs[29]), + }; dumpStackTraceFromBase(bp, ip); }, else => {},