mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
std.debug: add s390x-linux unwind support
This commit is contained in:
parent
006bc5a8ca
commit
8263f55ab2
@ -1433,6 +1433,7 @@ pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 {
|
||||
.arm, .armeb, .thumb, .thumbeb => 15,
|
||||
.loongarch32, .loongarch64 => 32,
|
||||
.riscv32, .riscv32be, .riscv64, .riscv64be => 32,
|
||||
.s390x => 65,
|
||||
.x86 => 8,
|
||||
.x86_64 => 16,
|
||||
else => null,
|
||||
@ -1445,6 +1446,7 @@ pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 {
|
||||
.arm, .armeb, .thumb, .thumbeb => 11,
|
||||
.loongarch32, .loongarch64 => 22,
|
||||
.riscv32, .riscv32be, .riscv64, .riscv64be => 8,
|
||||
.s390x => 11,
|
||||
.x86 => 5,
|
||||
.x86_64 => 6,
|
||||
else => unreachable,
|
||||
@ -1457,6 +1459,7 @@ pub fn spRegNum(arch: std.Target.Cpu.Arch) u16 {
|
||||
.arm, .armeb, .thumb, .thumbeb => 13,
|
||||
.loongarch32, .loongarch64 => 3,
|
||||
.riscv32, .riscv32be, .riscv64, .riscv64be => 2,
|
||||
.s390x => 15,
|
||||
.x86 => 4,
|
||||
.x86_64 => 7,
|
||||
else => unreachable,
|
||||
|
||||
@ -176,7 +176,11 @@ fn nextInner(unwinder: *SelfUnwinder, gpa: Allocator, cache_entry: *const CacheE
|
||||
break :cfa try applyOffset(ptr.*, ro.offset);
|
||||
},
|
||||
.expression => |expr| cfa: {
|
||||
// On all implemented architectures, the CFA is defined to be the previous frame's SP
|
||||
// On most implemented architectures, the CFA is defined to be the previous frame's SP.
|
||||
//
|
||||
// On s390x, it's defined to be SP + 160 (ELF ABI s390x Supplement §1.6.3); however,
|
||||
// what this actually means is that there will be a `def_cfa r15 + 160`, so nothing
|
||||
// special for us to do.
|
||||
const prev_cfa_val = (try regNative(&unwinder.cpu_state, sp_reg_num)).*;
|
||||
unwinder.expr_vm.reset();
|
||||
const value = try unwinder.expr_vm.run(expr, gpa, .{
|
||||
|
||||
@ -90,6 +90,7 @@ pub const can_unwind: bool = s: {
|
||||
.loongarch64,
|
||||
.riscv32,
|
||||
.riscv64,
|
||||
.s390x,
|
||||
.x86,
|
||||
.x86_64,
|
||||
},
|
||||
|
||||
@ -8,6 +8,7 @@ else switch (native_arch) {
|
||||
.arm, .armeb, .thumb, .thumbeb => Arm,
|
||||
.loongarch32, .loongarch64 => LoongArch,
|
||||
.riscv32, .riscv32be, .riscv64, .riscv64be => Riscv,
|
||||
.s390x => S390x,
|
||||
.x86 => X86,
|
||||
.x86_64 => X86_64,
|
||||
else => noreturn,
|
||||
@ -189,6 +190,17 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native {
|
||||
},
|
||||
else => null,
|
||||
},
|
||||
.s390x => switch (builtin.os.tag) {
|
||||
.linux => .{
|
||||
.r = uc.mcontext.gregs,
|
||||
.f = uc.mcontext.fregs,
|
||||
.psw = .{
|
||||
.mask = uc.mcontext.psw.mask,
|
||||
.addr = uc.mcontext.psw.addr,
|
||||
},
|
||||
},
|
||||
else => null,
|
||||
},
|
||||
else => null,
|
||||
};
|
||||
}
|
||||
@ -677,6 +689,81 @@ pub const Riscv = extern struct {
|
||||
}
|
||||
};
|
||||
|
||||
/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
|
||||
pub const S390x = extern struct {
|
||||
/// The numbered general-purpose registers r0 - r15.
|
||||
r: [16]u64,
|
||||
/// The numbered floating-point registers f0 - f15. Yes, really - they can be used in DWARF CFI.
|
||||
f: [16]f64,
|
||||
/// The program counter.
|
||||
psw: extern struct {
|
||||
mask: u64,
|
||||
addr: u64,
|
||||
},
|
||||
|
||||
pub inline fn current() S390x {
|
||||
var ctx: S390x = undefined;
|
||||
asm volatile (
|
||||
\\ stmg %%r0, %%r15, 0(%%r2)
|
||||
\\ std %%f0, 128(%%r2)
|
||||
\\ std %%f1, 136(%%r2)
|
||||
\\ std %%f2, 144(%%r2)
|
||||
\\ std %%f3, 152(%%r2)
|
||||
\\ std %%f4, 160(%%r2)
|
||||
\\ std %%f5, 168(%%r2)
|
||||
\\ std %%f6, 176(%%r2)
|
||||
\\ std %%f7, 184(%%r2)
|
||||
\\ std %%f8, 192(%%r2)
|
||||
\\ std %%f9, 200(%%r2)
|
||||
\\ std %%f10, 208(%%r2)
|
||||
\\ std %%f11, 216(%%r2)
|
||||
\\ std %%f12, 224(%%r2)
|
||||
\\ std %%f13, 232(%%r2)
|
||||
\\ std %%f14, 240(%%r2)
|
||||
\\ std %%f15, 248(%%r2)
|
||||
\\ epsw %%r0, %%r1
|
||||
\\ stm %%r0, %%r1, 256(%%r2)
|
||||
\\ larl %%r0, .
|
||||
\\ stg %%r0, 264(%%r2)
|
||||
\\ lg %%r0, 0(%%r2)
|
||||
\\ lg %%r1, 8(%%r2)
|
||||
:
|
||||
: [gprs] "{r2}" (&ctx),
|
||||
: .{ .memory = true });
|
||||
return ctx;
|
||||
}
|
||||
|
||||
pub fn dwarfRegisterBytes(ctx: *S390x, register_num: u16) DwarfRegisterError![]u8 {
|
||||
switch (register_num) {
|
||||
0...15 => return @ptrCast(&ctx.r[register_num]),
|
||||
// Why???
|
||||
16 => return @ptrCast(&ctx.f[0]),
|
||||
17 => return @ptrCast(&ctx.f[2]),
|
||||
18 => return @ptrCast(&ctx.f[4]),
|
||||
19 => return @ptrCast(&ctx.f[6]),
|
||||
20 => return @ptrCast(&ctx.f[1]),
|
||||
21 => return @ptrCast(&ctx.f[3]),
|
||||
22 => return @ptrCast(&ctx.f[5]),
|
||||
23 => return @ptrCast(&ctx.f[7]),
|
||||
24 => return @ptrCast(&ctx.f[8]),
|
||||
25 => return @ptrCast(&ctx.f[10]),
|
||||
26 => return @ptrCast(&ctx.f[12]),
|
||||
27 => return @ptrCast(&ctx.f[14]),
|
||||
28 => return @ptrCast(&ctx.f[9]),
|
||||
29 => return @ptrCast(&ctx.f[11]),
|
||||
30 => return @ptrCast(&ctx.f[13]),
|
||||
31 => return @ptrCast(&ctx.f[15]),
|
||||
64 => return @ptrCast(&ctx.psw.mask),
|
||||
65 => return @ptrCast(&ctx.psw.addr),
|
||||
|
||||
48...63 => return error.UnsupportedRegister, // a0 - a15
|
||||
68...83 => return error.UnsupportedRegister, // v16 - v31
|
||||
|
||||
else => return error.InvalidRegister,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const signal_ucontext_t = switch (native_os) {
|
||||
.linux => std.os.linux.ucontext_t,
|
||||
.emscripten => std.os.emscripten.ucontext_t,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user