Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Add initial unwind support for SPARC/SPARC64.



details:   https://anonhg.NetBSD.org/src/rev/4ea9a59416f9
branches:  trunk
changeset: 328723:4ea9a59416f9
user:      joerg <joerg%NetBSD.org@localhost>
date:      Tue Apr 15 11:44:26 2014 +0000

description:
Add initial unwind support for SPARC/SPARC64.

diffstat:

 share/mk/bsd.own.mk                  |    4 +-
 sys/lib/libunwind/DwarfParser.hpp    |   14 ++
 sys/lib/libunwind/Registers.hpp      |  132 +++++++++++++++++++++++++++
 sys/lib/libunwind/unwind_registers.S |  168 +++++++++++++++++++++++++++++++++++
 4 files changed, 317 insertions(+), 1 deletions(-)

diffs (truncated from 366 to 300 lines):

diff -r 9be195b75ecf -r 4ea9a59416f9 share/mk/bsd.own.mk
--- a/share/mk/bsd.own.mk       Tue Apr 15 10:39:44 2014 +0000
+++ b/share/mk/bsd.own.mk       Tue Apr 15 11:44:26 2014 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: bsd.own.mk,v 1.796 2014/04/05 02:22:56 christos Exp $
+#      $NetBSD: bsd.own.mk,v 1.797 2014/04/15 11:44:26 joerg Exp $
 
 # This needs to be before bsd.init.mk
 .if defined(BSD_MK_COMPAT_FILE)
@@ -104,6 +104,8 @@
 _LIBC_UNWIND_SUPPORT.powerpc=  yes
 _LIBC_UNWIND_SUPPORT.sh3el=    yes
 _LIBC_UNWIND_SUPPORT.sh3eb=    yes
+_LIBC_UNWIND_SUPPORT.sparc=    yes
+_LIBC_UNWIND_SUPPORT.sparc64=  yes
 _LIBC_UNWIND_SUPPORT.vax=      yes
 _LIBC_UNWIND_SUPPORT.x86_64=   yes
 .if ${MKLLVM:Uno} == "yes" && ${_LIBC_UNWIND_SUPPORT.${MACHINE_ARCH}:Uno} == "yes"
diff -r 9be195b75ecf -r 4ea9a59416f9 sys/lib/libunwind/DwarfParser.hpp
--- a/sys/lib/libunwind/DwarfParser.hpp Tue Apr 15 10:39:44 2014 +0000
+++ b/sys/lib/libunwind/DwarfParser.hpp Tue Apr 15 11:44:26 2014 +0000
@@ -481,6 +481,20 @@
       length = addressSpace.getULEB128(p, instructionsEnd);
       p += length;
       break;
+    case DW_CFA_GNU_window_save:
+#if defined(__sparc__)
+      for (reg = 8; reg < 16; ++reg) {
+        results->savedRegisters[reg].location = kRegisterInRegister;
+        results->savedRegisters[reg].value = reg + 16;
+      }
+      for (reg = 16; reg < 32; ++reg) {
+        results->savedRegisters[reg].location = kRegisterInCFA;
+        results->savedRegisters[reg].value = (reg - 16) * sizeof(typename R::reg_t);
+      }
+      break;
+#else
+      return false;
+#endif
     case DW_CFA_GNU_args_size:
       offset = addressSpace.getULEB128(p, instructionsEnd);
       results->spExtraArgSize = offset;
diff -r 9be195b75ecf -r 4ea9a59416f9 sys/lib/libunwind/Registers.hpp
--- a/sys/lib/libunwind/Registers.hpp   Tue Apr 15 10:39:44 2014 +0000
+++ b/sys/lib/libunwind/Registers.hpp   Tue Apr 15 11:44:26 2014 +0000
@@ -525,6 +525,134 @@
   uint32_t reg[REGNO_SH3_PR + 1];
 };
 
+enum {
+  DWARF_SPARC64_R0 = 0,
+  DWARF_SPARC64_R31 = 31,
+  DWARF_SPARC64_PC = 32,
+
+  REGNO_SPARC64_R0 = 0,
+  REGNO_SPARC64_R14 = 14,
+  REGNO_SPARC64_R15 = 15,
+  REGNO_SPARC64_R31 = 31,
+  REGNO_SPARC64_PC = 32,
+};
+
+class Registers_SPARC64 {
+public:
+  enum {
+    LAST_REGISTER = REGNO_SPARC64_PC,
+    LAST_RESTORE_REG = REGNO_SPARC64_PC,
+    RETURN_REG = REGNO_SPARC64_R15,
+    RETURN_OFFSET = 8,
+  };
+  typedef uint64_t reg_t;
+
+  __dso_hidden Registers_SPARC64();
+
+  static int dwarf2regno(int num) {
+    if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31)
+      return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0);
+    if (num == DWARF_SPARC64_PC)
+      return REGNO_SPARC64_PC;
+    return LAST_REGISTER + 1;
+  }
+
+  bool validRegister(int num) const {
+    return num >= 0 && num <= REGNO_SPARC64_PC;
+  }
+
+  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_SPARC64_PC]; }
+
+  void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
+
+  uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
+
+  void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
+
+  bool validFloatVectorRegister(int num) const { return false; }
+
+  void copyFloatVectorRegister(int num, uint64_t addr_) {}
+
+  __dso_hidden void jumpto() const __dead;
+
+private:
+  uint64_t reg[REGNO_SPARC64_PC + 1];
+};
+
+enum {
+  DWARF_SPARC_R0 = 0,
+  DWARF_SPARC_R31 = 31,
+  DWARF_SPARC_PC = 32,
+
+  REGNO_SPARC_R0 = 0,
+  REGNO_SPARC_R14 = 14,
+  REGNO_SPARC_R15 = 15,
+  REGNO_SPARC_R31 = 31,
+  REGNO_SPARC_PC = 32,
+};
+
+class Registers_SPARC {
+public:
+  enum {
+    LAST_REGISTER = REGNO_SPARC_PC,
+    LAST_RESTORE_REG = REGNO_SPARC_PC,
+    RETURN_REG = REGNO_SPARC_R15,
+    RETURN_OFFSET = 8,
+  };
+  typedef uint32_t reg_t;
+
+  __dso_hidden Registers_SPARC();
+
+  static int dwarf2regno(int num) {
+    if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31)
+      return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0);
+    if (num == DWARF_SPARC_PC)
+      return REGNO_SPARC_PC;
+    return LAST_REGISTER + 1;
+  }
+
+  bool validRegister(int num) const {
+    return num >= 0 && num <= REGNO_SPARC_PC;
+  }
+
+  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_SPARC_PC]; }
+
+  void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
+
+  uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
+
+  void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
+
+  bool validFloatVectorRegister(int num) const { return false; }
+
+  void copyFloatVectorRegister(int num, uint64_t addr_) {}
+
+  __dso_hidden void jumpto() const __dead;
+
+private:
+  uint32_t reg[REGNO_SPARC_PC + 1];
+};
+
 #if __i386__
 typedef Registers_x86 NativeUnwindRegisters;
 #elif __x86_64__
@@ -539,6 +667,10 @@
 typedef Registers_M68K NativeUnwindRegisters;
 #elif __sh3__
 typedef Registers_SH3 NativeUnwindRegisters;
+#elif __sparc64__
+typedef Registers_SPARC64 NativeUnwindRegisters;
+#elif __sparc__
+typedef Registers_SPARC NativeUnwindRegisters;
 #endif
 } // namespace _Unwind
 
diff -r 9be195b75ecf -r 4ea9a59416f9 sys/lib/libunwind/unwind_registers.S
--- a/sys/lib/libunwind/unwind_registers.S      Tue Apr 15 10:39:44 2014 +0000
+++ b/sys/lib/libunwind/unwind_registers.S      Tue Apr 15 11:44:26 2014 +0000
@@ -421,3 +421,171 @@
          nop
 SET_ENTRY_SIZE(_ZNK7_Unwind13Registers_SH36jumptoEv)
 #endif
