diff --git a/libunwind/include/__libunwind_config.h b/libunwind/include/__libunwind_config.h --- a/libunwind/include/__libunwind_config.h +++ b/libunwind/include/__libunwind_config.h @@ -30,6 +30,7 @@ #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV 64 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE 143 #define _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X 83 +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH 64 #if defined(_LIBUNWIND_IS_NATIVE_ONLY) # if defined(__linux__) @@ -166,6 +167,16 @@ # define _LIBUNWIND_CONTEXT_SIZE 34 # define _LIBUNWIND_CURSOR_SIZE 46 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X +#elif defined(__loongarch__) +#define _LIBUNWIND_TARGET_LOONGARCH 1 +#if __loongarch_grlen == 64 +#define _LIBUNWIND_CONTEXT_SIZE 65 +#define _LIBUNWIND_CURSOR_SIZE 77 +#else +#error "Unsupported LoongArch ABI" +#endif +#define _LIBUNWIND_HIGHEST_DWARF_REGISTER \ + _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH # else # error "Unsupported architecture." # endif @@ -185,6 +196,7 @@ # define _LIBUNWIND_TARGET_RISCV 1 # define _LIBUNWIND_TARGET_VE 1 # define _LIBUNWIND_TARGET_S390X 1 +#define _LIBUNWIND_TARGET_LOONGARCH 1 # define _LIBUNWIND_CONTEXT_SIZE 167 # define _LIBUNWIND_CURSOR_SIZE 179 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287 diff --git a/libunwind/include/libunwind.h b/libunwind/include/libunwind.h --- a/libunwind/include/libunwind.h +++ b/libunwind/include/libunwind.h @@ -1219,4 +1219,72 @@ // 68-83 Vector Registers %v16-%v31 }; +// LoongArch registers. +enum { + UNW_LOONGARCH_R0 = 0, + UNW_LOONGARCH_R1 = 1, + UNW_LOONGARCH_R2 = 2, + UNW_LOONGARCH_R3 = 3, + UNW_LOONGARCH_R4 = 4, + UNW_LOONGARCH_R5 = 5, + UNW_LOONGARCH_R6 = 6, + UNW_LOONGARCH_R7 = 7, + UNW_LOONGARCH_R8 = 8, + UNW_LOONGARCH_R9 = 9, + UNW_LOONGARCH_R10 = 10, + UNW_LOONGARCH_R11 = 11, + UNW_LOONGARCH_R12 = 12, + UNW_LOONGARCH_R13 = 13, + UNW_LOONGARCH_R14 = 14, + UNW_LOONGARCH_R15 = 15, + UNW_LOONGARCH_R16 = 16, + UNW_LOONGARCH_R17 = 17, + UNW_LOONGARCH_R18 = 18, + UNW_LOONGARCH_R19 = 19, + UNW_LOONGARCH_R20 = 20, + UNW_LOONGARCH_R21 = 21, + UNW_LOONGARCH_R22 = 22, + UNW_LOONGARCH_R23 = 23, + UNW_LOONGARCH_R24 = 24, + UNW_LOONGARCH_R25 = 25, + UNW_LOONGARCH_R26 = 26, + UNW_LOONGARCH_R27 = 27, + UNW_LOONGARCH_R28 = 28, + UNW_LOONGARCH_R29 = 29, + UNW_LOONGARCH_R30 = 30, + UNW_LOONGARCH_R31 = 31, + UNW_LOONGARCH_F0 = 32, + UNW_LOONGARCH_F1 = 33, + UNW_LOONGARCH_F2 = 34, + UNW_LOONGARCH_F3 = 35, + UNW_LOONGARCH_F4 = 36, + UNW_LOONGARCH_F5 = 37, + UNW_LOONGARCH_F6 = 38, + UNW_LOONGARCH_F7 = 39, + UNW_LOONGARCH_F8 = 40, + UNW_LOONGARCH_F9 = 41, + UNW_LOONGARCH_F10 = 42, + UNW_LOONGARCH_F11 = 43, + UNW_LOONGARCH_F12 = 44, + UNW_LOONGARCH_F13 = 45, + UNW_LOONGARCH_F14 = 46, + UNW_LOONGARCH_F15 = 47, + UNW_LOONGARCH_F16 = 48, + UNW_LOONGARCH_F17 = 49, + UNW_LOONGARCH_F18 = 50, + UNW_LOONGARCH_F19 = 51, + UNW_LOONGARCH_F20 = 52, + UNW_LOONGARCH_F21 = 53, + UNW_LOONGARCH_F22 = 54, + UNW_LOONGARCH_F23 = 55, + UNW_LOONGARCH_F24 = 56, + UNW_LOONGARCH_F25 = 57, + UNW_LOONGARCH_F26 = 58, + UNW_LOONGARCH_F27 = 59, + UNW_LOONGARCH_F28 = 60, + UNW_LOONGARCH_F29 = 61, + UNW_LOONGARCH_F30 = 62, + UNW_LOONGARCH_F31 = 63, +}; + #endif diff --git a/libunwind/src/Registers.hpp b/libunwind/src/Registers.hpp --- a/libunwind/src/Registers.hpp +++ b/libunwind/src/Registers.hpp @@ -40,6 +40,7 @@ REGISTERS_RISCV, REGISTERS_VE, REGISTERS_S390X, + REGISTERS_LOONGARCH, }; #if defined(_LIBUNWIND_TARGET_I386) @@ -5031,6 +5032,271 @@ } #endif // _LIBUNWIND_TARGET_S390X +#if defined(_LIBUNWIND_TARGET_LOONGARCH) +/// Registers_loongarch holds the register state of a thread in a 64-bit +/// LoongArch process. +class _LIBUNWIND_HIDDEN Registers_loongarch { +public: + Registers_loongarch(); + Registers_loongarch(const void *registers); + + bool validRegister(int num) const; + uint64_t getRegister(int num) const; + void setRegister(int num, uint64_t value); + bool validFloatRegister(int num) const; + double getFloatRegister(int num) const; + void setFloatRegister(int num, double value); + bool validVectorRegister(int num) const; + v128 getVectorRegister(int num) const; + void setVectorRegister(int num, v128 value); + static const char *getRegisterName(int num); + void jumpto(); + static constexpr int lastDwarfRegNum() { + return _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH; + } + static int getArch() { return REGISTERS_LOONGARCH; } + + uint64_t getSP() const { return _registers.__r[3]; } + void setSP(uint64_t value) { _registers.__r[3] = value; } + uint64_t getIP() const { return _registers.__pc; } + void setIP(uint64_t value) { _registers.__pc = value; } + +private: + struct loongarch_thread_state_t { + uint64_t __r[32]; + uint64_t __pc; + }; + + loongarch_thread_state_t _registers; +#if __loongarch_frlen == 64 + double _floats[32]; +#endif +}; + +inline Registers_loongarch::Registers_loongarch(const void *registers) { + static_assert((check_fit::does_fit), + "loongarch registers do not fit into unw_context_t"); + memcpy(&_registers, registers, sizeof(_registers)); + static_assert(sizeof(_registers) == 0x108, + "expected float registers to be at offset 264"); +#if __loongarch_frlen == 64 + memcpy(_floats, static_cast(registers) + sizeof(_registers), + sizeof(_floats)); +#endif +} + +inline Registers_loongarch::Registers_loongarch() { + memset(&_registers, 0, sizeof(_registers)); +#if __loongarch_frlen == 64 + memset(&_floats, 0, sizeof(_floats)); +#endif +} + +inline bool Registers_loongarch::validRegister(int regNum) const { + if (regNum == UNW_REG_IP || regNum == UNW_REG_SP) + return true; + if (regNum < 0 || regNum > UNW_LOONGARCH_F31) + return false; + return true; +} + +inline uint64_t Registers_loongarch::getRegister(int regNum) const { + if (regNum >= UNW_LOONGARCH_R0 && regNum <= UNW_LOONGARCH_R31) + return _registers.__r[regNum - UNW_LOONGARCH_R0]; + + if (regNum == UNW_REG_IP) + return _registers.__pc; + if (regNum == UNW_REG_SP) + return _registers.__r[3]; + _LIBUNWIND_ABORT("unsupported loongarch register"); +} + +inline void Registers_loongarch::setRegister(int regNum, uint64_t value) { + if (regNum >= UNW_LOONGARCH_R0 && regNum <= UNW_LOONGARCH_R31) + _registers.__r[regNum - UNW_LOONGARCH_R0] = value; + else if (regNum == UNW_REG_IP) + _registers.__pc = value; + else if (regNum == UNW_REG_SP) + _registers.__r[3] = value; + else + _LIBUNWIND_ABORT("unsupported loongarch register"); +} + +inline const char *Registers_loongarch::getRegisterName(int regNum) { + switch (regNum) { + case UNW_REG_IP: + return "$pc"; + case UNW_REG_SP: + return "$sp"; + case UNW_LOONGARCH_R0: + return "$r0"; + case UNW_LOONGARCH_R1: + return "$r1"; + case UNW_LOONGARCH_R2: + return "$r2"; + case UNW_LOONGARCH_R3: + return "$r3"; + case UNW_LOONGARCH_R4: + return "$r4"; + case UNW_LOONGARCH_R5: + return "$r5"; + case UNW_LOONGARCH_R6: + return "$r6"; + case UNW_LOONGARCH_R7: + return "$r7"; + case UNW_LOONGARCH_R8: + return "$r8"; + case UNW_LOONGARCH_R9: + return "$r9"; + case UNW_LOONGARCH_R10: + return "$r10"; + case UNW_LOONGARCH_R11: + return "$r11"; + case UNW_LOONGARCH_R12: + return "$r12"; + case UNW_LOONGARCH_R13: + return "$r13"; + case UNW_LOONGARCH_R14: + return "$r14"; + case UNW_LOONGARCH_R15: + return "$r15"; + case UNW_LOONGARCH_R16: + return "$r16"; + case UNW_LOONGARCH_R17: + return "$r17"; + case UNW_LOONGARCH_R18: + return "$r18"; + case UNW_LOONGARCH_R19: + return "$r19"; + case UNW_LOONGARCH_R20: + return "$r20"; + case UNW_LOONGARCH_R21: + return "$r21"; + case UNW_LOONGARCH_R22: + return "$r22"; + case UNW_LOONGARCH_R23: + return "$r23"; + case UNW_LOONGARCH_R24: + return "$r24"; + case UNW_LOONGARCH_R25: + return "$r25"; + case UNW_LOONGARCH_R26: + return "$r26"; + case UNW_LOONGARCH_R27: + return "$r27"; + case UNW_LOONGARCH_R28: + return "$r28"; + case UNW_LOONGARCH_R29: + return "$r29"; + case UNW_LOONGARCH_R30: + return "$r30"; + case UNW_LOONGARCH_R31: + return "$r31"; + case UNW_LOONGARCH_F0: + return "$f0"; + case UNW_LOONGARCH_F1: + return "$f1"; + case UNW_LOONGARCH_F2: + return "$f2"; + case UNW_LOONGARCH_F3: + return "$f3"; + case UNW_LOONGARCH_F4: + return "$f4"; + case UNW_LOONGARCH_F5: + return "$f5"; + case UNW_LOONGARCH_F6: + return "$f6"; + case UNW_LOONGARCH_F7: + return "$f7"; + case UNW_LOONGARCH_F8: + return "$f8"; + case UNW_LOONGARCH_F9: + return "$f9"; + case UNW_LOONGARCH_F10: + return "$f10"; + case UNW_LOONGARCH_F11: + return "$f11"; + case UNW_LOONGARCH_F12: + return "$f12"; + case UNW_LOONGARCH_F13: + return "$f13"; + case UNW_LOONGARCH_F14: + return "$f14"; + case UNW_LOONGARCH_F15: + return "$f15"; + case UNW_LOONGARCH_F16: + return "$f16"; + case UNW_LOONGARCH_F17: + return "$f17"; + case UNW_LOONGARCH_F18: + return "$f18"; + case UNW_LOONGARCH_F19: + return "$f19"; + case UNW_LOONGARCH_F20: + return "$f20"; + case UNW_LOONGARCH_F21: + return "$f21"; + case UNW_LOONGARCH_F22: + return "$f22"; + case UNW_LOONGARCH_F23: + return "$f23"; + case UNW_LOONGARCH_F24: + return "$f24"; + case UNW_LOONGARCH_F25: + return "$f25"; + case UNW_LOONGARCH_F26: + return "$f26"; + case UNW_LOONGARCH_F27: + return "$f27"; + case UNW_LOONGARCH_F28: + return "$f28"; + case UNW_LOONGARCH_F29: + return "$f29"; + case UNW_LOONGARCH_F30: + return "$f30"; + case UNW_LOONGARCH_F31: + return "$f31"; + default: + return "unknown register"; + } +} + +inline bool Registers_loongarch::validFloatRegister(int regNum) const { + if (regNum < UNW_LOONGARCH_F0 || regNum > UNW_LOONGARCH_F31) + return false; + return true; +} + +inline double Registers_loongarch::getFloatRegister(int regNum) const { +#if __loongarch_frlen == 64 + assert(validFloatRegister(regNum)); + return _floats[regNum - UNW_LOONGARCH_F0]; +#else + _LIBUNWIND_ABORT("libunwind not built with float support"); +#endif +} + +inline void Registers_loongarch::setFloatRegister(int regNum, double value) { +#if __loongarch_frlen == 64 + assert(validFloatRegister(regNum)); + _floats[regNum - UNW_LOONGARCH_F0] = value; +#else + _LIBUNWIND_ABORT("libunwind not built with float support"); +#endif +} + +inline bool Registers_loongarch::validVectorRegister(int) const { + return false; +} + +inline v128 Registers_loongarch::getVectorRegister(int) const { + _LIBUNWIND_ABORT("loongarch vector support not implemented"); +} + +inline void Registers_loongarch::setVectorRegister(int, v128) { + _LIBUNWIND_ABORT("loongarch vector support not implemented"); +} +#endif //_LIBUNWIND_TARGET_LOONGARCH } // namespace libunwind diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp --- a/libunwind/src/UnwindCursor.hpp +++ b/libunwind/src/UnwindCursor.hpp @@ -1064,6 +1064,10 @@ } #endif +#if defined(_LIBUNWIND_TARGET_LOONGARCH) + int stepWithCompactEncoding(Registers_loongarch &) { return UNW_EINVAL; } +#endif + #if defined(_LIBUNWIND_TARGET_SPARC) int stepWithCompactEncoding(Registers_sparc &) { return UNW_EINVAL; } #endif @@ -1140,6 +1144,12 @@ } #endif +#if defined(_LIBUNWIND_TARGET_LOONGARCH) + bool compactSaysUseDwarf(Registers_loongarch &, uint32_t *) const { + return true; + } +#endif + #if defined(_LIBUNWIND_TARGET_SPARC) bool compactSaysUseDwarf(Registers_sparc &, uint32_t *) const { return true; } #endif @@ -1224,6 +1234,12 @@ } #endif +#if defined(_LIBUNWIND_TARGET_LOONGARCH) + compact_unwind_encoding_t dwarfEncoding(Registers_loongarch &) const { + return 0; + } +#endif + #if defined(_LIBUNWIND_TARGET_SPARC) compact_unwind_encoding_t dwarfEncoding(Registers_sparc &) const { return 0; } #endif diff --git a/libunwind/src/UnwindRegistersRestore.S b/libunwind/src/UnwindRegistersRestore.S --- a/libunwind/src/UnwindRegistersRestore.S +++ b/libunwind/src/UnwindRegistersRestore.S @@ -1289,6 +1289,88 @@ // Return to PSWA (was loaded into %r1 above) br %r1 +#elif defined(__loongarch__) && __loongarch_grlen == 64 + +// +// void libunwind::Registers_loongarch::jumpto() +// +// On entry: +// thread_state pointer is in $a0($r4) +// + .p2align 2 +DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind19Registers_loongarch6jumptoEv) +# if __loongarch_frlen == 64 + fld.d $f0, $a0, (8 * 33 + 8 * 0) + fld.d $f1, $a0, (8 * 33 + 8 * 1) + fld.d $f2, $a0, (8 * 33 + 8 * 2) + fld.d $f3, $a0, (8 * 33 + 8 * 3) + fld.d $f4, $a0, (8 * 33 + 8 * 4) + fld.d $f5, $a0, (8 * 33 + 8 * 5) + fld.d $f6, $a0, (8 * 33 + 8 * 6) + fld.d $f7, $a0, (8 * 33 + 8 * 7) + fld.d $f8, $a0, (8 * 33 + 8 * 8) + fld.d $f9, $a0, (8 * 33 + 8 * 9) + fld.d $f10, $a0, (8 * 33 + 8 * 10) + fld.d $f11, $a0, (8 * 33 + 8 * 11) + fld.d $f12, $a0, (8 * 33 + 8 * 12) + fld.d $f13, $a0, (8 * 33 + 8 * 13) + fld.d $f14, $a0, (8 * 33 + 8 * 14) + fld.d $f15, $a0, (8 * 33 + 8 * 15) + fld.d $f16, $a0, (8 * 33 + 8 * 16) + fld.d $f17, $a0, (8 * 33 + 8 * 17) + fld.d $f18, $a0, (8 * 33 + 8 * 18) + fld.d $f19, $a0, (8 * 33 + 8 * 19) + fld.d $f20, $a0, (8 * 33 + 8 * 20) + fld.d $f21, $a0, (8 * 33 + 8 * 21) + fld.d $f22, $a0, (8 * 33 + 8 * 22) + fld.d $f23, $a0, (8 * 33 + 8 * 23) + fld.d $f24, $a0, (8 * 33 + 8 * 24) + fld.d $f25, $a0, (8 * 33 + 8 * 25) + fld.d $f26, $a0, (8 * 33 + 8 * 26) + fld.d $f27, $a0, (8 * 33 + 8 * 27) + fld.d $f28, $a0, (8 * 33 + 8 * 28) + fld.d $f29, $a0, (8 * 33 + 8 * 29) + fld.d $f30, $a0, (8 * 33 + 8 * 30) + fld.d $f31, $a0, (8 * 33 + 8 * 31) +# endif + + // $r0 is zero + ld.d $r1, $a0, (8 * 1) + ld.d $r2, $a0, (8 * 2) + ld.d $r3, $a0, (8 * 3) + // skip $a0 for now + ld.d $r5, $a0, (8 * 5) + ld.d $r6, $a0, (8 * 6) + ld.d $r7, $a0, (8 * 7) + ld.d $r8, $a0, (8 * 8) + ld.d $r9, $a0, (8 * 9) + ld.d $r10, $a0, (8 * 10) + ld.d $r11, $a0, (8 * 11) + ld.d $r12, $a0, (8 * 12) + ld.d $r13, $a0, (8 * 13) + ld.d $r14, $a0, (8 * 14) + ld.d $r15, $a0, (8 * 15) + ld.d $r16, $a0, (8 * 16) + ld.d $r17, $a0, (8 * 17) + ld.d $r18, $a0, (8 * 18) + ld.d $r19, $a0, (8 * 19) + ld.d $r20, $a0, (8 * 20) + ld.d $r21, $a0, (8 * 21) + ld.d $r22, $a0, (8 * 22) + ld.d $r23, $a0, (8 * 23) + ld.d $r24, $a0, (8 * 24) + ld.d $r25, $a0, (8 * 25) + ld.d $r26, $a0, (8 * 26) + ld.d $r27, $a0, (8 * 27) + ld.d $r28, $a0, (8 * 28) + ld.d $r29, $a0, (8 * 29) + ld.d $r30, $a0, (8 * 30) + ld.d $r31, $a0, (8 * 31) + ld.d $r4, $a0, (8 * 4) // restore $a0 last + ld.d $r1, $a0, (8 * 32) // load new pc into $ra + + jr $ra + #endif #endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */ diff --git a/libunwind/src/UnwindRegistersSave.S b/libunwind/src/UnwindRegistersSave.S --- a/libunwind/src/UnwindRegistersSave.S +++ b/libunwind/src/UnwindRegistersSave.S @@ -1222,6 +1222,86 @@ lghi %r2, 0 br %r14 +#elif defined(__loongarch__) && __loongarch_grlen == 64 + +# +# extern int __unw_getcontext(unw_context_t* thread_state) +# +# On entry: +# thread_state pointer is in $a0($r4) +# +DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) + st.d $r1, $a0, (8 * 1) + st.d $r2, $a0, (8 * 2) + st.d $r3, $a0, (8 * 3) + st.d $r4, $a0, (8 * 4) + st.d $r5, $a0, (8 * 5) + st.d $r6, $a0, (8 * 6) + st.d $r7, $a0, (8 * 7) + st.d $r8, $a0, (8 * 8) + st.d $r9, $a0, (8 * 9) + st.d $r10, $a0, (8 * 10) + st.d $r11, $a0, (8 * 11) + st.d $r12, $a0, (8 * 12) + st.d $r13, $a0, (8 * 13) + st.d $r14, $a0, (8 * 14) + st.d $r15, $a0, (8 * 15) + st.d $r16, $a0, (8 * 16) + st.d $r17, $a0, (8 * 17) + st.d $r18, $a0, (8 * 18) + st.d $r19, $a0, (8 * 19) + st.d $r20, $a0, (8 * 20) + st.d $r21, $a0, (8 * 21) + st.d $r22, $a0, (8 * 22) + st.d $r23, $a0, (8 * 23) + st.d $r24, $a0, (8 * 24) + st.d $r25, $a0, (8 * 25) + st.d $r26, $a0, (8 * 26) + st.d $r27, $a0, (8 * 27) + st.d $r28, $a0, (8 * 28) + st.d $r29, $a0, (8 * 29) + st.d $r30, $a0, (8 * 30) + st.d $r31, $a0, (8 * 31) + st.d $r1, $a0, (8 * 32) // store $ra to pc + +# if __loongarch_frlen == 64 + fst.d $f0, $a0, (8 * 33 + 8 * 0) + fst.d $f1, $a0, (8 * 33 + 8 * 1) + fst.d $f2, $a0, (8 * 33 + 8 * 2) + fst.d $f3, $a0, (8 * 33 + 8 * 3) + fst.d $f4, $a0, (8 * 33 + 8 * 4) + fst.d $f5, $a0, (8 * 33 + 8 * 5) + fst.d $f6, $a0, (8 * 33 + 8 * 6) + fst.d $f7, $a0, (8 * 33 + 8 * 7) + fst.d $f8, $a0, (8 * 33 + 8 * 8) + fst.d $f9, $a0, (8 * 33 + 8 * 9) + fst.d $f10, $a0, (8 * 33 + 8 * 10) + fst.d $f11, $a0, (8 * 33 + 8 * 11) + fst.d $f12, $a0, (8 * 33 + 8 * 12) + fst.d $f13, $a0, (8 * 33 + 8 * 13) + fst.d $f14, $a0, (8 * 33 + 8 * 14) + fst.d $f15, $a0, (8 * 33 + 8 * 15) + fst.d $f16, $a0, (8 * 33 + 8 * 16) + fst.d $f17, $a0, (8 * 33 + 8 * 17) + fst.d $f18, $a0, (8 * 33 + 8 * 18) + fst.d $f19, $a0, (8 * 33 + 8 * 19) + fst.d $f20, $a0, (8 * 33 + 8 * 20) + fst.d $f21, $a0, (8 * 33 + 8 * 21) + fst.d $f22, $a0, (8 * 33 + 8 * 22) + fst.d $f23, $a0, (8 * 33 + 8 * 23) + fst.d $f24, $a0, (8 * 33 + 8 * 24) + fst.d $f25, $a0, (8 * 33 + 8 * 25) + fst.d $f26, $a0, (8 * 33 + 8 * 26) + fst.d $f27, $a0, (8 * 33 + 8 * 27) + fst.d $f28, $a0, (8 * 33 + 8 * 28) + fst.d $f29, $a0, (8 * 33 + 8 * 29) + fst.d $f30, $a0, (8 * 33 + 8 * 30) + fst.d $f31, $a0, (8 * 33 + 8 * 31) +# endif + + move $a0, $zero // UNW_ESUCCESS + jr $ra + #endif WEAK_ALIAS(__unw_getcontext, unw_getcontext) diff --git a/libunwind/src/config.h b/libunwind/src/config.h --- a/libunwind/src/config.h +++ b/libunwind/src/config.h @@ -115,7 +115,7 @@ #if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || \ (!defined(__APPLE__) && defined(__arm__)) || defined(__aarch64__) || \ defined(__mips__) || defined(__riscv) || defined(__hexagon__) || \ - defined(__sparc__) || defined(__s390x__) + defined(__sparc__) || defined(__s390x__) || defined(__loongarch__) #if !defined(_LIBUNWIND_BUILD_SJLJ_APIS) #define _LIBUNWIND_BUILD_ZERO_COST_APIS #endif diff --git a/libunwind/src/libunwind.cpp b/libunwind/src/libunwind.cpp --- a/libunwind/src/libunwind.cpp +++ b/libunwind/src/libunwind.cpp @@ -77,6 +77,8 @@ # define REGISTER_KIND Registers_ve #elif defined(__s390x__) # define REGISTER_KIND Registers_s390x +#elif defined(__loongarch__) && __loongarch_grlen == 64 +#define REGISTER_KIND Registers_loongarch #else # error Architecture not supported #endif