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__) */ _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits