aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorKoakuma <koachan@protonmail.com>2021-02-04 20:51:41 +0700
committerKoakuma <koachan@protonmail.com>2021-02-04 20:51:41 +0700
commit1eb2e4801448aca29471bf6f7582135ddafb15fe (patch)
tree63bdd5c92fe67a3bbac31cf01d2c9df66904ede1 /lib
parent2d447b57ccfd1a65383bf7ca9f882c7e69e94f2b (diff)
downloadzig-1eb2e4801448aca29471bf6f7582135ddafb15fe.tar.gz
zig-1eb2e4801448aca29471bf6f7582135ddafb15fe.zip
std.debug.StackIterator: account for SPARC %fp quirk
On SPARC, previous %fp is saved with a 14 slots offset from current %fp+bias. Also account for the bias constant at the new_fp calculation.
Diffstat (limited to 'lib')
-rw-r--r--lib/std/debug.zig12
1 files changed, 11 insertions, 1 deletions
diff --git a/lib/std/debug.zig b/lib/std/debug.zig
index a434fe0e8b..b887899c7a 100644
--- a/lib/std/debug.zig
+++ b/lib/std/debug.zig
@@ -366,8 +366,18 @@ pub const StackIterator = struct {
// area, on pretty much every other architecture it points to the stack
// slot where the previous frame pointer is saved.
2 * @sizeOf(usize)
+ else if (builtin.arch.isSPARC())
+ // On SPARC the previous frame pointer is stored at 14 slots past %fp+BIAS.
+ 14 * @sizeOf(usize)
else
0;
+
+ const fp_bias = if (builtin.arch.isSPARC())
+ // On SPARC frame pointers are biased by a constant.
+ 2047
+ else
+ 0;
+
// Positive offset of the saved PC wrt the frame pointer.
const pc_offset = if (builtin.arch == .powerpc64le)
2 * @sizeOf(usize)
@@ -394,7 +404,7 @@ pub const StackIterator = struct {
if (fp == 0 or !mem.isAligned(fp, @alignOf(usize)))
return null;
- const new_fp = @intToPtr(*const usize, fp).*;
+ const new_fp = math.add(usize, @intToPtr(*const usize, fp).*, fp_bias) catch return null;
// Sanity check: the stack grows down thus all the parent frames must be
// be at addresses that are greater (or equal) than the previous one.