feature. See also
. The project being documented here (as the example) is the Zig library itself.
cpu_context.fromPosixSignalContext
pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native
File
Code
pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native {
if (signal_ucontext_t == void) return null;
const uc: *const signal_ucontext_t = @ptrCast(@alignCast(ctx_ptr));
if (native_arch.isArc() and native_os == .linux) {
var native: Native = .{
.r = [_]u32{ uc.mcontext.r31, uc.mcontext.r30, 0, uc.mcontext.r28 } ++
uc.mcontext.r27_26 ++
uc.mcontext.r25_13 ++
uc.mcontext.r12_0,
.pcl = uc.mcontext.pcl,
};
std.mem.reverse(u32, native.r[0..]);
return native;
} else if (native_arch == .loongarch32 and native_os == .linux) {
return .{
.r = s: {
var regs: [32]LoongArch.Gpr = undefined;
for (uc.mcontext.r, 0..) |r, i| regs[i] = @truncate(r);
break :s regs;
},
.pc = @truncate(uc.mcontext.pc),
};
} else if (native_arch == .m88k and native_os == .openbsd) {
// to user space, so we need to do that here.
return .{
.r = uc.mcontext.r,
.xip = uc.mcontext.xip & ~@as(u32, 0b11),
};
} else if (native_arch.isMIPS32() and native_os == .linux) {
return .{
.r = s: {
var regs: [32]Mips.Gpr = undefined;
for (uc.mcontext.r, 0..) |r, i| regs[i] = @truncate(r);
break :s regs;
},
.pc = @truncate(uc.mcontext.pc),
};
} else if (native_arch.isSPARC() and native_os == .linux) {
const SparcStackFrame = extern struct {
l: [8]usize,
i: [8]usize,
_x: [8]usize,
};
// stack and passes a pointer to its `info` field to the signal handler. This implies that
// prior to said `info` field, we will find the `ss` field which, among other things,
// contains the incoming and local registers of the interrupted code.
const frame = @as(*const SparcStackFrame, @ptrFromInt(@as(usize, @intFromPtr(ctx_ptr)) - @sizeOf(SparcStackFrame)));
return .{
.g = uc.mcontext.g,
.o = uc.mcontext.o,
.l = frame.l,
.i = frame.i,
.pc = uc.mcontext.pc,
};
}
return switch (native_arch) {
.arm, .armeb, .thumb, .thumbeb => .{
.r = uc.mcontext.r ++ [_]u32{uc.mcontext.pc},
},
.aarch64, .aarch64_be => .{
.x = uc.mcontext.x ++ [_]u64{uc.mcontext.lr},
.sp = uc.mcontext.sp,
.pc = uc.mcontext.pc,
},
.alpha => .{
.r = uc.mcontext.r,
.pc = uc.mcontext.pc,
},
.csky => .{
.r = uc.mcontext.r0_13 ++
[_]u32{ uc.mcontext.r14, uc.mcontext.r15 } ++
uc.mcontext.r16_30 ++
[_]u32{uc.mcontext.r31},
.pc = uc.mcontext.pc,
},
.hexagon, .loongarch32, .loongarch64, .mips, .mipsel, .mips64, .mips64el, .or1k => .{
.r = uc.mcontext.r,
.pc = uc.mcontext.pc,
},
.m68k => .{
.d = uc.mcontext.d,
.a = uc.mcontext.a,
.pc = uc.mcontext.pc,
},
.powerpc, .powerpcle, .powerpc64, .powerpc64le => .{
.r = uc.mcontext.r,
.pc = uc.mcontext.pc,
.lr = uc.mcontext.lr,
},
.riscv32, .riscv32be, .riscv64, .riscv64be => .{
// group the registers by ABI mnemonic rather than register number.
.x = [_]Riscv.Gpr{0} ++
uc.mcontext.ra_sp_gp_tp ++
uc.mcontext.t0_2 ++
uc.mcontext.s0_1 ++
uc.mcontext.a ++
uc.mcontext.s2_11 ++
uc.mcontext.t3_6,
.pc = uc.mcontext.pc,
},
.s390x => .{
.r = uc.mcontext.r,
.psw = .{
.mask = uc.mcontext.psw.mask,
.addr = uc.mcontext.psw.addr,
},
},
.x86 => .{ .gprs = .init(.{
.eax = uc.mcontext.eax,
.ecx = uc.mcontext.ecx,
.edx = uc.mcontext.edx,
.ebx = uc.mcontext.ebx,
.esp = uc.mcontext.esp,
.ebp = uc.mcontext.ebp,
.esi = uc.mcontext.esi,
.edi = uc.mcontext.edi,
.eip = uc.mcontext.eip,
}) },
.x86_64 => .{ .gprs = .init(.{
.rax = uc.mcontext.rax,
.rdx = uc.mcontext.rdx,
.rcx = uc.mcontext.rcx,
.rbx = uc.mcontext.rbx,
.rsi = uc.mcontext.rsi,
.rdi = uc.mcontext.rdi,
.rbp = uc.mcontext.rbp,
.rsp = uc.mcontext.rsp,
.r8 = uc.mcontext.r8,
.r9 = uc.mcontext.r9,
.r10 = uc.mcontext.r10,
.r11 = uc.mcontext.r11,
.r12 = uc.mcontext.r12,
.r13 = uc.mcontext.r13,
.r14 = uc.mcontext.r14,
.r15 = uc.mcontext.r15,
.rip = uc.mcontext.rip,
}) },
else => comptime unreachable,
};
}