From b751d63a784064aebf980951f93dbfbc6afd26ea Mon Sep 17 00:00:00 2001 From: thorpej Date: Sat, 20 Nov 2021 18:19:18 +0000 Subject: - 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. --- sys/lib/libunwind/Registers.hpp | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'sys/lib') 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 { -- cgit