| author | |
| committer | |
| log | 55fa349ad946aaa4e2ff5a5dc2a3f0d6bce64282 |
| tree | fbd8365132d929851ec418d048a90aaafd1d575e |
| parent | b5f8fb85e64022ed1ee59ff70753577839ad41b6 |
| signature |
Import LLVM's D32450/D116857 patch to enable unwinding support on
SPARCv9 systems.9 files changed, 367 insertions(+), 10 deletions(-)
lib/libunwind/include/__libunwind_config.h+7| ... | @@ -23,6 +23,7 @@ | ... | @@ -23,6 +23,7 @@ |
| 23 | #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K 32 | 23 | #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K 32 |
| 24 | #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS 65 | 24 | #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS 65 |
| 25 | #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC 31 | 25 | #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC 31 |
| 26 | #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64 31 | ||
| 26 | #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON 34 | 27 | #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON 34 |
| 27 | #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV 64 | 28 | #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV 64 |
| 28 | #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE 143 | 29 | #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE 143 |
| ... | @@ -125,6 +126,11 @@ | ... | @@ -125,6 +126,11 @@ |
| 125 | # error "Unsupported MIPS ABI and/or environment" | 126 | # error "Unsupported MIPS ABI and/or environment" |
| 126 | # endif | 127 | # endif |
| 127 | # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS | 128 | # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS |
| 129 | # elif defined(__sparc__) && defined(__arch64__) | ||
| 130 | # define _LIBUNWIND_TARGET_SPARC64 1 | ||
| 131 | # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64 | ||
| 132 | # define _LIBUNWIND_CONTEXT_SIZE 33 | ||
| 133 | # define _LIBUNWIND_CURSOR_SIZE 45 | ||
| 128 | # elif defined(__sparc__) | 134 | # elif defined(__sparc__) |
| 129 | #define _LIBUNWIND_TARGET_SPARC 1 | 135 | #define _LIBUNWIND_TARGET_SPARC 1 |
| 130 | #define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC | 136 | #define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC |
| ... | @@ -165,6 +171,7 @@ | ... | @@ -165,6 +171,7 @@ |
| 165 | # define _LIBUNWIND_TARGET_MIPS_O32 1 | 171 | # define _LIBUNWIND_TARGET_MIPS_O32 1 |
| 166 | # define _LIBUNWIND_TARGET_MIPS_NEWABI 1 | 172 | # define _LIBUNWIND_TARGET_MIPS_NEWABI 1 |
| 167 | # define _LIBUNWIND_TARGET_SPARC 1 | 173 | # define _LIBUNWIND_TARGET_SPARC 1 |
| 174 | # define _LIBUNWIND_TARGET_SPARC64 1 | ||
| 168 | # define _LIBUNWIND_TARGET_HEXAGON 1 | 175 | # define _LIBUNWIND_TARGET_HEXAGON 1 |
| 169 | # define _LIBUNWIND_TARGET_RISCV 1 | 176 | # define _LIBUNWIND_TARGET_RISCV 1 |
| 170 | # define _LIBUNWIND_TARGET_VE 1 | 177 | # define _LIBUNWIND_TARGET_VE 1 |
lib/libunwind/src/DwarfInstructions.hpp+21-1| ... | @@ -67,7 +67,7 @@ private: | ... | @@ -67,7 +67,7 @@ private: |
| 67 | return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister) + | 67 | return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister) + |
| 68 | prolog.cfaRegisterOffset); | 68 | prolog.cfaRegisterOffset); |
| 69 | if (prolog.cfaExpression != 0) | 69 | if (prolog.cfaExpression != 0) |
| 70 | return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace, | 70 | return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace, |
| 71 | registers, 0); | 71 | registers, 0); |
| 72 | assert(0 && "getCFA(): unknown location"); | 72 | assert(0 && "getCFA(): unknown location"); |
| 73 | __builtin_unreachable(); | 73 | __builtin_unreachable(); |
| ... | @@ -75,6 +75,14 @@ private: | ... | @@ -75,6 +75,14 @@ private: |
| 75 | }; | 75 | }; |
| 76 | 76 | ||
| 77 | 77 | ||
| 78 | template <typename R> | ||
| 79 | auto getSparcWCookie(const R &r, int) -> decltype(r.getWCookie()) { | ||
| 80 | return r.getWCookie(); | ||
| 81 | } | ||
| 82 | template <typename R> uint64_t getSparcWCookie(const R &, long) { | ||
| 83 | return 0; | ||
| 84 | } | ||
| 85 | |||
| 78 | template <typename A, typename R> | 86 | template <typename A, typename R> |
| 79 | typename A::pint_t DwarfInstructions<A, R>::getSavedRegister( | 87 | typename A::pint_t DwarfInstructions<A, R>::getSavedRegister( |
| 80 | A &addressSpace, const R &registers, pint_t cfa, | 88 | A &addressSpace, const R &registers, pint_t cfa, |
| ... | @@ -83,6 +91,10 @@ typename A::pint_t DwarfInstructions<A, R>::getSavedRegister( | ... | @@ -83,6 +91,10 @@ typename A::pint_t DwarfInstructions<A, R>::getSavedRegister( |
| 83 | case CFI_Parser<A>::kRegisterInCFA: | 91 | case CFI_Parser<A>::kRegisterInCFA: |
| 84 | return (pint_t)addressSpace.getRegister(cfa + (pint_t)savedReg.value); | 92 | return (pint_t)addressSpace.getRegister(cfa + (pint_t)savedReg.value); |
| 85 | 93 | ||
| 94 | case CFI_Parser<A>::kRegisterInCFADecrypt: // sparc64 specific | ||
| 95 | return addressSpace.getP(cfa + (pint_t)savedReg.value) ^ | ||
| 96 | getSparcWCookie(registers, 0); | ||
| 97 | |||
| 86 | case CFI_Parser<A>::kRegisterAtExpression: | 98 | case CFI_Parser<A>::kRegisterAtExpression: |
| 87 | return (pint_t)addressSpace.getRegister(evaluateExpression( | 99 | return (pint_t)addressSpace.getRegister(evaluateExpression( |
| 88 | (pint_t)savedReg.value, addressSpace, registers, cfa)); | 100 | (pint_t)savedReg.value, addressSpace, registers, cfa)); |
| ... | @@ -121,6 +133,7 @@ double DwarfInstructions<A, R>::getSavedFloatRegister( | ... | @@ -121,6 +133,7 @@ double DwarfInstructions<A, R>::getSavedFloatRegister( |
| 121 | case CFI_Parser<A>::kRegisterUndefined: | 133 | case CFI_Parser<A>::kRegisterUndefined: |
| 122 | case CFI_Parser<A>::kRegisterOffsetFromCFA: | 134 | case CFI_Parser<A>::kRegisterOffsetFromCFA: |
| 123 | case CFI_Parser<A>::kRegisterInRegister: | 135 | case CFI_Parser<A>::kRegisterInRegister: |
| 136 | case CFI_Parser<A>::kRegisterInCFADecrypt: | ||
| 124 | // FIX ME | 137 | // FIX ME |
| 125 | break; | 138 | break; |
| 126 | } | 139 | } |
| ... | @@ -145,6 +158,7 @@ v128 DwarfInstructions<A, R>::getSavedVectorRegister( | ... | @@ -145,6 +158,7 @@ v128 DwarfInstructions<A, R>::getSavedVectorRegister( |
| 145 | case CFI_Parser<A>::kRegisterUndefined: | 158 | case CFI_Parser<A>::kRegisterUndefined: |
| 146 | case CFI_Parser<A>::kRegisterOffsetFromCFA: | 159 | case CFI_Parser<A>::kRegisterOffsetFromCFA: |
| 147 | case CFI_Parser<A>::kRegisterInRegister: | 160 | case CFI_Parser<A>::kRegisterInRegister: |
| 161 | case CFI_Parser<A>::kRegisterInCFADecrypt: | ||
| 148 | // FIX ME | 162 | // FIX ME |
| 149 | break; | 163 | break; |
| 150 | } | 164 | } |
| ... | @@ -249,6 +263,12 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc, | ... | @@ -249,6 +263,12 @@ int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc, |
| 249 | } | 263 | } |
| 250 | #endif | 264 | #endif |
| 251 | 265 | ||
| 266 | #if defined(_LIBUNWIND_TARGET_SPARC64) | ||
| 267 | // Skip call site instruction and delay slot | ||
| 268 | if (R::getArch() == REGISTERS_SPARC64) | ||
| 269 | returnAddress += 8; | ||
| 270 | #endif | ||
| 271 | |||
| 252 | #if defined(_LIBUNWIND_TARGET_PPC64) | 272 | #if defined(_LIBUNWIND_TARGET_PPC64) |
| 253 | #define PPC64_ELFV1_R2_LOAD_INST_ENCODING 0xe8410028u // ld r2,40(r1) | 273 | #define PPC64_ELFV1_R2_LOAD_INST_ENCODING 0xe8410028u // ld r2,40(r1) |
| 254 | #define PPC64_ELFV1_R2_OFFSET 40 | 274 | #define PPC64_ELFV1_R2_OFFSET 40 |
lib/libunwind/src/DwarfParser.hpp+24-1| ... | @@ -71,6 +71,7 @@ public: | ... | @@ -71,6 +71,7 @@ public: |
| 71 | kRegisterUnused, | 71 | kRegisterUnused, |
| 72 | kRegisterUndefined, | 72 | kRegisterUndefined, |
| 73 | kRegisterInCFA, | 73 | kRegisterInCFA, |
| 74 | kRegisterInCFADecrypt, // sparc64 specific | ||
| 74 | kRegisterOffsetFromCFA, | 75 | kRegisterOffsetFromCFA, |
| 75 | kRegisterInRegister, | 76 | kRegisterInRegister, |
| 76 | kRegisterAtExpression, | 77 | kRegisterAtExpression, |
| ... | @@ -723,7 +724,8 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace, | ... | @@ -723,7 +724,8 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace, |
| 723 | "DW_CFA_GNU_negative_offset_extended(%" PRId64 ")\n", offset); | 724 | "DW_CFA_GNU_negative_offset_extended(%" PRId64 ")\n", offset); |
| 724 | break; | 725 | break; |
| 725 | 726 | ||
| 726 | #if defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_SPARC) | 727 | #if defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_SPARC) || \ |
| 728 | defined(_LIBUNWIND_TARGET_SPARC64) | ||
| 727 | // The same constant is used to represent different instructions on | 729 | // The same constant is used to represent different instructions on |
| 728 | // AArch64 (negate_ra_state) and SPARC (window_save). | 730 | // AArch64 (negate_ra_state) and SPARC (window_save). |
| 729 | static_assert(DW_CFA_AARCH64_negate_ra_state == DW_CFA_GNU_window_save, | 731 | static_assert(DW_CFA_AARCH64_negate_ra_state == DW_CFA_GNU_window_save, |
| ... | @@ -757,8 +759,29 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace, | ... | @@ -757,8 +759,29 @@ bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace, |
| 757 | } | 759 | } |
| 758 | break; | 760 | break; |
| 759 | #endif | 761 | #endif |
| 762 | |||
| 763 | #if defined(_LIBUNWIND_TARGET_SPARC64) | ||
| 764 | // case DW_CFA_GNU_window_save: | ||
| 765 | case REGISTERS_SPARC64: | ||
| 766 | // Don't save %o0-%o7 on sparc64. | ||
| 767 | // https://reviews.llvm.org/D32450#736405 | ||
| 768 | |||
| 769 | for (reg = UNW_SPARC_L0; reg <= UNW_SPARC_I7; reg++) { | ||
| 770 | if (reg == UNW_SPARC_I7) | ||
| 771 | results->setRegister( | ||
| 772 | reg, kRegisterInCFADecrypt, | ||
| 773 | ((int64_t)reg - UNW_SPARC_L0) * sizeof(pint_t), initialState); | ||
| 774 | else | ||
| 775 | results->setRegister( | ||
| 776 | reg, kRegisterInCFA, | ||
| 777 | ((int64_t)reg - UNW_SPARC_L0) * sizeof(pint_t), initialState); | ||
| 778 | } | ||
| 779 | _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_window_save\n"); | ||
| 780 | break; | ||
| 781 | #endif | ||
| 760 | } | 782 | } |
| 761 | break; | 783 | break; |
| 784 | |||
| 762 | #else | 785 | #else |
| 763 | (void)arch; | 786 | (void)arch; |
| 764 | #endif | 787 | #endif |
lib/libunwind/src/Registers.hpp+187| ... | @@ -34,6 +34,7 @@ enum { | ... | @@ -34,6 +34,7 @@ enum { |
| 34 | REGISTERS_MIPS_O32, | 34 | REGISTERS_MIPS_O32, |
| 35 | REGISTERS_MIPS_NEWABI, | 35 | REGISTERS_MIPS_NEWABI, |
| 36 | REGISTERS_SPARC, | 36 | REGISTERS_SPARC, |
| 37 | REGISTERS_SPARC64, | ||
| 37 | REGISTERS_HEXAGON, | 38 | REGISTERS_HEXAGON, |
| 38 | REGISTERS_RISCV, | 39 | REGISTERS_RISCV, |
| 39 | REGISTERS_VE, | 40 | REGISTERS_VE, |
| ... | @@ -3546,6 +3547,192 @@ inline const char *Registers_sparc::getRegisterName(int regNum) { | ... | @@ -3546,6 +3547,192 @@ inline const char *Registers_sparc::getRegisterName(int regNum) { |
| 3546 | } | 3547 | } |
| 3547 | #endif // _LIBUNWIND_TARGET_SPARC | 3548 | #endif // _LIBUNWIND_TARGET_SPARC |
| 3548 | 3549 | ||
| 3550 | |||
| 3551 | #if defined(_LIBUNWIND_TARGET_SPARC64) | ||
| 3552 | /// Registers_sparc64 holds the register state of a thread in a 64-bit | ||
| 3553 | /// sparc process. | ||
| 3554 | class _LIBUNWIND_HIDDEN Registers_sparc64 { | ||
| 3555 | public: | ||
| 3556 | Registers_sparc64() = default; | ||
| 3557 | Registers_sparc64(const void *registers); | ||
| 3558 | |||
| 3559 | bool validRegister(int num) const; | ||
| 3560 | uint64_t getRegister(int num) const; | ||
| 3561 | void setRegister(int num, uint64_t value); | ||
| 3562 | bool validFloatRegister(int num) const; | ||
| 3563 | double getFloatRegister(int num) const; | ||
| 3564 | void setFloatRegister(int num, double value); | ||
| 3565 | bool validVectorRegister(int num) const; | ||
| 3566 | v128 getVectorRegister(int num) const; | ||
| 3567 | void setVectorRegister(int num, v128 value); | ||
| 3568 | const char *getRegisterName(int num); | ||
| 3569 | void jumpto(); | ||
| 3570 | static int lastDwarfRegNum() { | ||
| 3571 | return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC64; | ||
| 3572 | } | ||
| 3573 | static int getArch() { return REGISTERS_SPARC64; } | ||
| 3574 | |||
| 3575 | uint64_t getSP() const { return _registers.__regs[UNW_SPARC_O6] + 2047; } | ||
| 3576 | void setSP(uint64_t value) { _registers.__regs[UNW_SPARC_O6] = value - 2047; } | ||
| 3577 | uint64_t getIP() const { return _registers.__regs[UNW_SPARC_O7]; } | ||
| 3578 | void setIP(uint64_t value) { _registers.__regs[UNW_SPARC_O7] = value; } | ||
| 3579 | uint64_t getWCookie() const { return _wcookie; } | ||
| 3580 | |||
| 3581 | private: | ||
| 3582 | struct sparc64_thread_state_t { | ||
| 3583 | uint64_t __regs[32]; | ||
| 3584 | }; | ||
| 3585 | |||
| 3586 | sparc64_thread_state_t _registers{}; | ||
| 3587 | uint64_t _wcookie = 0; | ||
| 3588 | }; | ||
| 3589 | |||
| 3590 | inline Registers_sparc64::Registers_sparc64(const void *registers) { | ||
| 3591 | static_assert((check_fit<Registers_sparc64, unw_context_t>::does_fit), | ||
| 3592 | "sparc64 registers do not fit into unw_context_t"); | ||
| 3593 | memcpy(&_registers, registers, sizeof(_registers)); | ||
| 3594 | memcpy(&_wcookie, | ||
| 3595 | static_cast<const uint8_t *>(registers) + sizeof(_registers), | ||
| 3596 | sizeof(_wcookie)); | ||
| 3597 | } | ||
| 3598 | |||
| 3599 | inline bool Registers_sparc64::validRegister(int regNum) const { | ||
| 3600 | if (regNum == UNW_REG_IP) | ||
| 3601 | return true; | ||
| 3602 | if (regNum == UNW_REG_SP) | ||
| 3603 | return true; | ||
| 3604 | if (regNum < 0) | ||
| 3605 | return false; | ||
| 3606 | if (regNum <= UNW_SPARC_I7) | ||
| 3607 | return true; | ||
| 3608 | return false; | ||
| 3609 | } | ||
| 3610 | |||
| 3611 | inline uint64_t Registers_sparc64::getRegister(int regNum) const { | ||
| 3612 | if (regNum >= UNW_SPARC_G0 && regNum <= UNW_SPARC_I7) | ||
| 3613 | return _registers.__regs[regNum]; | ||
| 3614 | |||
| 3615 | switch (regNum) { | ||
| 3616 | case UNW_REG_IP: | ||
| 3617 | return _registers.__regs[UNW_SPARC_O7]; | ||
| 3618 | case UNW_REG_SP: | ||
| 3619 | return _registers.__regs[UNW_SPARC_O6] + 2047; | ||
| 3620 | } | ||
| 3621 | _LIBUNWIND_ABORT("unsupported sparc64 register"); | ||
| 3622 | } | ||
| 3623 | |||
| 3624 | inline void Registers_sparc64::setRegister(int regNum, uint64_t value) { | ||
| 3625 | if (regNum >= UNW_SPARC_G0 && regNum <= UNW_SPARC_I7) { | ||
| 3626 | _registers.__regs[regNum] = value; | ||
| 3627 | return; | ||
| 3628 | } | ||
| 3629 | |||
| 3630 | switch (regNum) { | ||
| 3631 | case UNW_REG_IP: | ||
| 3632 | _registers.__regs[UNW_SPARC_O7] = value; | ||
| 3633 | return; | ||
| 3634 | case UNW_REG_SP: | ||
| 3635 | _registers.__regs[UNW_SPARC_O6] = value - 2047; | ||
| 3636 | return; | ||
| 3637 | } | ||
| 3638 | _LIBUNWIND_ABORT("unsupported sparc64 register"); | ||
| 3639 | } | ||
| 3640 | |||
| 3641 | inline bool Registers_sparc64::validFloatRegister(int) const { return false; } | ||
| 3642 | |||
| 3643 | inline double Registers_sparc64::getFloatRegister(int) const { | ||
| 3644 | _LIBUNWIND_ABORT("no sparc64 float registers"); | ||
| 3645 | } | ||
| 3646 | |||
| 3647 | inline void Registers_sparc64::setFloatRegister(int, double) { | ||
| 3648 | _LIBUNWIND_ABORT("no sparc64 float registers"); | ||
| 3649 | } | ||
| 3650 | |||
| 3651 | inline bool Registers_sparc64::validVectorRegister(int) const { return false; } | ||
| 3652 | |||
| 3653 | inline v128 Registers_sparc64::getVectorRegister(int) const { | ||
| 3654 | _LIBUNWIND_ABORT("no sparc64 vector registers"); | ||
| 3655 | } | ||
| 3656 | |||
| 3657 | inline void Registers_sparc64::setVectorRegister(int, v128) { | ||
| 3658 | _LIBUNWIND_ABORT("no sparc64 vector registers"); | ||
| 3659 | } | ||
| 3660 | |||
| 3661 | inline const char *Registers_sparc64::getRegisterName(int regNum) { | ||
| 3662 | switch (regNum) { | ||
| 3663 | case UNW_REG_IP: | ||
| 3664 | return "pc"; | ||
| 3665 | case UNW_SPARC_G0: | ||
| 3666 | return "g0"; | ||
| 3667 | case UNW_SPARC_G1: | ||
| 3668 | return "g1"; | ||
| 3669 | case UNW_SPARC_G2: | ||
| 3670 | return "g2"; | ||
| 3671 | case UNW_SPARC_G3: | ||
| 3672 | return "g3"; | ||
| 3673 | case UNW_SPARC_G4: | ||
| 3674 | return "g4"; | ||
| 3675 | case UNW_SPARC_G5: | ||
| 3676 | return "g5"; | ||
| 3677 | case UNW_SPARC_G6: | ||
| 3678 | return "g6"; | ||
| 3679 | case UNW_SPARC_G7: | ||
| 3680 | return "g7"; | ||
| 3681 | case UNW_SPARC_O0: | ||
| 3682 | return "o0"; | ||
| 3683 | case UNW_SPARC_O1: | ||
| 3684 | return "o1"; | ||
| 3685 | case UNW_SPARC_O2: | ||
| 3686 | return "o2"; | ||
| 3687 | case UNW_SPARC_O3: | ||
| 3688 | return "o3"; | ||
| 3689 | case UNW_SPARC_O4: | ||
| 3690 | return "o4"; | ||
| 3691 | case UNW_SPARC_O5: | ||
| 3692 | return "o5"; | ||
| 3693 | case UNW_REG_SP: | ||
| 3694 | case UNW_SPARC_O6: | ||
| 3695 | return "o6"; | ||
| 3696 | case UNW_SPARC_O7: | ||
| 3697 | return "o7"; | ||
| 3698 | case UNW_SPARC_L0: | ||
| 3699 | return "l0"; | ||
| 3700 | case UNW_SPARC_L1: | ||
| 3701 | return "l1"; | ||
| 3702 | case UNW_SPARC_L2: | ||
| 3703 | return "l2"; | ||
| 3704 | case UNW_SPARC_L3: | ||
| 3705 | return "l3"; | ||
| 3706 | case UNW_SPARC_L4: | ||
| 3707 | return "l4"; | ||
| 3708 | case UNW_SPARC_L5: | ||
| 3709 | return "l5"; | ||
| 3710 | case UNW_SPARC_L6: | ||
| 3711 | return "l6"; | ||
| 3712 | case UNW_SPARC_L7: | ||
| 3713 | return "l7"; | ||
| 3714 | case UNW_SPARC_I0: | ||
| 3715 | return "i0"; | ||
| 3716 | case UNW_SPARC_I1: | ||
| 3717 | return "i1"; | ||
| 3718 | case UNW_SPARC_I2: | ||
| 3719 | return "i2"; | ||
| 3720 | case UNW_SPARC_I3: | ||
| 3721 | return "i3"; | ||
| 3722 | case UNW_SPARC_I4: | ||
| 3723 | return "i4"; | ||
| 3724 | case UNW_SPARC_I5: | ||
| 3725 | return "i5"; | ||
| 3726 | case UNW_SPARC_I6: | ||
| 3727 | return "i6"; | ||
| 3728 | case UNW_SPARC_I7: | ||
| 3729 | return "i7"; | ||
| 3730 | default: | ||
| 3731 | return "unknown register"; | ||
| 3732 | } | ||
| 3733 | } | ||
| 3734 | #endif // _LIBUNWIND_TARGET_SPARC64 | ||
| 3735 | |||
| 3549 | #if defined(_LIBUNWIND_TARGET_HEXAGON) | 3736 | #if defined(_LIBUNWIND_TARGET_HEXAGON) |
| 3550 | /// Registers_hexagon holds the register state of a thread in a Hexagon QDSP6 | 3737 | /// Registers_hexagon holds the register state of a thread in a Hexagon QDSP6 |
| 3551 | /// process. | 3738 | /// process. |
lib/libunwind/src/UnwindCursor.hpp+16| ... | @@ -1020,6 +1020,10 @@ private: | ... | @@ -1020,6 +1020,10 @@ private: |
| 1020 | int stepWithCompactEncoding(Registers_sparc &) { return UNW_EINVAL; } | 1020 | int stepWithCompactEncoding(Registers_sparc &) { return UNW_EINVAL; } |
| 1021 | #endif | 1021 | #endif |
| 1022 | 1022 | ||
| 1023 | #if defined(_LIBUNWIND_TARGET_SPARC64) | ||
| 1024 | int stepWithCompactEncoding(Registers_sparc64 &) { return UNW_EINVAL; } | ||
| 1025 | #endif | ||
| 1026 | |||
| 1023 | #if defined (_LIBUNWIND_TARGET_RISCV) | 1027 | #if defined (_LIBUNWIND_TARGET_RISCV) |
| 1024 | int stepWithCompactEncoding(Registers_riscv &) { | 1028 | int stepWithCompactEncoding(Registers_riscv &) { |
| 1025 | return UNW_EINVAL; | 1029 | return UNW_EINVAL; |
| ... | @@ -1092,6 +1096,12 @@ private: | ... | @@ -1092,6 +1096,12 @@ private: |
| 1092 | bool compactSaysUseDwarf(Registers_sparc &, uint32_t *) const { return true; } | 1096 | bool compactSaysUseDwarf(Registers_sparc &, uint32_t *) const { return true; } |
| 1093 | #endif | 1097 | #endif |
| 1094 | 1098 | ||
| 1099 | #if defined(_LIBUNWIND_TARGET_SPARC64) | ||
| 1100 | bool compactSaysUseDwarf(Registers_sparc64 &, uint32_t *) const { | ||
| 1101 | return true; | ||
| 1102 | } | ||
| 1103 | #endif | ||
| 1104 | |||
| 1095 | #if defined (_LIBUNWIND_TARGET_RISCV) | 1105 | #if defined (_LIBUNWIND_TARGET_RISCV) |
| 1096 | bool compactSaysUseDwarf(Registers_riscv &, uint32_t *) const { | 1106 | bool compactSaysUseDwarf(Registers_riscv &, uint32_t *) const { |
| 1097 | return true; | 1107 | return true; |
| ... | @@ -1170,6 +1180,12 @@ private: | ... | @@ -1170,6 +1180,12 @@ private: |
| 1170 | compact_unwind_encoding_t dwarfEncoding(Registers_sparc &) const { return 0; } | 1180 | compact_unwind_encoding_t dwarfEncoding(Registers_sparc &) const { return 0; } |
| 1171 | #endif | 1181 | #endif |
| 1172 | 1182 | ||
| 1183 | #if defined(_LIBUNWIND_TARGET_SPARC64) | ||
| 1184 | compact_unwind_encoding_t dwarfEncoding(Registers_sparc64 &) const { | ||
| 1185 | return 0; | ||
| 1186 | } | ||
| 1187 | #endif | ||
| 1188 | |||
| 1173 | #if defined (_LIBUNWIND_TARGET_RISCV) | 1189 | #if defined (_LIBUNWIND_TARGET_RISCV) |
| 1174 | compact_unwind_encoding_t dwarfEncoding(Registers_riscv &) const { | 1190 | compact_unwind_encoding_t dwarfEncoding(Registers_riscv &) const { |
| 1175 | return 0; | 1191 | return 0; |
lib/libunwind/src/UnwindRegistersRestore.S+47| ... | @@ -1050,6 +1050,53 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) | ... | @@ -1050,6 +1050,53 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) |
| 1050 | ld $4, (8 * 4)($4) | 1050 | ld $4, (8 * 4)($4) |
| 1051 | .set pop | 1051 | .set pop |
| 1052 | 1052 | ||
| 1053 | #elif defined(__sparc__) && defined(__arch64__) | ||
| 1054 | |||
| 1055 | DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind17Registers_sparc646jumptoEv) | ||
| 1056 | // | ||
| 1057 | // void libunwind::Registers_sparc64::jumpto() | ||
| 1058 | // | ||
| 1059 | // On entry: | ||
| 1060 | // thread_state pointer is in %o0 | ||
| 1061 | // | ||
| 1062 | .register %g2, #scratch | ||
| 1063 | .register %g3, #scratch | ||
| 1064 | .register %g6, #scratch | ||
| 1065 | .register %g7, #scratch | ||
| 1066 | flushw | ||
| 1067 | ldx [%o0 + 0x08], %g1 | ||
| 1068 | ldx [%o0 + 0x10], %g2 | ||
| 1069 | ldx [%o0 + 0x18], %g3 | ||
| 1070 | ldx [%o0 + 0x20], %g4 | ||
| 1071 | ldx [%o0 + 0x28], %g5 | ||
| 1072 | ldx [%o0 + 0x30], %g6 | ||
| 1073 | ldx [%o0 + 0x38], %g7 | ||
| 1074 | ldx [%o0 + 0x48], %o1 | ||
| 1075 | ldx [%o0 + 0x50], %o2 | ||
| 1076 | ldx [%o0 + 0x58], %o3 | ||
| 1077 | ldx [%o0 + 0x60], %o4 | ||
| 1078 | ldx [%o0 + 0x68], %o5 | ||
| 1079 | ldx [%o0 + 0x70], %o6 | ||
| 1080 | ldx [%o0 + 0x78], %o7 | ||
| 1081 | ldx [%o0 + 0x80], %l0 | ||
| 1082 | ldx [%o0 + 0x88], %l1 | ||
| 1083 | ldx [%o0 + 0x90], %l2 | ||
| 1084 | ldx [%o0 + 0x98], %l3 | ||
| 1085 | ldx [%o0 + 0xa0], %l4 | ||
| 1086 | ldx [%o0 + 0xa8], %l5 | ||
| 1087 | ldx [%o0 + 0xb0], %l6 | ||
| 1088 | ldx [%o0 + 0xb8], %l7 | ||
| 1089 | ldx [%o0 + 0xc0], %i0 | ||
| 1090 | ldx [%o0 + 0xc8], %i1 | ||
| 1091 | ldx [%o0 + 0xd0], %i2 | ||
| 1092 | ldx [%o0 + 0xd8], %i3 | ||
| 1093 | ldx [%o0 + 0xe0], %i4 | ||
| 1094 | ldx [%o0 + 0xe8], %i5 | ||
| 1095 | ldx [%o0 + 0xf0], %i6 | ||
| 1096 | ldx [%o0 + 0xf8], %i7 | ||
| 1097 | jmp %o7 | ||
| 1098 | ldx [%o0 + 0x40], %o0 | ||
| 1099 | |||
| 1053 | #elif defined(__sparc__) | 1100 | #elif defined(__sparc__) |
| 1054 | 1101 | ||
| 1055 | // | 1102 | // |
lib/libunwind/src/UnwindRegistersSave.S+59-1| ... | @@ -766,7 +766,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) | ... | @@ -766,7 +766,7 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) |
| 766 | @ | 766 | @ |
| 767 | @ On entry: | 767 | @ On entry: |
| 768 | @ thread_state pointer is in r0 | 768 | @ thread_state pointer is in r0 |
| 769 | @ | 769 | @ |
| 770 | @ Per EHABI #4.7 this only saves the core integer registers. | 770 | @ Per EHABI #4.7 this only saves the core integer registers. |
| 771 | @ EHABI #7.4.5 notes that in general all VRS registers should be restored | 771 | @ EHABI #7.4.5 notes that in general all VRS registers should be restored |
| 772 | @ however this is very hard to do for VFP registers because it is unknown | 772 | @ however this is very hard to do for VFP registers because it is unknown |
| ... | @@ -996,6 +996,64 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) | ... | @@ -996,6 +996,64 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) |
| 996 | 996 | ||
| 997 | jumpr r31 | 997 | jumpr r31 |
| 998 | 998 | ||
| 999 | #elif defined(__sparc__) && defined(__arch64__) | ||
| 1000 | |||
| 1001 | # | ||
| 1002 | # extern int __unw_getcontext(unw_context_t* thread_state) | ||
| 1003 | # | ||
| 1004 | # On entry: | ||
| 1005 | # thread_state pointer is in %o0 | ||
| 1006 | # | ||
| 1007 | DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) | ||
| 1008 | .register %g2, #scratch | ||
| 1009 | .register %g3, #scratch | ||
| 1010 | .register %g6, #scratch | ||
| 1011 | .register %g7, #scratch | ||
| 1012 | stx %g1, [%o0 + 0x08] | ||
| 1013 | stx %g2, [%o0 + 0x10] | ||
| 1014 | stx %g3, [%o0 + 0x18] | ||
| 1015 | stx %g4, [%o0 + 0x20] | ||
| 1016 | stx %g5, [%o0 + 0x28] | ||
| 1017 | stx %g6, [%o0 + 0x30] | ||
| 1018 | stx %g7, [%o0 + 0x38] | ||
| 1019 | stx %o0, [%o0 + 0x40] | ||
| 1020 | stx %o1, [%o0 + 0x48] | ||
| 1021 | stx %o2, [%o0 + 0x50] | ||
| 1022 | stx %o3, [%o0 + 0x58] | ||
| 1023 | stx %o4, [%o0 + 0x60] | ||
| 1024 | stx %o5, [%o0 + 0x68] | ||
| 1025 | stx %o6, [%o0 + 0x70] | ||
| 1026 | stx %o7, [%o0 + 0x78] | ||
| 1027 | stx %l0, [%o0 + 0x80] | ||
| 1028 | stx %l1, [%o0 + 0x88] | ||
| 1029 | stx %l2, [%o0 + 0x90] | ||
| 1030 | stx %l3, [%o0 + 0x98] | ||
| 1031 | stx %l4, [%o0 + 0xa0] | ||
| 1032 | stx %l5, [%o0 + 0xa8] | ||
| 1033 | stx %l6, [%o0 + 0xb0] | ||
| 1034 | stx %l7, [%o0 + 0xb8] | ||
| 1035 | stx %i0, [%o0 + 0xc0] | ||
| 1036 | stx %i1, [%o0 + 0xc8] | ||
| 1037 | stx %i2, [%o0 + 0xd0] | ||
| 1038 | stx %i3, [%o0 + 0xd8] | ||
| 1039 | stx %i4, [%o0 + 0xe0] | ||
| 1040 | stx %i5, [%o0 + 0xe8] | ||
| 1041 | stx %i6, [%o0 + 0xf0] | ||
| 1042 | stx %i7, [%o0 + 0xf8] | ||
| 1043 | |||
| 1044 | # save StackGhost cookie | ||
| 1045 | mov %i7, %g4 | ||
| 1046 | save %sp, -176, %sp | ||
| 1047 | # register window flush necessary even without StackGhost | ||
| 1048 | flushw | ||
| 1049 | restore | ||
| 1050 | ldx [%sp + 2047 + 0x78], %g5 | ||
| 1051 | xor %g4, %g5, %g4 | ||
| 1052 | stx %g4, [%o0 + 0x100] | ||
| 1053 | retl | ||
| 1054 | # return UNW_ESUCCESS | ||
| 1055 | clr %o0 | ||
| 1056 | |||
| 999 | #elif defined(__sparc__) | 1057 | #elif defined(__sparc__) |
| 1000 | 1058 | ||
| 1001 | # | 1059 | # |
lib/libunwind/src/config.h+4-7| ... | @@ -109,13 +109,10 @@ | ... | @@ -109,13 +109,10 @@ |
| 109 | #define _LIBUNWIND_SUPPORT_FRAME_APIS | 109 | #define _LIBUNWIND_SUPPORT_FRAME_APIS |
| 110 | #endif | 110 | #endif |
| 111 | 111 | ||
| 112 | #if defined(__i386__) || defined(__x86_64__) || \ | 112 | #if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || \ |
| 113 | defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) || \ | 113 | (!defined(__APPLE__) && defined(__arm__)) || defined(__aarch64__) || \ |
| 114 | (!defined(__APPLE__) && defined(__arm__)) || \ | 114 | defined(__mips__) || defined(__riscv) || defined(__hexagon__) || \ |
| 115 | defined(__aarch64__) || \ | 115 | defined(__sparc__) |
| 116 | defined(__mips__) || \ | ||
| 117 | defined(__riscv) || \ | ||
| 118 | defined(__hexagon__) | ||
| 119 | #if !defined(_LIBUNWIND_BUILD_SJLJ_APIS) | 116 | #if !defined(_LIBUNWIND_BUILD_SJLJ_APIS) |
| 120 | #define _LIBUNWIND_BUILD_ZERO_COST_APIS | 117 | #define _LIBUNWIND_BUILD_ZERO_COST_APIS |
| 121 | #endif | 118 | #endif |
lib/libunwind/src/libunwind.cpp+2| ... | @@ -69,6 +69,8 @@ _LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor, | ... | @@ -69,6 +69,8 @@ _LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor, |
| 69 | # define REGISTER_KIND Registers_mips_newabi | 69 | # define REGISTER_KIND Registers_mips_newabi |
| 70 | #elif defined(__mips__) | 70 | #elif defined(__mips__) |
| 71 | # warning The MIPS architecture is not supported with this ABI and environment! | 71 | # warning The MIPS architecture is not supported with this ABI and environment! |
| 72 | #elif defined(__sparc__) && defined(__arch64__) | ||
| 73 | # define REGISTER_KIND Registers_sparc64 | ||
| 72 | #elif defined(__sparc__) | 74 | #elif defined(__sparc__) |
| 73 | # define REGISTER_KIND Registers_sparc | 75 | # define REGISTER_KIND Registers_sparc |
| 74 | #elif defined(__riscv) | 76 | #elif defined(__riscv) |