Skip to content

Commit bc4da9a

Browse files
authored
Merge pull request ziglang#25437 from alexrp/std-debug
`std.debug`: LoongArch and RISC-V unwind support + some minor cleanups
2 parents 14019a9 + a4f95b1 commit bc4da9a

File tree

7 files changed

+280
-50
lines changed

7 files changed

+280
-50
lines changed

lib/std/debug.zig

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -61,28 +61,12 @@ pub const cpu_context = @import("debug/cpu_context.zig");
6161
/// ```
6262
pub const SelfInfo = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "SelfInfo"))
6363
root.debug.SelfInfo
64-
else switch (native_os) {
65-
.linux,
66-
.netbsd,
67-
.freebsd,
68-
.dragonfly,
69-
.openbsd,
70-
.solaris,
71-
.illumos,
72-
=> @import("debug/SelfInfo/Elf.zig"),
73-
74-
.macos,
75-
.ios,
76-
.watchos,
77-
.tvos,
78-
.visionos,
79-
=> @import("debug/SelfInfo/Darwin.zig"),
80-
81-
.uefi,
82-
.windows,
83-
=> @import("debug/SelfInfo/Windows.zig"),
84-
85-
else => void,
64+
else switch (std.Target.ObjectFormat.default(native_os, native_arch)) {
65+
.coff => if (native_os == .windows) @import("debug/SelfInfo/Windows.zig") else void,
66+
.elf => @import("debug/SelfInfo/Elf.zig"),
67+
.macho => @import("debug/SelfInfo/MachO.zig"),
68+
.goff, .plan9, .spirv, .wasm, .xcoff => void,
69+
.c, .hex, .raw => unreachable,
8670
};
8771

8872
pub const SelfInfoError = error{

lib/std/debug/Dwarf.zig

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,30 +1429,36 @@ pub fn compactUnwindToDwarfRegNumber(unwind_reg_number: u3) !u16 {
14291429
/// Returns `null` for CPU architectures without an instruction pointer register.
14301430
pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 {
14311431
return switch (arch) {
1432+
.aarch64, .aarch64_be => 32,
1433+
.arm, .armeb, .thumb, .thumbeb => 15,
1434+
.loongarch32, .loongarch64 => 32,
1435+
.riscv32, .riscv32be, .riscv64, .riscv64be => 32,
14321436
.x86 => 8,
14331437
.x86_64 => 16,
1434-
.arm, .armeb, .thumb, .thumbeb => 15,
1435-
.aarch64, .aarch64_be => 32,
14361438
else => null,
14371439
};
14381440
}
14391441

14401442
pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 {
14411443
return switch (arch) {
1444+
.aarch64, .aarch64_be => 29,
1445+
.arm, .armeb, .thumb, .thumbeb => 11,
1446+
.loongarch32, .loongarch64 => 22,
1447+
.riscv32, .riscv32be, .riscv64, .riscv64be => 8,
14421448
.x86 => 5,
14431449
.x86_64 => 6,
1444-
.arm, .armeb, .thumb, .thumbeb => 11,
1445-
.aarch64, .aarch64_be => 29,
14461450
else => unreachable,
14471451
};
14481452
}
14491453

14501454
pub fn spRegNum(arch: std.Target.Cpu.Arch) u16 {
14511455
return switch (arch) {
1456+
.aarch64, .aarch64_be => 31,
1457+
.arm, .armeb, .thumb, .thumbeb => 13,
1458+
.loongarch32, .loongarch64 => 3,
1459+
.riscv32, .riscv32be, .riscv64, .riscv64be => 2,
14521460
.x86 => 4,
14531461
.x86_64 => 7,
1454-
.arm, .armeb, .thumb, .thumbeb => 13,
1455-
.aarch64, .aarch64_be => 31,
14561462
else => unreachable,
14571463
};
14581464
}
@@ -1470,10 +1476,6 @@ pub fn supportsUnwinding(target: *const std.Target) bool {
14701476
.spirv64,
14711477
=> false,
14721478

1473-
// Enabling this causes relocation errors such as:
1474-
// error: invalid relocation type R_RISCV_SUB32 at offset 0x20
1475-
.riscv64, .riscv64be, .riscv32, .riscv32be => false,
1476-
14771479
// Conservative guess. Feel free to update this logic with any targets
14781480
// that are known to not support Dwarf unwinding.
14791481
else => true,

lib/std/debug/Dwarf/Unwind/VirtualMachine.zig

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,18 @@ fn evalInstructions(
256256
.offset = cfa.offset_sf * cie.data_alignment_factor,
257257
} },
258258
.def_cfa_reg => |register| switch (vm.current_row.cfa) {
259-
.none, .expression => return error.InvalidOperation,
259+
.none => {
260+
// According to the DWARF specification, this is not valid, because this
261+
// instruction can only be used to replace the register if the rule is already a
262+
// `.reg_off`. However, this is emitted in practice by GNU toolchains for some
263+
// targets, and so by convention is interpreted as equivalent to `.def_cfa` with
264+
// an offset of 0.
265+
vm.current_row.cfa = .{ .reg_off = .{
266+
.register = register,
267+
.offset = 0,
268+
} };
269+
},
270+
.expression => return error.InvalidOperation,
260271
.reg_off => |*ro| ro.register = register,
261272
},
262273
.def_cfa_offset => |offset| switch (vm.current_row.cfa) {

lib/std/debug/SelfInfo/Elf.zig

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,35 @@ pub const can_unwind: bool = s: {
8484
// Notably, we are yet to support unwinding on ARM. There, unwinding is not done through
8585
// `.eh_frame`, but instead with the `.ARM.exidx` section, which has a different format.
8686
const archs: []const std.Target.Cpu.Arch = switch (builtin.target.os.tag) {
87-
.linux => &.{ .x86, .x86_64, .aarch64, .aarch64_be },
88-
.netbsd => &.{ .x86, .x86_64, .aarch64, .aarch64_be },
89-
.freebsd => &.{ .x86_64, .aarch64, .aarch64_be },
90-
.openbsd => &.{.x86_64},
91-
.solaris => &.{ .x86, .x86_64 },
92-
.illumos => &.{ .x86, .x86_64 },
87+
.linux => &.{
88+
.aarch64,
89+
.aarch64_be,
90+
.loongarch64,
91+
.riscv32,
92+
.riscv64,
93+
.x86,
94+
.x86_64,
95+
},
96+
.netbsd => &.{
97+
.aarch64,
98+
.aarch64_be,
99+
.x86,
100+
.x86_64,
101+
},
102+
.freebsd => &.{
103+
.x86_64,
104+
.aarch64,
105+
},
106+
.openbsd => &.{
107+
.x86_64,
108+
},
109+
.solaris => &.{
110+
.x86_64,
111+
},
112+
.illumos => &.{
113+
.x86,
114+
.x86_64,
115+
},
93116
else => unreachable,
94117
};
95118
for (archs) |a| {

lib/std/debug/SelfInfo/Darwin.zig renamed to lib/std/debug/SelfInfo/MachO.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ fn unwindFrameInner(si: *SelfInfo, gpa: Allocator, context: *UnwindContext) !usi
371371
return context.next(gpa, &rules);
372372
},
373373
},
374-
.aarch64, .aarch64_be => switch (encoding.mode.arm64) {
374+
.aarch64 => switch (encoding.mode.arm64) {
375375
.OLD => return error.UnsupportedDebugInfo,
376376
.FRAMELESS => ip: {
377377
const sp = (try dwarfRegNative(&context.cpu_state, sp_reg_num)).*;

lib/std/debug/SelfInfo/Windows.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ pub const UnwindContext = struct {
8888
.R15 = ctx.gprs.get(.r15),
8989
.Rip = ctx.gprs.get(.rip),
9090
}),
91-
.aarch64, .aarch64_be => .{
91+
.aarch64 => .{
9292
.ContextFlags = 0,
9393
.Cpsr = 0,
9494
.DUMMYUNIONNAME = .{ .X = ctx.x },

0 commit comments

Comments
 (0)