[PATCH] D78931: [libunwind][RISCV] Track PC separately from RA

Amanieu d'Antras via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 27 08:01:48 PDT 2020


Amanieu created this revision.
Amanieu added reviewers: libunwind, mhorne, lenary, luismarques.
Amanieu added a project: libunwind.
Herald added subscribers: libcxx-commits, llvm-commits, evandro, sameer.abuasal, s.egerton, Jim, benna, psnobl, rkruppe, rogfer01, shiva0217, kito-cheng, simoncook.
Herald added a project: LLVM.
Herald added 1 blocking reviewer(s): libunwind.

This allows unwinding to work across signal handler frames where the IP of the previous frame is not the same as the current value of the RA register. This is particularly useful for acquiring backtraces from signal handlers.

I kept the size of the context structure the same to avoid ABI breakage; the PC is stored in the previously unused slot for register 0.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D78931

Files:
  libunwind/src/Registers.hpp
  libunwind/src/UnwindRegistersRestore.S
  libunwind/src/UnwindRegistersSave.S


Index: libunwind/src/UnwindRegistersSave.S
===================================================================
--- libunwind/src/UnwindRegistersSave.S
+++ libunwind/src/UnwindRegistersSave.S
@@ -1030,7 +1030,7 @@
 #  thread_state pointer is in a0
 #
 DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
-  // x0 is zero
+  sd    x1, (8 * 0)(a0) // store ra as pc
   sd    x1, (8 * 1)(a0)
   sd    x2, (8 * 2)(a0)
   sd    x3, (8 * 3)(a0)
Index: libunwind/src/UnwindRegistersRestore.S
===================================================================
--- libunwind/src/UnwindRegistersRestore.S
+++ libunwind/src/UnwindRegistersRestore.S
@@ -1117,7 +1117,7 @@
 #endif
 
   // x0 is zero
-  ld    x1, (8 * 1)(a0)
+  ld    x1, (8 * 0)(a0) // restore pc into ra
   ld    x2, (8 * 2)(a0)
   ld    x3, (8 * 3)(a0)
   ld    x4, (8 * 4)(a0)
Index: libunwind/src/Registers.hpp
===================================================================
--- libunwind/src/Registers.hpp
+++ libunwind/src/Registers.hpp
@@ -3734,11 +3734,11 @@
 
   uint64_t  getSP() const         { return _registers[2]; }
   void      setSP(uint64_t value) { _registers[2] = value; }
-  uint64_t  getIP() const         { return _registers[1]; }
-  void      setIP(uint64_t value) { _registers[1] = value; }
+  uint64_t  getIP() const         { return _registers[0]; }
+  void      setIP(uint64_t value) { _registers[0] = value; }
 
 private:
-
+  // _registers[0] holds the pc
   uint64_t _registers[32];
   double   _floats[32];
 };
@@ -3773,7 +3773,7 @@
 
 inline uint64_t Registers_riscv::getRegister(int regNum) const {
   if (regNum == UNW_REG_IP)
-    return _registers[1];
+    return _registers[0];
   if (regNum == UNW_REG_SP)
     return _registers[2];
   if (regNum == UNW_RISCV_X0)
@@ -3785,7 +3785,7 @@
 
 inline void Registers_riscv::setRegister(int regNum, uint64_t value) {
   if (regNum == UNW_REG_IP)
-    _registers[1] = value;
+    _registers[0] = value;
   else if (regNum == UNW_REG_SP)
     _registers[2] = value;
   else if (regNum == UNW_RISCV_X0)


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D78931.260323.patch
Type: text/x-patch
Size: 2031 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200427/03adf6c6/attachment.bin>


More information about the llvm-commits mailing list