diff options
| author | thorpej <thorpej@NetBSD.org> | 2021-11-20 18:19:18 +0000 |
|---|---|---|
| committer | thorpej <thorpej@NetBSD.org> | 2021-11-20 18:19:18 +0000 |
| commit | b751d63a784064aebf980951f93dbfbc6afd26ea (patch) | |
| tree | 2abcf1f76787c6c789b9ca48f75726ec7f13aeb3 /sys/lib | |
| parent | ccb7d22f1d158b498cb7ce015f8609853d64c6b4 (diff) | |
- Teach the LLVM-derived unwinder about the DWARF pseudo-registers defined
by GCC for MIPS64 to hold the MDHI and MDLO registers, as well as the return
address where the signal trampoline will resume.
- In the MIPS64 validFloatVectorRegister(), compare against the internal
register numbers, not the DWARF register numbers.
Diffstat (limited to 'sys/lib')
| -rw-r--r-- | sys/lib/libunwind/Registers.hpp | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/sys/lib/libunwind/Registers.hpp b/sys/lib/libunwind/Registers.hpp index fd9790d1d08..764920e8fec 100644 --- a/sys/lib/libunwind/Registers.hpp +++ b/sys/lib/libunwind/Registers.hpp @@ -1026,20 +1026,29 @@ enum { DWARF_MIPS64_R31 = 31, DWARF_MIPS64_F0 = 32, DWARF_MIPS64_F31 = 63, + // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and + // signal handler return address. + DWARF_MIPS64_MDHI = 64, + DWARF_MIPS64_MDLO = 65, + DWARF_MIPS64_SIGRETURN = 66, REGNO_MIPS64_PC = 0, REGNO_MIPS64_R1 = 0, REGNO_MIPS64_R29 = 29, REGNO_MIPS64_R31 = 31, REGNO_MIPS64_F0 = 33, - REGNO_MIPS64_F31 = 64 + REGNO_MIPS64_F31 = 64, + // these live in other_reg[] + REGNO_MIPS64_MDHI = 65, + REGNO_MIPS64_MDLO = 66, + REGNO_MIPS64_SIGRETURN = 67 }; class Registers_MIPS64 { public: enum { - LAST_REGISTER = REGNO_MIPS64_F31, - LAST_RESTORE_REG = REGNO_MIPS64_F31, + LAST_REGISTER = REGNO_MIPS_SIGRETURN, + LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN, RETURN_OFFSET = 0, RETURN_MASK = 0, }; @@ -1051,21 +1060,29 @@ public: return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1); if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31) return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0); + if (num >= DWARF_MIPS64_MDHI && num <= DWARF_MIPS64_SIGRETURN) + return REGNO_MIPS64_MDHI + (num - DWARF_MIPS64_MDHI); return LAST_REGISTER + 1; } bool validRegister(int num) const { - return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31; + return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31 || + (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN); } uint64_t getRegister(int num) const { assert(validRegister(num)); + if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN) + return other_reg[num - REGNO_MIPS64_MDHI]; return reg[num]; } void setRegister(int num, uint64_t value) { assert(validRegister(num)); - reg[num] = value; + if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN) + other_reg[num - REGNO_MIPS64_MDHI] = value; + else + reg[num] = value; } uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; } @@ -1077,7 +1094,7 @@ public: void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; } bool validFloatVectorRegister(int num) const { - return num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31; + return num >= REGNO_MIPS64_F0 && num <= REGNO_MIPS64_F31; } void copyFloatVectorRegister(int num, uint64_t addr_) { @@ -1091,6 +1108,7 @@ public: private: uint64_t reg[REGNO_MIPS64_R31 + 1]; uint64_t fpreg[32]; + uint64_t other_reg[3]; }; enum { |
