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 {

Reply via email to