Commit 6d606cc38b

Andrew Kelley <andrew@ziglang.org>
2024-08-02 21:35:49
reintroduce std.Dwarf.abi.supportsUnwinding
There are two concepts here: one for whether dwarf supports unwinding on that target, and another for whether the Zig standard library implements it yet.
1 parent 975c185
Changed files (3)
lib
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) {
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,
-    };
-}
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,