std: Fix backtraces on sparcv9

Flush all the register windows to stack before starting the stack walk,
we may otherwise try to read garbage and crash and burn.

Add a few comptime annotations to debloat some functions.
This commit is contained in:
LemonBoy
2021-04-25 19:10:11 +02:00
parent 37b05742ff
commit 54db36cd88

View File

@@ -336,6 +336,13 @@ pub const StackIterator = struct {
fp: usize,
pub fn init(first_address: ?usize, fp: ?usize) StackIterator {
if (builtin.arch == .sparcv9) {
// Flush all the register windows on stack.
asm volatile (
\\ flushw
::: "memory");
}
return StackIterator{
.first_address = first_address,
.fp = fp orelse @frameAddress(),
@@ -343,18 +350,18 @@ pub const StackIterator = struct {
}
// Offset of the saved BP wrt the frame pointer.
const fp_offset = if (builtin.arch.isRISCV())
const fp_offset = if (comptime builtin.arch.isRISCV())
// On RISC-V the frame pointer points to the top of the saved register
// 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())
else if (comptime 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())
const fp_bias = if (comptime builtin.arch.isSPARC())
// On SPARC frame pointers are biased by a constant.
2047
else
@@ -380,7 +387,7 @@ pub const StackIterator = struct {
}
fn next_internal(self: *StackIterator) ?usize {
const fp = if (builtin.arch.isSPARC())
const fp = if (comptime builtin.arch.isSPARC())
// On SPARC the offset is positive. (!)
math.add(usize, self.fp, fp_offset) catch return null
else