+
+#if defined(__sparc64__)
+#include <machine/trap.h>
+       .register %g2, #ignore
+       .register %g3, #ignore
+       .register %g6, #ignore
+       .register %g7, #ignore
+       .hidden _ZN7_Unwind17Registers_SPARC64C1Ev
+ENTRY(_ZN7_Unwind17Registers_SPARC64C1Ev)
+       t       ST_FLUSHWIN
+       stx     %g0, [%o0 + 0]
+       stx     %g1, [%o0 + 8]
+       stx     %g2, [%o0 + 16]
+       stx     %g3, [%o0 + 24]
+       stx     %g4, [%o0 + 32]
+       stx     %g5, [%o0 + 40]
+       stx     %g6, [%o0 + 48]
+       stx     %g7, [%o0 + 56]
+       stx     %o0, [%o0 + 64]
+       stx     %o1, [%o0 + 72]
+       stx     %o2, [%o0 + 80]
+       stx     %o3, [%o0 + 88]
+       stx     %o4, [%o0 + 96]
+       stx     %o5, [%o0 + 104]
+       stx     %o6, [%o0 + 112]
+       stx     %o7, [%o0 + 120]
+       stx     %l0, [%o0 + 128]
+       stx     %l1, [%o0 + 136]
+       stx     %l2, [%o0 + 144]
+       stx     %l3, [%o0 + 152]
+       stx     %l4, [%o0 + 160]
+       stx     %l5, [%o0 + 168]
+       stx     %l6, [%o0 + 176]
+       stx     %l7, [%o0 + 184]
+       stx     %i0, [%o0 + 192]
+       stx     %i1, [%o0 + 200]
+       stx     %i2, [%o0 + 208]
+       stx     %i3, [%o0 + 216]
+       stx     %i4, [%o0 + 224]
+       stx     %i5, [%o0 + 232]
+       stx     %i6, [%o0 + 240]
+       stx     %i7, [%o0 + 248]
+       add     %o7, 8, %g1
+       retl
+        stx    %g1, [%o0 + 256]
+END(_ZN7_Unwind17Registers_SPARC64C1Ev)
+
+       .hidden _ZNK7_Unwind17Registers_SPARC646jumptoEv
+ENTRY(_ZNK7_Unwind17Registers_SPARC646jumptoEv)
+       t       ST_FLUSHWIN
+       ldx     [%o0 + 0], %g0
+       ldx     [%o0 + 8], %g1
+       ldx     [%o0 + 16], %g2
+       ldx     [%o0 + 24], %g3
+       ldx     [%o0 + 32], %g4
+       ldx     [%o0 + 40], %g5
+       ldx     [%o0 + 48], %g6
+       ldx     [%o0 + 56], %g7
+       ldx     [%o0 + 72], %o1
+       ldx     [%o0 + 80], %o2
+       ldx     [%o0 + 88], %o3
+       ldx     [%o0 + 96], %o4
+       ldx     [%o0 + 104], %o5
+       ldx     [%o0 + 112], %g1
+       sub     %g1, 2047, %o6
+       ldx     [%o0 + 120], %o7
+       ldx     [%o0 + 128], %l0
+       ldx     [%o0 + 136], %l1
+       ldx     [%o0 + 144], %l2
+       ldx     [%o0 + 152], %l3
+       ldx     [%o0 + 160], %l4
+       ldx     [%o0 + 168], %l5
+       ldx     [%o0 + 176], %l6
+       ldx     [%o0 + 184], %l7
+       ldx     [%o0 + 192], %i0
+       ldx     [%o0 + 200], %i1
+       ldx     [%o0 + 208], %i2
+       ldx     [%o0 + 216], %i3
+       ldx     [%o0 + 224], %i4
+       ldx     [%o0 + 232], %i5
+       ldx     [%o0 + 240], %i6
+       ldx     [%o0 + 248], %i7
+       ldx     [%o0 + 256], %g1
+       jmpl    %g1, %g0
+         ldx   [%o0 + 64], %o0
+END(_ZNK7_Unwind17Registers_SPARC646jumptoEv)
+#elif defined(__sparc__)
+#include <machine/trap.h>
+
+       .hidden _ZN7_Unwind15Registers_SPARCC1Ev
+ENTRY(_ZN7_Unwind15Registers_SPARCC1Ev)
+       t       ST_FLUSHWIN
+       st      %g0, [%o0 + 0]
+       st      %g1, [%o0 + 4]
+       st      %g2, [%o0 + 8]
+       st      %g3, [%o0 + 12]
+       st      %g4, [%o0 + 16]
+       st      %g5, [%o0 + 20]
+       st      %g6, [%o0 + 24]
+       st      %g7, [%o0 + 28]
+       st      %o0, [%o0 + 32]
+       st      %o1, [%o0 + 36]



Home | Main Index | Thread Index | Old Index