Index: include/__libunwind_config.h =================================================================== --- include/__libunwind_config.h +++ include/__libunwind_config.h @@ -62,8 +62,13 @@ # define _LIBUNWIND_CONTEXT_SIZE 18 # define _LIBUNWIND_CURSOR_SIZE 29 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER 65 +# elif defined(__mips__) && defined(_ABIN32) && defined(__mips_soft_float) +# define _LIBUNWIND_TARGET_MIPS_NEWABI 1 +# define _LIBUNWIND_CONTEXT_SIZE 35 +# define _LIBUNWIND_CURSOR_SIZE 46 +# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 65 # elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) -# define _LIBUNWIND_TARGET_MIPS_N64 1 +# define _LIBUNWIND_TARGET_MIPS_NEWABI 1 # define _LIBUNWIND_CONTEXT_SIZE 35 # define _LIBUNWIND_CURSOR_SIZE 47 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER 65 @@ -78,7 +83,7 @@ # define _LIBUNWIND_TARGET_ARM 1 # define _LIBUNWIND_TARGET_OR1K 1 # define _LIBUNWIND_TARGET_MIPS_O32 1 -# define _LIBUNWIND_TARGET_MIPS_N64 1 +# define _LIBUNWIND_TARGET_MIPS_NEWABI 1 # define _LIBUNWIND_CONTEXT_SIZE 128 # define _LIBUNWIND_CURSOR_SIZE 140 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER 119 Index: src/AddressSpace.hpp =================================================================== --- src/AddressSpace.hpp +++ src/AddressSpace.hpp @@ -175,6 +175,7 @@ return val; } uintptr_t getP(pint_t addr); + uint64_t getRegister(pint_t addr); static uint64_t getULEB128(pint_t &addr, pint_t end); static int64_t getSLEB128(pint_t &addr, pint_t end); @@ -196,6 +197,14 @@ #endif } +inline uint64_t LocalAddressSpace::getRegister(pint_t addr) { +#if defined(__LP64__) || (defined(__mips__) && defined(_ABIN32)) + return get64(addr); +#else + return get32(addr); +#endif +} + /// Read a ULEB128 into a 64-bit word. inline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) { const uint8_t *p = (uint8_t *)addr; @@ -548,6 +557,7 @@ uint32_t get32(pint_t addr); uint64_t get64(pint_t addr); pint_t getP(pint_t addr); + uint64_t getRegister(pint_t addr); uint64_t getULEB128(pint_t &addr, pint_t end); int64_t getSLEB128(pint_t &addr, pint_t end); pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding, @@ -584,7 +594,12 @@ } template -uint64_t RemoteAddressSpace

