Module Name:    src
Committed By:   matt
Date:           Wed Jan 29 06:59:53 UTC 2014

Modified Files:
        src/sys/lib/libunwind: Registers.hpp libunwind.cxx unwind_registers.S

Log Message:
Add support for non-EABI (DWARF) ARM exception handling.


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/lib/libunwind/Registers.hpp \
    src/sys/lib/libunwind/libunwind.cxx \
    src/sys/lib/libunwind/unwind_registers.S

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.1 src/sys/lib/libunwind/Registers.hpp:1.2
--- src/sys/lib/libunwind/Registers.hpp:1.1	Mon Oct 14 01:14:57 2013
+++ src/sys/lib/libunwind/Registers.hpp	Wed Jan 29 06:59:53 2014
@@ -229,6 +229,78 @@ private:
   vecreg_t vecreg[64];
 };
 
+enum {
+  DWARF_ARM32_R0 = 0,
+  DWARF_ARM32_R15 = 15,
+  DWARF_ARM32_SPSR = 128,
+  DWARF_ARM32_D0 = 256,		// VFP-v3/Neon
+  DWARF_ARM32_D31 = 287,
+  REGNO_ARM32_R0 = 0,
+  REGNO_ARM32_SP = 13,
+  REGNO_ARM32_R15 = 15,
+  REGNO_ARM32_SPSR = 16,
+  REGNO_ARM32_D0 = 0,
+  REGNO_ARM32_D31 = 31,
+};
+
+class Registers_arm32 {
+public:
+  enum {
+    LAST_RESTORE_REG = REGNO_ARM32_SPSR,
+    IP_PSEUDO_REG = REGNO_ARM32_SPSR,
+    LAST_REGISTER = REGNO_ARM32_D31,
+  };
+
+  __dso_hidden Registers_arm32();
+
+  static int dwarf2regno(int num) {
+    if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
+      return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
+    if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
+      return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
+    if (num == DWARF_ARM32_SPSR)
+      return REGNO_ARM32_SPSR;
+    return LAST_REGISTER + 1;
+  }
+
+  bool validRegister(int num) const {
+    return num >= 0 && num <= LAST_RESTORE_REG;
+  }
+
+  uint64_t getRegister(int num) const {
+    assert(validRegister(num));
+    return reg[num];
+  }
+
+  void setRegister(int num, uint64_t value) {
+    assert(validRegister(num));
+    reg[num] = value;
+  }
+
+  uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
+
+  void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
+
+  uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
+
+  void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
+
+  bool validFloatVectorRegister(int num) const {
+    return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_D31);
+  }
+
+  void copyFloatVectorRegister(int num, uint64_t addr_) {
+    const void *addr = reinterpret_cast<const void *>(addr_);
+    memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
+  }
+
+  __dso_hidden void jumpto() const __dead;
+
+private:
+  uint32_t reg[REGNO_ARM32_SPSR + 1];
+  uint64_t fpreg[32];
+};
+
 } // namespace _Unwind
 
 #endif // __REGISTERS_HPP__
Index: src/sys/lib/libunwind/libunwind.cxx
diff -u src/sys/lib/libunwind/libunwind.cxx:1.1 src/sys/lib/libunwind/libunwind.cxx:1.2
--- src/sys/lib/libunwind/libunwind.cxx:1.1	Mon Oct 14 01:14:57 2013
+++ src/sys/lib/libunwind/libunwind.cxx	Wed Jan 29 06:59:53 2014
@@ -23,6 +23,8 @@ typedef Registers_x86 ThisUnwindRegister
 typedef Registers_x86_64 ThisUnwindRegisters;
 #elif __powerpc__
 typedef Registers_ppc32 ThisUnwindRegisters;
+#elif __arm__ && !defined(__ARM_EABI__)
+typedef Registers_arm32 ThisUnwindRegisters;
 #else
 #error Unsupported architecture
 #endif
Index: src/sys/lib/libunwind/unwind_registers.S
diff -u src/sys/lib/libunwind/unwind_registers.S:1.1 src/sys/lib/libunwind/unwind_registers.S:1.2
--- src/sys/lib/libunwind/unwind_registers.S:1.1	Mon Oct 14 01:14:57 2013
+++ src/sys/lib/libunwind/unwind_registers.S	Wed Jan 29 06:59:53 2014
@@ -210,3 +210,23 @@ ENTRY(_ZNK7_Unwind15Registers_ppc326jump
 	lwz		%r3,12(%r3)   /* do r3 last */
 	bctr
 #endif
+
+#if defined(__arm__) && !defined(__ARM_EABI__)
+	.hidden _ZN7_Unwind15Registers_arm32C1Ev
+ENTRY(_ZN7_Unwind15Registers_arm32C1Ev)
+	stmia	r0, {r0-r14}
+
+	str	lr, [r0, #60]	/* PC */
+	mrs	r1, cpsr
+	str	r1, [r0, #64]	/* CPSR */
+
+	RET
+END(_ZN7_Unwind15Registers_arm32C1Ev)
+
+	.hidden _ZNK7_Unwind15Registers_arm326jumptoEv
+ENTRY(_ZNK7_Unwind15Registers_arm326jumptoEv)
+	ldr	r1, [r0, #64]
+	msr	cpsr_sxc, r1
+	ldmia	r0, {r0-r15}
+END(_ZNK7_Unwind15Registers_arm326jumptoEv)
+#endif

Reply via email to