Module Name: src Committed By: joerg Date: Tue Apr 15 11:44:26 UTC 2014
Modified Files: src/share/mk: bsd.own.mk src/sys/lib/libunwind: DwarfParser.hpp Registers.hpp unwind_registers.S Log Message: Add initial unwind support for SPARC/SPARC64. To generate a diff of this commit: cvs rdiff -u -r1.796 -r1.797 src/share/mk/bsd.own.mk cvs rdiff -u -r1.2 -r1.3 src/sys/lib/libunwind/DwarfParser.hpp cvs rdiff -u -r1.10 -r1.11 src/sys/lib/libunwind/Registers.hpp cvs rdiff -u -r1.8 -r1.9 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/share/mk/bsd.own.mk diff -u src/share/mk/bsd.own.mk:1.796 src/share/mk/bsd.own.mk:1.797 --- src/share/mk/bsd.own.mk:1.796 Sat Apr 5 02:22:56 2014 +++ src/share/mk/bsd.own.mk Tue Apr 15 11:44:26 2014 @@ -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.m68k= yes _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" Index: src/sys/lib/libunwind/DwarfParser.hpp diff -u src/sys/lib/libunwind/DwarfParser.hpp:1.2 src/sys/lib/libunwind/DwarfParser.hpp:1.3 --- src/sys/lib/libunwind/DwarfParser.hpp:1.2 Tue Mar 11 23:52:17 2014 +++ src/sys/lib/libunwind/DwarfParser.hpp Tue Apr 15 11:44:26 2014 @@ -481,6 +481,20 @@ CFI_Parser<A, R>::parseInstructions(A &a 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; Index: src/sys/lib/libunwind/Registers.hpp diff -u src/sys/lib/libunwind/Registers.hpp:1.10 src/sys/lib/libunwind/Registers.hpp:1.11 --- src/sys/lib/libunwind/Registers.hpp:1.10 Mon Apr 14 18:15:17 2014 +++ src/sys/lib/libunwind/Registers.hpp Tue Apr 15 11:44:26 2014 @@ -525,6 +525,134 @@ private: 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_vax NativeUnwindRegist 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 Index: src/sys/lib/libunwind/unwind_registers.S diff -u src/sys/lib/libunwind/unwind_registers.S:1.8 src/sys/lib/libunwind/unwind_registers.S:1.9 --- src/sys/lib/libunwind/unwind_registers.S:1.8 Wed Apr 2 22:34:29 2014 +++ src/sys/lib/libunwind/unwind_registers.S Tue Apr 15 11:44:26 2014 @@ -421,3 +421,171 @@ ENTRY(_ZNK7_Unwind13Registers_SH36jumpto 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] + st %o2, [%o0 + 40] + st %o3, [%o0 + 44] + st %o4, [%o0 + 48] + st %o5, [%o0 + 52] + st %o6, [%o0 + 56] + st %o7, [%o0 + 60] + st %l0, [%o0 + 64] + st %l1, [%o0 + 68] + st %l2, [%o0 + 72] + st %l3, [%o0 + 76] + st %l4, [%o0 + 80] + st %l5, [%o0 + 84] + st %l6, [%o0 + 88] + st %l7, [%o0 + 92] + st %i0, [%o0 + 96] + st %i1, [%o0 + 100] + st %i2, [%o0 + 104] + st %i3, [%o0 + 108] + st %i4, [%o0 + 112] + st %i5, [%o0 + 116] + st %i6, [%o0 + 120] + st %i7, [%o0 + 124 ] + add %o7, 8, %g1 + retl + st %g1, [%o0 + 128] +END(_ZN7_Unwind15Registers_SPARCC1Ev) + + .hidden _ZNK7_Unwind15Registers_SPARC6jumptoEv +ENTRY(_ZNK7_Unwind15Registers_SPARC6jumptoEv) + t ST_FLUSHWIN + ld [%o0 + 0], %g0 + ld [%o0 + 4], %g1 + ld [%o0 + 8], %g2 + ld [%o0 + 12], %g3 + ld [%o0 + 16], %g4 + ld [%o0 + 20], %g5 + ld [%o0 + 24], %g6 + ld [%o0 + 28], %g7 + ld [%o0 + 36], %o1 + ld [%o0 + 40], %o2 + ld [%o0 + 44], %o3 + ld [%o0 + 48], %o4 + ld [%o0 + 52], %o5 + ld [%o0 + 56], %o6 + ld [%o0 + 60], %o7 + ld [%o0 + 64], %l0 + ld [%o0 + 68], %l1 + ld [%o0 + 72], %l2 + ld [%o0 + 76], %l3 + ld [%o0 + 80], %l4 + ld [%o0 + 84], %l5 + ld [%o0 + 88], %l6 + ld [%o0 + 92], %l7 + ld [%o0 + 96], %i0 + ld [%o0 + 100], %i1 + ld [%o0 + 104], %i2 + ld [%o0 + 108], %i3 + ld [%o0 + 112], %i4 + ld [%o0 + 116], %i5 + ld [%o0 + 120], %i6 + ld [%o0 + 124], %i7 + ld [%o0 + 128], %g1 + jmpl %g1, %g0 + ld [%o0 + 32], %o0 +END(_ZNK7_Unwind15Registers_SPARC6jumptoEv) +#endif