Skip to content

Commit 9dbfa5b

Browse files
committed
std.debug: consider FP-based unwinding on hexagon and powerpc safe
The ABIs make this safe and reliable due to their backchain requirements.
1 parent d8268fa commit 9dbfa5b

File tree

1 file changed

+16
-4
lines changed

1 file changed

+16
-4
lines changed

lib/std/debug.zig

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ pub fn writeCurrentStackTrace(options: StackUnwindOptions, writer: *Writer, tty_
697697
var printed_any_frame = false;
698698
while (true) switch (it.next()) {
699699
.switch_to_fp => |unwind_error| {
700-
if (StackIterator.fp_unwind_is_safe) continue; // no need to even warn
700+
if (StackIterator.abi_requires_backchain or StackIterator.fp_unwind_is_safe) continue; // no need to even warn
701701
const module_name = di.getModuleName(di_gpa, unwind_error.address) catch "???";
702702
const caption: []const u8 = switch (unwind_error.err) {
703703
error.MissingDebugInfo => "unwind info unavailable",
@@ -855,10 +855,22 @@ const StackIterator = union(enum) {
855855
}
856856
}
857857

858-
/// On aarch64-macos, Apple mandate that the frame pointer is always used.
859-
/// TODO: are there any other architectures with guarantees like this?
858+
/// <https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Respect-the-purpose-of-specific-CPU-registers>
860859
const fp_unwind_is_safe = builtin.cpu.arch == .aarch64 and builtin.os.tag.isDarwin();
861860

861+
/// On some architectures, we can do FP unwinding even with `-fomit-frame-pointer` due to ABI
862+
/// requirements. Typically this is because the ABI requires a backchain regardless of whether
863+
/// codegen actually uses a frame pointer for stack frame access.
864+
const abi_requires_backchain = switch (builtin.cpu.arch) {
865+
.hexagon,
866+
.powerpc,
867+
.powerpcle,
868+
.powerpc64,
869+
.powerpc64le,
870+
=> true,
871+
else => false,
872+
};
873+
862874
/// Whether the current unwind strategy is allowed given `allow_unsafe`.
863875
fn stratOk(it: *const StackIterator, allow_unsafe: bool) bool {
864876
return switch (it.*) {
@@ -867,7 +879,7 @@ const StackIterator = union(enum) {
867879
// immediately regardless of anything. But FPs could also be omitted from a different
868880
// linked object, so it's not guaranteed to be safe, unless the target specifically
869881
// requires it.
870-
.fp => !builtin.omit_frame_pointer and (fp_unwind_is_safe or allow_unsafe),
882+
.fp => abi_requires_backchain or (!builtin.omit_frame_pointer and (fp_unwind_is_safe or allow_unsafe)),
871883
};
872884
}
873885

0 commit comments

Comments
 (0)