> 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:

Reply via email to