Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 6 additions & 22 deletions lib/std/debug.zig
Original file line number Diff line number Diff line change
Expand Up @@ -61,28 +61,12 @@ pub const cpu_context = @import("debug/cpu_context.zig");
/// ```
pub const SelfInfo = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "SelfInfo"))
root.debug.SelfInfo
else switch (native_os) {
.linux,
.netbsd,
.freebsd,
.dragonfly,
.openbsd,
.solaris,
.illumos,
=> @import("debug/SelfInfo/Elf.zig"),

.macos,
.ios,
.watchos,
.tvos,
.visionos,
=> @import("debug/SelfInfo/Darwin.zig"),

.uefi,
.windows,
=> @import("debug/SelfInfo/Windows.zig"),

else => void,
else switch (std.Target.ObjectFormat.default(native_os, native_arch)) {
.coff => if (native_os == .windows) @import("debug/SelfInfo/Windows.zig") else void,
.elf => @import("debug/SelfInfo/Elf.zig"),
.macho => @import("debug/SelfInfo/MachO.zig"),
.goff, .plan9, .spirv, .wasm, .xcoff => void,
.c, .hex, .raw => unreachable,
};

pub const SelfInfoError = error{
Expand Down
22 changes: 12 additions & 10 deletions lib/std/debug/Dwarf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1429,30 +1429,36 @@ pub fn compactUnwindToDwarfRegNumber(unwind_reg_number: u3) !u16 {
/// Returns `null` for CPU architectures without an instruction pointer register.
pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 {
return switch (arch) {
.aarch64, .aarch64_be => 32,
.arm, .armeb, .thumb, .thumbeb => 15,
.loongarch32, .loongarch64 => 32,
.riscv32, .riscv32be, .riscv64, .riscv64be => 32,
.x86 => 8,
.x86_64 => 16,
.arm, .armeb, .thumb, .thumbeb => 15,
.aarch64, .aarch64_be => 32,
else => null,
};
}

pub fn fpRegNum(arch: std.Target.Cpu.Arch) u16 {
return switch (arch) {
.aarch64, .aarch64_be => 29,
.arm, .armeb, .thumb, .thumbeb => 11,
.loongarch32, .loongarch64 => 22,
.riscv32, .riscv32be, .riscv64, .riscv64be => 8,
.x86 => 5,
.x86_64 => 6,
.arm, .armeb, .thumb, .thumbeb => 11,
.aarch64, .aarch64_be => 29,
else => unreachable,
};
}

pub fn spRegNum(arch: std.Target.Cpu.Arch) u16 {
return switch (arch) {
.aarch64, .aarch64_be => 31,
.arm, .armeb, .thumb, .thumbeb => 13,
.loongarch32, .loongarch64 => 3,
.riscv32, .riscv32be, .riscv64, .riscv64be => 2,
.x86 => 4,
.x86_64 => 7,
.arm, .armeb, .thumb, .thumbeb => 13,
.aarch64, .aarch64_be => 31,
else => unreachable,
};
}
Expand All @@ -1470,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,
Expand Down
13 changes: 12 additions & 1 deletion lib/std/debug/Dwarf/Unwind/VirtualMachine.zig
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,18 @@ fn evalInstructions(
.offset = cfa.offset_sf * cie.data_alignment_factor,
} },
.def_cfa_reg => |register| switch (vm.current_row.cfa) {
.none, .expression => return error.InvalidOperation,
.none => {
// According to the DWARF specification, this is not valid, because this
// instruction can only be used to replace the register if the rule is already a
// `.reg_off`. However, this is emitted in practice by GNU toolchains for some
// targets, and so by convention is interpreted as equivalent to `.def_cfa` with
// an offset of 0.
vm.current_row.cfa = .{ .reg_off = .{
.register = register,
.offset = 0,
} };
},
.expression => return error.InvalidOperation,
.reg_off => |*ro| ro.register = register,
},
.def_cfa_offset => |offset| switch (vm.current_row.cfa) {
Expand Down
35 changes: 29 additions & 6 deletions lib/std/debug/SelfInfo/Elf.zig
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,35 @@ pub const can_unwind: bool = s: {
// Notably, we are yet to support unwinding on ARM. There, unwinding is not done through
// `.eh_frame`, but instead with the `.ARM.exidx` section, which has a different format.
const archs: []const std.Target.Cpu.Arch = switch (builtin.target.os.tag) {
.linux => &.{ .x86, .x86_64, .aarch64, .aarch64_be },
.netbsd => &.{ .x86, .x86_64, .aarch64, .aarch64_be },
.freebsd => &.{ .x86_64, .aarch64, .aarch64_be },
.openbsd => &.{.x86_64},
.solaris => &.{ .x86, .x86_64 },
.illumos => &.{ .x86, .x86_64 },
.linux => &.{
.aarch64,
.aarch64_be,
.loongarch64,
.riscv32,
.riscv64,
.x86,
.x86_64,
},
.netbsd => &.{
.aarch64,
.aarch64_be,
.x86,
.x86_64,
},
.freebsd => &.{
.x86_64,
.aarch64,
},
.openbsd => &.{
.x86_64,
},
.solaris => &.{
.x86_64,
},
.illumos => &.{
.x86,
.x86_64,
},
else => unreachable,
};
for (archs) |a| {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ fn unwindFrameInner(si: *SelfInfo, gpa: Allocator, context: *UnwindContext) !usi
return context.next(gpa, &rules);
},
},
.aarch64, .aarch64_be => switch (encoding.mode.arm64) {
.aarch64 => switch (encoding.mode.arm64) {
.OLD => return error.UnsupportedDebugInfo,
.FRAMELESS => ip: {
const sp = (try dwarfRegNative(&context.cpu_state, sp_reg_num)).*;
Expand Down
2 changes: 1 addition & 1 deletion lib/std/debug/SelfInfo/Windows.zig
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ pub const UnwindContext = struct {
.R15 = ctx.gprs.get(.r15),
.Rip = ctx.gprs.get(.rip),
}),
.aarch64, .aarch64_be => .{
.aarch64 => .{
.ContextFlags = 0,
.Cpsr = 0,
.DUMMYUNIONNAME = .{ .X = ctx.x },
Expand Down
Loading