diff options
| author | Alex Rønne Petersen <alex@alexrp.com> | 2025-10-03 21:19:38 +0200 |
|---|---|---|
| committer | Alex Rønne Petersen <alex@alexrp.com> | 2025-10-04 03:22:40 +0200 |
| commit | 9dbfa5b2946193e71a80805ed490d64b66994f1c (patch) | |
| tree | 4e77afa38b48f2cfca03356e5400a2bcac705bbe /lib/std/debug.zig | |
| parent | d8268fac9829965ac0ffff72fb2f96a36d04d996 (diff) | |
| download | zig-9dbfa5b2946193e71a80805ed490d64b66994f1c.tar.gz zig-9dbfa5b2946193e71a80805ed490d64b66994f1c.zip | |
std.debug: consider FP-based unwinding on hexagon and powerpc safe
The ABIs make this safe and reliable due to their backchain requirements.
Diffstat (limited to 'lib/std/debug.zig')
| -rw-r--r-- | lib/std/debug.zig | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 4203027863..4846b3ce93 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -697,7 +697,7 @@ pub fn writeCurrentStackTrace(options: StackUnwindOptions, writer: *Writer, tty_ var printed_any_frame = false; while (true) switch (it.next()) { .switch_to_fp => |unwind_error| { - if (StackIterator.fp_unwind_is_safe) continue; // no need to even warn + if (StackIterator.abi_requires_backchain or StackIterator.fp_unwind_is_safe) continue; // no need to even warn const module_name = di.getModuleName(di_gpa, unwind_error.address) catch "???"; const caption: []const u8 = switch (unwind_error.err) { error.MissingDebugInfo => "unwind info unavailable", @@ -855,10 +855,22 @@ const StackIterator = union(enum) { } } - /// On aarch64-macos, Apple mandate that the frame pointer is always used. - /// TODO: are there any other architectures with guarantees like this? + /// <https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Respect-the-purpose-of-specific-CPU-registers> const fp_unwind_is_safe = builtin.cpu.arch == .aarch64 and builtin.os.tag.isDarwin(); + /// On some architectures, we can do FP unwinding even with `-fomit-frame-pointer` due to ABI + /// requirements. Typically this is because the ABI requires a backchain regardless of whether + /// codegen actually uses a frame pointer for stack frame access. + const abi_requires_backchain = switch (builtin.cpu.arch) { + .hexagon, + .powerpc, + .powerpcle, + .powerpc64, + .powerpc64le, + => true, + else => false, + }; + /// Whether the current unwind strategy is allowed given `allow_unsafe`. fn stratOk(it: *const StackIterator, allow_unsafe: bool) bool { return switch (it.*) { @@ -867,7 +879,7 @@ const StackIterator = union(enum) { // immediately regardless of anything. But FPs could also be omitted from a different // linked object, so it's not guaranteed to be safe, unless the target specifically // requires it. - .fp => !builtin.omit_frame_pointer and (fp_unwind_is_safe or allow_unsafe), + .fp => abi_requires_backchain or (!builtin.omit_frame_pointer and (fp_unwind_is_safe or allow_unsafe)), }; } |
