diff options
| author | Alex Rønne Petersen <alex@alexrp.com> | 2025-10-01 23:24:53 +0200 |
|---|---|---|
| committer | Alex Rønne Petersen <alex@alexrp.com> | 2025-10-01 23:47:47 +0200 |
| commit | 97de46dc16b584f5bd7aa2ae9afb2bb77970cd22 (patch) | |
| tree | 67cdb1aaf5dc90c873c6b0c36b53a80c8856a67f /lib/std | |
| parent | 8520e9312eed3b3b8d7f95d4844c83105c91ead1 (diff) | |
| download | zig-97de46dc16b584f5bd7aa2ae9afb2bb77970cd22.tar.gz zig-97de46dc16b584f5bd7aa2ae9afb2bb77970cd22.zip | |
std.debug: add riscv32-linux and riscv64-linux unwind support
Diffstat (limited to 'lib/std')
| -rw-r--r-- | lib/std/debug/Dwarf.zig | 7 | ||||
| -rw-r--r-- | lib/std/debug/SelfInfo/Elf.zig | 2 | ||||
| -rw-r--r-- | lib/std/debug/cpu_context.zig | 106 |
3 files changed, 111 insertions, 4 deletions
diff --git a/lib/std/debug/Dwarf.zig b/lib/std/debug/Dwarf.zig index 3283e59aea..ab064617ea 100644 --- a/lib/std/debug/Dwarf.zig +++ b/lib/std/debug/Dwarf.zig @@ -1432,6 +1432,7 @@ pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 { .aarch64, .aarch64_be => 32, .arm, .armeb, .thumb, .thumbeb => 15, .loongarch32, .loongarch64 => 32, + .riscv32, .riscv32be, .riscv64, .riscv64be => 32, .x86 => 8, .x86_64 => 16, else => null, @@ -1443,6 +1444,7 @@ pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 { .aarch64, .aarch64_be => 29, .arm, .armeb, .thumb, .thumbeb => 11, .loongarch32, .loongarch64 => 22, + .riscv32, .riscv32be, .riscv64, .riscv64be => 8, .x86 => 5, .x86_64 => 6, else => unreachable, @@ -1454,6 +1456,7 @@ pub fn spRegNum(arch: std.Target.Cpu.Arch) u16 { .aarch64, .aarch64_be => 31, .arm, .armeb, .thumb, .thumbeb => 13, .loongarch32, .loongarch64 => 3, + .riscv32, .riscv32be, .riscv64, .riscv64be => 2, .x86 => 4, .x86_64 => 7, else => unreachable, @@ -1473,10 +1476,6 @@ pub fn supportsUnwinding(target: *const std.Target) bool { .spirv64, => false, - // Enabling this causes relocation errors such as: - // error: invalid relocation type R_RISCV_SUB32 at offset 0x20 - .riscv64, .riscv64be, .riscv32, .riscv32be => false, - // Conservative guess. Feel free to update this logic with any targets // that are known to not support Dwarf unwinding. else => true, diff --git a/lib/std/debug/SelfInfo/Elf.zig b/lib/std/debug/SelfInfo/Elf.zig index 7a7a0a2c57..ebb19c2a7b 100644 --- a/lib/std/debug/SelfInfo/Elf.zig +++ b/lib/std/debug/SelfInfo/Elf.zig @@ -88,6 +88,8 @@ pub const can_unwind: bool = s: { .aarch64, .aarch64_be, .loongarch64, + .riscv32, + .riscv64, .x86, .x86_64, }, diff --git a/lib/std/debug/cpu_context.zig b/lib/std/debug/cpu_context.zig index 9b0af90198..981174e954 100644 --- a/lib/std/debug/cpu_context.zig +++ b/lib/std/debug/cpu_context.zig @@ -7,6 +7,7 @@ else switch (native_arch) { .aarch64, .aarch64_be => Aarch64, .arm, .armeb, .thumb, .thumbeb => Arm, .loongarch32, .loongarch64 => LoongArch, + .riscv32, .riscv32be, .riscv64, .riscv64be => Riscv, .x86 => X86, .x86_64 => X86_64, else => noreturn, @@ -181,6 +182,13 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native { }, 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 + .pc = uc.mcontext.gregs[0], + }, + else => null, + }, else => null, }; } @@ -571,6 +579,104 @@ pub const LoongArch = extern struct { } }; +/// 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. + r: [32]usize, + pc: usize, + + pub inline fn current() Riscv { + var ctx: Riscv = undefined; + asm volatile (if (@sizeOf(usize) == 8) + \\ sd zero, 0(t0) + \\ sd ra, 8(t0) + \\ sd sp, 16(t0) + \\ sd gp, 24(t0) + \\ sd tp, 32(t0) + \\ sd t0, 40(t0) + \\ sd t1, 48(t0) + \\ sd t2, 56(t0) + \\ sd s0, 64(t0) + \\ sd s1, 72(t0) + \\ sd a0, 80(t0) + \\ sd a1, 88(t0) + \\ sd a2, 96(t0) + \\ sd a3, 104(t0) + \\ sd a4, 112(t0) + \\ sd a5, 120(t0) + \\ sd a6, 128(t0) + \\ sd a7, 136(t0) + \\ sd s2, 144(t0) + \\ sd s3, 152(t0) + \\ sd s4, 160(t0) + \\ sd s5, 168(t0) + \\ sd s6, 176(t0) + \\ sd s7, 184(t0) + \\ sd s8, 192(t0) + \\ sd s9, 200(t0) + \\ sd s10, 208(t0) + \\ sd s11, 216(t0) + \\ sd t3, 224(t0) + \\ sd t4, 232(t0) + \\ sd t5, 240(t0) + \\ sd t6, 248(t0) + \\ jal ra, 1f + \\1: + \\ sd ra, 256(t0) + \\ ld ra, 8(t0) + else + \\ sw zero, 0(t0) + \\ sw ra, 4(t0) + \\ sw sp, 8(t0) + \\ sw gp, 12(t0) + \\ sw tp, 16(t0) + \\ sw t0, 20(t0) + \\ sw t1, 24(t0) + \\ sw t2, 28(t0) + \\ sw s0, 32(t0) + \\ sw s1, 36(t0) + \\ sw a0, 40(t0) + \\ sw a1, 44(t0) + \\ sw a2, 48(t0) + \\ sw a3, 52(t0) + \\ sw a4, 56(t0) + \\ sw a5, 60(t0) + \\ sw a6, 64(t0) + \\ sw a7, 68(t0) + \\ sw s2, 72(t0) + \\ sw s3, 76(t0) + \\ sw s4, 80(t0) + \\ sw s5, 84(t0) + \\ sw s6, 88(t0) + \\ sw s7, 92(t0) + \\ sw s8, 96(t0) + \\ sw s9, 100(t0) + \\ sw s10, 104(t0) + \\ sw s11, 108(t0) + \\ sw t3, 112(t0) + \\ sw t4, 116(t0) + \\ sw t5, 120(t0) + \\ sw t6, 124(t0) + \\ jal ra, 1f + \\1: + \\ sw ra, 128(t0) + \\ lw ra, 4(t0) + : + : [gprs] "{t0}" (&ctx), + : .{ .memory = true }); + return ctx; + } + + pub fn dwarfRegisterBytes(ctx: *Riscv, register_num: u16) DwarfRegisterError![]u8 { + switch (register_num) { + 0...31 => return @ptrCast(&ctx.r[register_num]), + 32 => return @ptrCast(&ctx.pc), + + else => return error.InvalidRegister, + } + } +}; + const signal_ucontext_t = switch (native_os) { .linux => std.os.linux.ucontext_t, .emscripten => std.os.emscripten.ucontext_t, |
