[libunwind] r332512 - [OR1K] Add a dedicated PC register to register state.

whitequark via cfe-commits cfe-commits at lists.llvm.org
Wed May 16 12:09:42 PDT 2018


Author: whitequark
Date: Wed May 16 12:09:41 2018
New Revision: 332512

URL: http://llvm.org/viewvc/llvm-project?rev=332512&view=rev
Log:
[OR1K] Add a dedicated PC register to register state.

Before this commit, R9, the link register, was used as PC register.
However, a stack frame may have R9 not set to PC on entry, either
because it uses a custom calling convention, or, more likely,
because this is a signal or exception stack frame. Using R9 as
PC register made it impossible to unwind such frames.

All other architectures similarly use a dedicated PC register.

Modified:
    libunwind/trunk/src/Registers.hpp
    libunwind/trunk/src/UnwindRegistersRestore.S
    libunwind/trunk/src/UnwindRegistersSave.S

Modified: libunwind/trunk/src/Registers.hpp
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/Registers.hpp?rev=332512&r1=332511&r2=332512&view=diff
==============================================================================
--- libunwind/trunk/src/Registers.hpp (original)
+++ libunwind/trunk/src/Registers.hpp Wed May 16 12:09:41 2018
@@ -2521,12 +2521,13 @@ public:
 
   uint64_t  getSP() const         { return _registers.__r[1]; }
   void      setSP(uint32_t value) { _registers.__r[1] = value; }
-  uint64_t  getIP() const         { return _registers.__r[9]; }
-  void      setIP(uint32_t value) { _registers.__r[9] = value; }
+  uint64_t  getIP() const         { return _registers.__pc; }
+  void      setIP(uint32_t value) { _registers.__pc = value; }
 
 private:
   struct or1k_thread_state_t {
-    unsigned int __r[32];
+    unsigned int __r[32]; // r0-r31
+    unsigned int __pc;    // Program counter
   };
 
   or1k_thread_state_t _registers;
@@ -2561,7 +2562,7 @@ inline uint32_t Registers_or1k::getRegis
 
   switch (regNum) {
   case UNW_REG_IP:
-    return _registers.__r[9];
+    return _registers.__pc;
   case UNW_REG_SP:
     return _registers.__r[1];
   }
@@ -2576,7 +2577,7 @@ inline void Registers_or1k::setRegister(
 
   switch (regNum) {
   case UNW_REG_IP:
-    _registers.__r[9] = value;
+    _registers.__pc = value;
     return;
   case UNW_REG_SP:
     _registers.__r[1] = value;

Modified: libunwind/trunk/src/UnwindRegistersRestore.S
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindRegistersRestore.S?rev=332512&r1=332511&r2=332512&view=diff
==============================================================================
--- libunwind/trunk/src/UnwindRegistersRestore.S (original)
+++ libunwind/trunk/src/UnwindRegistersRestore.S Wed May 16 12:09:41 2018
@@ -758,7 +758,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9li
 #  thread_state pointer is in r3
 #
 
-  # restore integral registerrs
+  # restore integral registers
   l.lwz     r0,  0(r3)
   l.lwz     r1,  4(r3)
   l.lwz     r2,  8(r3)
@@ -768,7 +768,7 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9li
   l.lwz     r6, 24(r3)
   l.lwz     r7, 28(r3)
   l.lwz     r8, 32(r3)
-  l.lwz     r9, 36(r3)
+  # skip r9
   l.lwz    r10, 40(r3)
   l.lwz    r11, 44(r3)
   l.lwz    r12, 48(r3)
@@ -795,6 +795,8 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9li
   # at last, restore r3
   l.lwz    r3,  12(r3)
 
+  # load new pc into ra
+  l.lwz    r9, 128(r3)
   # jump to pc
   l.jr     r9
    l.nop

Modified: libunwind/trunk/src/UnwindRegistersSave.S
URL: http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindRegistersSave.S?rev=332512&r1=332511&r2=332512&view=diff
==============================================================================
--- libunwind/trunk/src/UnwindRegistersSave.S (original)
+++ libunwind/trunk/src/UnwindRegistersSave.S Wed May 16 12:09:41 2018
@@ -938,6 +938,8 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext
   l.sw     116(r3), r29
   l.sw     120(r3), r30
   l.sw     124(r3), r31
+  # store ra to pc
+  l.sw     128(r3), r9
 #endif
 
 #endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */




More information about the cfe-commits mailing list