Module Name: src Committed By: thorpej Date: Sat Nov 20 18:19:18 UTC 2021
Modified Files: src/sys/lib/libunwind: Registers.hpp Log Message: - 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. To generate a diff of this commit: cvs rdiff -u -r1.29 -r1.30 src/sys/lib/libunwind/Registers.hpp Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/lib/libunwind/Registers.hpp diff -u src/sys/lib/libunwind/Registers.hpp:1.29 src/sys/lib/libunwind/Registers.hpp:1.30 --- src/sys/lib/libunwind/Registers.hpp:1.29 Thu Nov 18 04:20:11 2021 +++ src/sys/lib/libunwind/Registers.hpp Sat Nov 20 18:19:18 2021 @@ -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 {