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