std.debug: add unwind support for powerpc*-linux

This commit is contained in:
Alex Rønne Petersen 2025-10-07 00:05:39 +02:00
parent ca73d697b9
commit aa74eb505a
No known key found for this signature in database
3 changed files with 124 additions and 0 deletions

View File

@ -1434,6 +1434,7 @@ pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 {
.hexagon => 76,
.loongarch32, .loongarch64 => 32,
.mips, .mipsel, .mips64, .mips64el => 37,
.powerpc, .powerpcle, .powerpc64, .powerpc64le => 357,
.riscv32, .riscv32be, .riscv64, .riscv64be => 32,
.s390x => 65,
.x86 => 8,
@ -1449,6 +1450,7 @@ pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 {
.hexagon => 30,
.loongarch32, .loongarch64 => 22,
.mips, .mipsel, .mips64, .mips64el => 30,
.powerpc, .powerpcle, .powerpc64, .powerpc64le => 1,
.riscv32, .riscv32be, .riscv64, .riscv64be => 8,
.s390x => 11,
.x86 => 5,
@ -1464,6 +1466,7 @@ pub fn spRegNum(arch: std.Target.Cpu.Arch) u16 {
.hexagon => 29,
.loongarch32, .loongarch64 => 3,
.mips, .mipsel, .mips64, .mips64el => 29,
.powerpc, .powerpcle, .powerpc64, .powerpc64le => 1,
.riscv32, .riscv32be, .riscv64, .riscv64be => 2,
.s390x => 15,
.x86 => 4,

View File

@ -103,6 +103,10 @@ pub const can_unwind: bool = s: {
.mipsel,
.mips64,
.mips64el,
.powerpc,
.powerpcle,
.powerpc64,
.powerpc64le,
.riscv32,
.riscv64,
.s390x,

View File

@ -9,6 +9,7 @@ else switch (native_arch) {
.hexagon => Hexagon,
.loongarch32, .loongarch64 => LoongArch,
.mips, .mipsel, .mips64, .mips64el => Mips,
.powerpc, .powerpcle, .powerpc64, .powerpc64le => Powerpc,
.riscv32, .riscv32be, .riscv64, .riscv64be => Riscv,
.s390x => S390x,
.x86 => X86,
@ -216,6 +217,14 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native {
},
else => null,
},
.powerpc, .powerpcle, .powerpc64, .powerpc64le => switch (builtin.os.tag) {
.linux => .{
.r = uc.mcontext.gp_regs[0..32].*,
.pc = uc.mcontext.gp_regs[32],
.lr = uc.mcontext.gp_regs[36],
},
else => null,
},
.riscv32, .riscv64 => switch (builtin.os.tag) {
.linux => .{
.r = [1]usize{0} ++ uc.mcontext.gregs[1..].*, // r0 position is used for pc; replace with zero
@ -808,6 +817,114 @@ pub const Mips = extern struct {
}
};
/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
pub const Powerpc = extern struct {
/// The numbered general-purpose registers r0 - r31.
r: [32]Gpr,
pc: Gpr,
lr: Gpr,
pub const Gpr = if (builtin.target.cpu.arch.isPowerPC64()) u64 else u32;
pub inline fn current() Powerpc {
var ctx: Powerpc = undefined;
asm volatile (if (Gpr == u64)
\\ std 0, 0(10)
\\ std 1, 8(10)
\\ std 2, 16(10)
\\ std 3, 24(10)
\\ std 4, 32(10)
\\ std 5, 40(10)
\\ std 6, 48(10)
\\ std 7, 56(10)
\\ std 8, 64(10)
\\ std 9, 72(10)
\\ std 10, 80(10)
\\ std 11, 88(10)
\\ std 12, 96(10)
\\ std 13, 104(10)
\\ std 14, 112(10)
\\ std 15, 120(10)
\\ std 16, 128(10)
\\ std 17, 136(10)
\\ std 18, 144(10)
\\ std 19, 152(10)
\\ std 20, 160(10)
\\ std 21, 168(10)
\\ std 22, 176(10)
\\ std 23, 184(10)
\\ std 24, 192(10)
\\ std 25, 200(10)
\\ std 26, 208(10)
\\ std 27, 216(10)
\\ std 28, 224(10)
\\ std 29, 232(10)
\\ std 30, 240(10)
\\ std 31, 248(10)
\\ mflr 8
\\ std 8, 264(10)
\\ bl 1f
\\1:
\\ mflr 8
\\ std 8, 256(10)
\\ ld 8, 64(10)
else
\\ stw 0, 0(10)
\\ stw 1, 4(10)
\\ stw 2, 8(10)
\\ stw 3, 12(10)
\\ stw 4, 16(10)
\\ stw 5, 20(10)
\\ stw 6, 24(10)
\\ stw 7, 28(10)
\\ stw 8, 32(10)
\\ stw 9, 36(10)
\\ stw 10, 40(10)
\\ stw 11, 44(10)
\\ stw 12, 48(10)
\\ stw 13, 52(10)
\\ stw 14, 56(10)
\\ stw 15, 60(10)
\\ stw 16, 64(10)
\\ stw 17, 68(10)
\\ stw 18, 72(10)
\\ stw 19, 76(10)
\\ stw 20, 80(10)
\\ stw 21, 84(10)
\\ stw 22, 88(10)
\\ stw 23, 92(10)
\\ stw 24, 96(10)
\\ stw 25, 100(10)
\\ stw 26, 104(10)
\\ stw 27, 108(10)
\\ stw 28, 112(10)
\\ stw 29, 116(10)
\\ stw 30, 120(10)
\\ stw 31, 124(10)
\\ mflr 8
\\ stw 8, 132(10)
\\ bl 1f
\\1:
\\ mflr 8
\\ stw 8, 128(10)
\\ lwz 8, 32(10)
:
: [gprs] "{r10}" (&ctx),
: .{ .lr = true, .memory = true });
return ctx;
}
pub fn dwarfRegisterBytes(ctx: *Powerpc, register_num: u16) DwarfRegisterError![]u8 {
switch (register_num) {
0...31 => return @ptrCast(&ctx.r[register_num]),
65 => return @ptrCast(&ctx.lr),
357 => return @ptrCast(&ctx.pc),
else => return error.InvalidRegister,
}
}
};
/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
pub const Riscv = extern struct {
/// The numbered general-purpose registers r0 - r31. r0 must be zero.