::getULEB128(pint_t &addr, pint_t end) { +typename P::uint_t OtherAddressSpace

::getRegister(pint_t addr) { + return P::getRegister(*(uint64_t *)localCopy(addr)); +} + +template +uint64_t OtherAddressSpace

::getULEB128(pint_t &addr, pint_t end) { uintptr_t size = (end - addr); LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr); LocalAddressSpace::pint_t sladdr = laddr; Index: src/DwarfInstructions.hpp =================================================================== --- src/DwarfInstructions.hpp +++ src/DwarfInstructions.hpp @@ -82,10 +82,10 @@ const RegisterLocation &savedReg) { switch (savedReg.location) { case CFI_Parser::kRegisterInCFA: - return addressSpace.getP(cfa + (pint_t)savedReg.value); + return addressSpace.getRegister(cfa + (pint_t)savedReg.value); case CFI_Parser::kRegisterAtExpression: - return addressSpace.getP( + return addressSpace.getRegister( evaluateExpression((pint_t)savedReg.value, addressSpace, registers, cfa)); Index: src/Registers.hpp =================================================================== --- src/Registers.hpp +++ src/Registers.hpp @@ -2247,13 +2247,13 @@ } #endif // _LIBUNWIND_TARGET_MIPS_O32 -#if defined(_LIBUNWIND_TARGET_MIPS_N64) -/// Registers_mips_n64 holds the register state of a thread in a 64-bit MIPS -/// process. -class _LIBUNWIND_HIDDEN Registers_mips_n64 { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) +/// Registers_mips_newabi holds the register state of a thread in a NEWABI +/// MIPS process including both the N32 and N64 ABIs. +class _LIBUNWIND_HIDDEN Registers_mips_newabi { public: - Registers_mips_n64(); - Registers_mips_n64(const void *registers); + Registers_mips_newabi(); + Registers_mips_newabi(const void *registers); bool validRegister(int num) const; uint64_t getRegister(int num) const; @@ -2274,28 +2274,28 @@ void setIP(uint64_t value) { _registers.__pc = value; } private: - struct mips_n64_thread_state_t { + struct mips_newabi_thread_state_t { uint64_t __r[32]; uint64_t __pc; uint64_t __hi; uint64_t __lo; }; - mips_n64_thread_state_t _registers; + mips_newabi_thread_state_t _registers; }; -inline Registers_mips_n64::Registers_mips_n64(const void *registers) { - static_assert((check_fit::does_fit), - "mips_n64 registers do not fit into unw_context_t"); +inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) { + static_assert((check_fit::does_fit), + "mips_newabi registers do not fit into unw_context_t"); memcpy(&_registers, static_cast(registers), sizeof(_registers)); } -inline Registers_mips_n64::Registers_mips_n64() { +inline Registers_mips_newabi::Registers_mips_newabi() { memset(&_registers, 0, sizeof(_registers)); } -inline bool Registers_mips_n64::validRegister(int regNum) const { +inline bool Registers_mips_newabi::validRegister(int regNum) const { if (regNum == UNW_REG_IP) return true; if (regNum == UNW_REG_SP) @@ -2312,7 +2312,7 @@ return false; } -inline uint64_t Registers_mips_n64::getRegister(int regNum) const { +inline uint64_t Registers_mips_newabi::getRegister(int regNum) const { if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) return _registers.__r[regNum - UNW_MIPS_R0]; @@ -2326,10 +2326,10 @@ case UNW_MIPS_LO: return _registers.__lo; } - _LIBUNWIND_ABORT("unsupported mips_n64 register"); + _LIBUNWIND_ABORT("unsupported mips_newabi register"); } -inline void Registers_mips_n64::setRegister(int regNum, uint64_t value) { +inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) { if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) { _registers.__r[regNum - UNW_MIPS_R0] = value; return; @@ -2349,35 +2349,35 @@ _registers.__lo = value; return; } - _LIBUNWIND_ABORT("unsupported mips_n64 register"); + _LIBUNWIND_ABORT("unsupported mips_newabi register"); } -inline bool Registers_mips_n64::validFloatRegister(int /* regNum */) const { +inline bool Registers_mips_newabi::validFloatRegister(int /* regNum */) const { return false; } -inline double Registers_mips_n64::getFloatRegister(int /* regNum */) const { - _LIBUNWIND_ABORT("mips_n64 float support not implemented"); +inline double Registers_mips_newabi::getFloatRegister(int /* regNum */) const { + _LIBUNWIND_ABORT("mips_newabi float support not implemented"); } -inline void Registers_mips_n64::setFloatRegister(int /* regNum */, +inline void Registers_mips_newabi::setFloatRegister(int /* regNum */, double /* value */) { - _LIBUNWIND_ABORT("mips_n64 float support not implemented"); + _LIBUNWIND_ABORT("mips_newabi float support not implemented"); } -inline bool Registers_mips_n64::validVectorRegister(int /* regNum */) const { +inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const { return false; } -inline v128 Registers_mips_n64::getVectorRegister(int /* regNum */) const { - _LIBUNWIND_ABORT("mips_n64 vector support not implemented"); +inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const { + _LIBUNWIND_ABORT("mips_newabi vector support not implemented"); } -inline void Registers_mips_n64::setVectorRegister(int /* regNum */, v128 /* value */) { - _LIBUNWIND_ABORT("mips_n64 vector support not implemented"); +inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) { + _LIBUNWIND_ABORT("mips_newabi vector support not implemented"); } -inline const char *Registers_mips_n64::getRegisterName(int regNum) { +inline const char *Registers_mips_newabi::getRegisterName(int regNum) { switch (regNum) { case UNW_MIPS_R0: return "$0"; @@ -2451,7 +2451,7 @@ return "unknown register"; } } -#endif // _LIBUNWIND_TARGET_MIPS_N64 +#endif // _LIBUNWIND_TARGET_MIPS_NEWABI } // namespace libunwind #endif // __REGISTERS_HPP__ Index: src/UnwindCursor.hpp =================================================================== --- src/UnwindCursor.hpp +++ src/UnwindCursor.hpp @@ -514,8 +514,8 @@ } #endif -#if defined(_LIBUNWIND_TARGET_MIPS_N64) - int stepWithCompactEncoding(Registers_mips_n64 &) { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) + int stepWithCompactEncoding(Registers_mips_newabi &) { return UNW_EINVAL; } #endif @@ -570,8 +570,8 @@ } #endif -#if defined(_LIBUNWIND_TARGET_MIPS_N64) - bool compactSaysUseDwarf(Registers_mips_n64 &, uint32_t *) const { +#if defined(_LIBUNWIND_TARGET_MIPS_NEWABI) + bool compactSaysUseDwarf(Registers_mips_newabi &, uint32_t *) const { return true; } #endif @@ -619,8 +619,8 @@ } #endif -#if defined (_LIBUNWIND_TARGET_MIPS_N64) - compact_unwind_encoding_t dwarfEncoding(Registers_mips_n64 &) const { +#if defined (_LIBUNWIND_TARGET_MIPS_NEWABI) + compact_unwind_encoding_t dwarfEncoding(Registers_mips_newabi &) const { return 0; } #endif Index: src/UnwindRegistersRestore.S =================================================================== --- src/UnwindRegistersRestore.S +++ src/UnwindRegistersRestore.S @@ -580,15 +580,16 @@ lw $4, (4 * 4)($4) .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) && \ + defined(__mips_soft_float) // -// void libunwind::Registers_mips_n64::jumpto() +// void libunwind::Registers_mips_newabi::jumpto() // // On entry: // thread state pointer is in a0 ($4) // -DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind18Registers_mips_n646jumptoEv) +DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind21Registers_mips_newabi6jumptoEv) .set push .set noat .set noreorder Index: src/UnwindRegistersSave.S =================================================================== --- src/UnwindRegistersSave.S +++ src/UnwindRegistersSave.S @@ -172,7 +172,8 @@ or $2, $0, $0 .set pop -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) +#elif defined(__mips__) && (defined(_ABI64) || defined(_ABIN32)) && \ + defined(__mips_soft_float) # # extern int unw_getcontext(unw_context_t* thread_state) Index: src/libunwind.cpp =================================================================== --- src/libunwind.cpp +++ src/libunwind.cpp @@ -61,8 +61,9 @@ # define REGISTER_KIND Registers_or1k #elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float) # define REGISTER_KIND Registers_mips_o32 -#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float) -# define REGISTER_KIND Registers_mips_n64 +#elif defined(__mips__) && (defined(_ABIN32) || defined(_ABI64)) && \ + defined(__mips_soft_float) +# define REGISTER_KIND Registers_mips_newabi #elif defined(__mips__) # warning The MIPS architecture is not supported with this ABI and environment! #else