diff --git a/lib/std/debug/Dwarf.zig b/lib/std/debug/Dwarf.zig index e30e3d06ac6f..991c7315492c 100644 --- a/lib/std/debug/Dwarf.zig +++ b/lib/std/debug/Dwarf.zig @@ -2023,27 +2023,3 @@ fn pcRelBase(field_ptr: usize, pc_rel_offset: i64) !usize { return std.math.add(usize, field_ptr, @as(usize, @intCast(pc_rel_offset))); } } - -pub fn supportsUnwinding(target: std.Target) bool { - return switch (target.cpu.arch) { - .x86 => switch (target.os.tag) { - .linux, .netbsd, .solaris, .illumos => true, - else => false, - }, - .x86_64 => switch (target.os.tag) { - .linux, .netbsd, .freebsd, .openbsd, .macos, .ios, .solaris, .illumos => true, - else => false, - }, - .arm => switch (target.os.tag) { - .linux => true, - else => false, - }, - .aarch64 => switch (target.os.tag) { - .linux, .netbsd, .freebsd, .macos, .ios => true, - else => false, - }, - // Unwinding is possible on other targets but this implementation does - // not support them...yet! - else => false, - }; -} diff --git a/lib/std/debug/Dwarf/abi.zig b/lib/std/debug/Dwarf/abi.zig index f153a10ba472..b2c4cb9536df 100644 --- a/lib/std/debug/Dwarf/abi.zig +++ b/lib/std/debug/Dwarf/abi.zig @@ -5,6 +5,31 @@ const mem = std.mem; const posix = std.posix; const Arch = std.Target.Cpu.Arch; +/// Tells whether unwinding for this target is supported by the Dwarf standard. +/// +/// See also `std.debug.SelfInfo.supportsUnwinding` which tells whether the Zig +/// standard library has a working implementation of unwinding for this target. +pub fn supportsUnwinding(target: std.Target) bool { + return switch (target.cpu.arch) { + .amdgcn, + .nvptx, + .nvptx64, + .spirv, + .spirv32, + .spirv64, + .spu_2, + => false, + + // Enabling this causes relocation errors such as: + // error: invalid relocation type R_RISCV_SUB32 at offset 0x20 + .riscv64, .riscv32 => false, + + // Conservative guess. Feel free to update this logic with any targets + // that are known to not support Dwarf unwinding. + else => true, + }; +} + /// Returns `null` for CPU architectures without an instruction pointer register. pub fn ipRegNum(arch: Arch) ?u8 { return switch (arch) { diff --git a/lib/std/debug/SelfInfo.zig b/lib/std/debug/SelfInfo.zig index b1679a224b9c..c27f466fb378 100644 --- a/lib/std/debug/SelfInfo.zig +++ b/lib/std/debug/SelfInfo.zig @@ -1982,7 +1982,42 @@ fn spRegNum(reg_context: Dwarf.abi.RegisterContext) u8 { } const ip_reg_num = Dwarf.abi.ipRegNum(native_arch).?; -pub const supports_unwinding = Dwarf.supportsUnwinding(builtin.target); + +/// Tells whether unwinding for the host is implemented. +pub const supports_unwinding = supportsUnwinding(builtin.target); + +comptime { + if (supports_unwinding) assert(Dwarf.abi.supportsUnwinding(builtin.target)); +} + +/// Tells whether unwinding for this target is *implemented* here in the Zig +/// standard library. +/// +/// See also `Dwarf.abi.supportsUnwinding` which tells whether Dwarf supports +/// unwinding on that target *in theory*. +pub fn supportsUnwinding(target: std.Target) bool { + return switch (target.cpu.arch) { + .x86 => switch (target.os.tag) { + .linux, .netbsd, .solaris, .illumos => true, + else => false, + }, + .x86_64 => switch (target.os.tag) { + .linux, .netbsd, .freebsd, .openbsd, .macos, .ios, .solaris, .illumos => true, + else => false, + }, + .arm => switch (target.os.tag) { + .linux => true, + else => false, + }, + .aarch64 => switch (target.os.tag) { + .linux, .netbsd, .freebsd, .macos, .ios => true, + else => false, + }, + // Unwinding is possible on other targets but this implementation does + // not support them...yet! + else => false, + }; +} fn unwindFrameMachODwarf( context: *UnwindContext,