| ... | ... | @@ -280,14 +280,23 @@ pub const StackIterator = struct { |
| 280 | 280 | }; |
| 281 | 281 | } |
| 282 | 282 | |
| 283 | // On some architectures such as x86 the frame pointer is the address where |
| 284 | // the previous fp is stored, while on some other architectures such as |
| 285 | // RISC-V it points to the "top" of the frame, just above where the previous |
| 286 | // fp and the return address are stored. |
| 287 | const fp_adjust_factor = if (builtin.arch == .riscv32 or builtin.arch == .riscv64) |
| 288 | 2 * @sizeOf(usize) |
| 289 | else |
| 290 | 0; |
| 291 | |
| 283 | 292 | fn next(self: *StackIterator) ?usize { |
| 284 | | if (self.fp == 0) return null; |
| 285 | | self.fp = @intToPtr(*const usize, self.fp).*; |
| 286 | | if (self.fp == 0) return null; |
| 293 | if (self.fp < fp_adjust_factor) return null; |
| 294 | self.fp = @intToPtr(*const usize, self.fp - fp_adjust_factor).*; |
| 295 | if (self.fp < fp_adjust_factor) return null; |
| 287 | 296 | |
| 288 | 297 | if (self.first_addr) |addr| { |
| 289 | | while (self.fp != 0) : (self.fp = @intToPtr(*const usize, self.fp).*) { |
| 290 | | const return_address = @intToPtr(*const usize, self.fp + @sizeOf(usize)).*; |
| 298 | while (self.fp >= fp_adjust_factor) : (self.fp = @intToPtr(*const usize, self.fp - fp_adjust_factor).*) { |
| 299 | const return_address = @intToPtr(*const usize, self.fp - fp_adjust_factor + @sizeOf(usize)).*; |
| 291 | 300 | if (addr == return_address) { |
| 292 | 301 | self.first_addr = null; |
| 293 | 302 | return return_address; |
| ... | ... | @@ -295,7 +304,7 @@ pub const StackIterator = struct { |
| 295 | 304 | } |
| 296 | 305 | } |
| 297 | 306 | |
| 298 | | const return_address = @intToPtr(*const usize, self.fp + @sizeOf(usize)).*; |
| 307 | const return_address = @intToPtr(*const usize, self.fp - fp_adjust_factor + @sizeOf(usize)).*; |
| 299 | 308 | return return_address; |
| 300 | 309 | } |
| 301 | 310 | }; |