> Date: Sat, 2 Feb 2019 17:19:07 +0100 (CET)
> From: Mark Kettenis <[email protected]>
>
> On SPARC the address of the call instruction is placed in %o7 and a
> normal function return will jump to %o7 + 8, skipping the delay slot.
> The diff below changes the low-level libunwind code to take this into
> account. This way the addresses seen by the unwinder are as expected
> and the unwinder can find the correct information in the various
> tables.
>
> ok?
Ugh, I botched that one at the last minute. And didn't notice because
I ran the regression tests without CXX=clang++ :(.
So the situation is a bit more complicated. On SPARC, DWARF2 uses
register 15 (which maps to %o7) as the return address "column". This
means that what DWARF2 calls the return address is actually what is
stored in %o7 and therefore off by two instructions. When the
unwinders processes DWARF2 "instructions" to update the register state
we must therefore set %o7 directly and not substract 8 from the passed
value.
The higher-level unwinding code needs to see the true return address
though. Luckily the DWARF2 parsing code uses a different interface,
se we can achieve this.
The DWARF2 parsing code uses setIP(), so the diff below changes that
function to remove the minus 8 I added in the previous diff. I also
changed getIP() back to what it was, even though that interface isn't
actually used in the code.
ok?
Index: lib/libunwind/src/Registers.hpp
===================================================================
RCS file: /cvs/src/lib/libunwind/src/Registers.hpp,v
retrieving revision 1.5
diff -u -p -r1.5 Registers.hpp
--- lib/libunwind/src/Registers.hpp 3 Feb 2019 12:30:02 -0000 1.5
+++ lib/libunwind/src/Registers.hpp 3 Feb 2019 13:42:15 -0000
@@ -2648,8 +2648,8 @@ public:
uint64_t getSP() const { return _registers.__o[6] + 2047; }
void setSP(uint64_t value) { _registers.__o[6] = value - 2047; }
- uint64_t getIP() const { return _registers.__o[7] + 8; }
- void setIP(uint64_t value) { _registers.__o[7] = value - 8; }
+ uint64_t getIP() const { return _registers.__o[7]; }
+ void setIP(uint64_t value) { _registers.__o[7] = value; }
uint64_t getWCookie() const { return _wcookie; }
private: