[libunwind][MIPS]: Add support for unwinding in O32 and N64 processes.
This supports the soft-float ABI only and has been tested with both clang and gcc on FreeBSD. Reviewed By: sdardis, compnerd Differential Revision: https://reviews.llvm.org/D38110 llvm-svn: 320528
This commit is contained in:
parent
b4c74c6603
commit
dfbbbdf8cd
@ -21,6 +21,7 @@
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64 95
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM 287
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K 31
|
||||
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS 65
|
||||
|
||||
#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
|
||||
# if defined(__i386__)
|
||||
@ -63,6 +64,19 @@
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 16
|
||||
# define _LIBUNWIND_CURSOR_SIZE 24
|
||||
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K
|
||||
# elif defined(__mips__)
|
||||
# if defined(_ABIO32) && defined(__mips_soft_float)
|
||||
# define _LIBUNWIND_TARGET_MIPS_O32 1
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 18
|
||||
# define _LIBUNWIND_CURSOR_SIZE 24
|
||||
# elif defined(_ABI64) && defined(__mips_soft_float)
|
||||
# define _LIBUNWIND_TARGET_MIPS_N64 1
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 35
|
||||
# define _LIBUNWIND_CURSOR_SIZE 47
|
||||
# else
|
||||
# error "Unsupported MIPS ABI and/or environment"
|
||||
# endif
|
||||
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS
|
||||
# else
|
||||
# error "Unsupported architecture."
|
||||
# endif
|
||||
@ -73,6 +87,8 @@
|
||||
# define _LIBUNWIND_TARGET_AARCH64 1
|
||||
# define _LIBUNWIND_TARGET_ARM 1
|
||||
# define _LIBUNWIND_TARGET_OR1K 1
|
||||
# define _LIBUNWIND_TARGET_MIPS_O32 1
|
||||
# define _LIBUNWIND_TARGET_MIPS_N64 1
|
||||
# define _LIBUNWIND_CONTEXT_SIZE 128
|
||||
# define _LIBUNWIND_CURSOR_SIZE 140
|
||||
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287
|
||||
|
||||
@ -563,4 +563,42 @@ enum {
|
||||
UNW_OR1K_R31 = 31,
|
||||
};
|
||||
|
||||
// MIPS registers
|
||||
enum {
|
||||
UNW_MIPS_R0 = 0,
|
||||
UNW_MIPS_R1 = 1,
|
||||
UNW_MIPS_R2 = 2,
|
||||
UNW_MIPS_R3 = 3,
|
||||
UNW_MIPS_R4 = 4,
|
||||
UNW_MIPS_R5 = 5,
|
||||
UNW_MIPS_R6 = 6,
|
||||
UNW_MIPS_R7 = 7,
|
||||
UNW_MIPS_R8 = 8,
|
||||
UNW_MIPS_R9 = 9,
|
||||
UNW_MIPS_R10 = 10,
|
||||
UNW_MIPS_R11 = 11,
|
||||
UNW_MIPS_R12 = 12,
|
||||
UNW_MIPS_R13 = 13,
|
||||
UNW_MIPS_R14 = 14,
|
||||
UNW_MIPS_R15 = 15,
|
||||
UNW_MIPS_R16 = 16,
|
||||
UNW_MIPS_R17 = 17,
|
||||
UNW_MIPS_R18 = 18,
|
||||
UNW_MIPS_R19 = 19,
|
||||
UNW_MIPS_R20 = 20,
|
||||
UNW_MIPS_R21 = 21,
|
||||
UNW_MIPS_R22 = 22,
|
||||
UNW_MIPS_R23 = 23,
|
||||
UNW_MIPS_R24 = 24,
|
||||
UNW_MIPS_R25 = 25,
|
||||
UNW_MIPS_R26 = 26,
|
||||
UNW_MIPS_R27 = 27,
|
||||
UNW_MIPS_R28 = 28,
|
||||
UNW_MIPS_R29 = 29,
|
||||
UNW_MIPS_R30 = 30,
|
||||
UNW_MIPS_R31 = 31,
|
||||
UNW_MIPS_HI = 64,
|
||||
UNW_MIPS_LO = 65,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -2041,6 +2041,418 @@ inline const char *Registers_or1k::getRegisterName(int regNum) {
|
||||
|
||||
}
|
||||
#endif // _LIBUNWIND_TARGET_OR1K
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_MIPS_O32)
|
||||
/// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS
|
||||
/// process.
|
||||
class _LIBUNWIND_HIDDEN Registers_mips_o32 {
|
||||
public:
|
||||
Registers_mips_o32();
|
||||
Registers_mips_o32(const void *registers);
|
||||
|
||||
bool validRegister(int num) const;
|
||||
uint32_t getRegister(int num) const;
|
||||
void setRegister(int num, uint32_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);
|
||||
const char *getRegisterName(int num);
|
||||
void jumpto();
|
||||
static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
|
||||
|
||||
uint32_t getSP() const { return _registers.__r[29]; }
|
||||
void setSP(uint32_t value) { _registers.__r[29] = value; }
|
||||
uint32_t getIP() const { return _registers.__pc; }
|
||||
void setIP(uint32_t value) { _registers.__pc = value; }
|
||||
|
||||
private:
|
||||
struct mips_o32_thread_state_t {
|
||||
uint32_t __r[32];
|
||||
uint32_t __pc;
|
||||
uint32_t __hi;
|
||||
uint32_t __lo;
|
||||
};
|
||||
|
||||
mips_o32_thread_state_t _registers;
|
||||
};
|
||||
|
||||
inline Registers_mips_o32::Registers_mips_o32(const void *registers) {
|
||||
static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit),
|
||||
"mips_o32 registers do not fit into unw_context_t");
|
||||
memcpy(&_registers, static_cast<const uint8_t *>(registers),
|
||||
sizeof(_registers));
|
||||
}
|
||||
|
||||
inline Registers_mips_o32::Registers_mips_o32() {
|
||||
memset(&_registers, 0, sizeof(_registers));
|
||||
}
|
||||
|
||||
inline bool Registers_mips_o32::validRegister(int regNum) const {
|
||||
if (regNum == UNW_REG_IP)
|
||||
return true;
|
||||
if (regNum == UNW_REG_SP)
|
||||
return true;
|
||||
if (regNum < 0)
|
||||
return false;
|
||||
if (regNum <= UNW_MIPS_R31)
|
||||
return true;
|
||||
if (regNum == UNW_MIPS_HI)
|
||||
return true;
|
||||
if (regNum == UNW_MIPS_LO)
|
||||
return true;
|
||||
// FIXME: Hard float, DSP accumulator registers, MSA registers
|
||||
return false;
|
||||
}
|
||||
|
||||
inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
|
||||
if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
|
||||
return _registers.__r[regNum - UNW_MIPS_R0];
|
||||
|
||||
switch (regNum) {
|
||||
case UNW_REG_IP:
|
||||
return _registers.__pc;
|
||||
case UNW_REG_SP:
|
||||
return _registers.__r[29];
|
||||
case UNW_MIPS_HI:
|
||||
return _registers.__hi;
|
||||
case UNW_MIPS_LO:
|
||||
return _registers.__lo;
|
||||
}
|
||||
_LIBUNWIND_ABORT("unsupported mips_o32 register");
|
||||
}
|
||||
|
||||
inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {
|
||||
if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
|
||||
_registers.__r[regNum - UNW_MIPS_R0] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (regNum) {
|
||||
case UNW_REG_IP:
|
||||
_registers.__pc = value;
|
||||
return;
|
||||
case UNW_REG_SP:
|
||||
_registers.__r[29] = value;
|
||||
return;
|
||||
case UNW_MIPS_HI:
|
||||
_registers.__hi = value;
|
||||
return;
|
||||
case UNW_MIPS_LO:
|
||||
_registers.__lo = value;
|
||||
return;
|
||||
}
|
||||
_LIBUNWIND_ABORT("unsupported mips_o32 register");
|
||||
}
|
||||
|
||||
inline bool Registers_mips_o32::validFloatRegister(int /* regNum */) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline double Registers_mips_o32::getFloatRegister(int /* regNum */) const {
|
||||
_LIBUNWIND_ABORT("mips_o32 float support not implemented");
|
||||
}
|
||||
|
||||
inline void Registers_mips_o32::setFloatRegister(int /* regNum */,
|
||||
double /* value */) {
|
||||
_LIBUNWIND_ABORT("mips_o32 float support not implemented");
|
||||
}
|
||||
|
||||
inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const {
|
||||
_LIBUNWIND_ABORT("mips_o32 vector support not implemented");
|
||||
}
|
||||
|
||||
inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) {
|
||||
_LIBUNWIND_ABORT("mips_o32 vector support not implemented");
|
||||
}
|
||||
|
||||
inline const char *Registers_mips_o32::getRegisterName(int regNum) {
|
||||
switch (regNum) {
|
||||
case UNW_MIPS_R0:
|
||||
return "$0";
|
||||
case UNW_MIPS_R1:
|
||||
return "$1";
|
||||
case UNW_MIPS_R2:
|
||||
return "$2";
|
||||
case UNW_MIPS_R3:
|
||||
return "$3";
|
||||
case UNW_MIPS_R4:
|
||||
return "$4";
|
||||
case UNW_MIPS_R5:
|
||||
return "$5";
|
||||
case UNW_MIPS_R6:
|
||||
return "$6";
|
||||
case UNW_MIPS_R7:
|
||||
return "$7";
|
||||
case UNW_MIPS_R8:
|
||||
return "$8";
|
||||
case UNW_MIPS_R9:
|
||||
return "$9";
|
||||
case UNW_MIPS_R10:
|
||||
return "$10";
|
||||
case UNW_MIPS_R11:
|
||||
return "$11";
|
||||
case UNW_MIPS_R12:
|
||||
return "$12";
|
||||
case UNW_MIPS_R13:
|
||||
return "$13";
|
||||
case UNW_MIPS_R14:
|
||||
return "$14";
|
||||
case UNW_MIPS_R15:
|
||||
return "$15";
|
||||
case UNW_MIPS_R16:
|
||||
return "$16";
|
||||
case UNW_MIPS_R17:
|
||||
return "$17";
|
||||
case UNW_MIPS_R18:
|
||||
return "$18";
|
||||
case UNW_MIPS_R19:
|
||||
return "$19";
|
||||
case UNW_MIPS_R20:
|
||||
return "$20";
|
||||
case UNW_MIPS_R21:
|
||||
return "$21";
|
||||
case UNW_MIPS_R22:
|
||||
return "$22";
|
||||
case UNW_MIPS_R23:
|
||||
return "$23";
|
||||
case UNW_MIPS_R24:
|
||||
return "$24";
|
||||
case UNW_MIPS_R25:
|
||||
return "$25";
|
||||
case UNW_MIPS_R26:
|
||||
return "$26";
|
||||
case UNW_MIPS_R27:
|
||||
return "$27";
|
||||
case UNW_MIPS_R28:
|
||||
return "$28";
|
||||
case UNW_MIPS_R29:
|
||||
return "$29";
|
||||
case UNW_MIPS_R30:
|
||||
return "$30";
|
||||
case UNW_MIPS_R31:
|
||||
return "$31";
|
||||
case UNW_MIPS_HI:
|
||||
return "$hi";
|
||||
case UNW_MIPS_LO:
|
||||
return "$lo";
|
||||
default:
|
||||
return "unknown register";
|
||||
}
|
||||
}
|
||||
#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 {
|
||||
public:
|
||||
Registers_mips_n64();
|
||||
Registers_mips_n64(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);
|
||||
const char *getRegisterName(int num);
|
||||
void jumpto();
|
||||
static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
|
||||
|
||||
uint64_t getSP() const { return _registers.__r[29]; }
|
||||
void setSP(uint64_t value) { _registers.__r[29] = value; }
|
||||
uint64_t getIP() const { return _registers.__pc; }
|
||||
void setIP(uint64_t value) { _registers.__pc = value; }
|
||||
|
||||
private:
|
||||
struct mips_n64_thread_state_t {
|
||||
uint64_t __r[32];
|
||||
uint64_t __pc;
|
||||
uint64_t __hi;
|
||||
uint64_t __lo;
|
||||
};
|
||||
|
||||
mips_n64_thread_state_t _registers;
|
||||
};
|
||||
|
||||
inline Registers_mips_n64::Registers_mips_n64(const void *registers) {
|
||||
static_assert((check_fit<Registers_mips_n64, unw_context_t>::does_fit),
|
||||
"mips_n64 registers do not fit into unw_context_t");
|
||||
memcpy(&_registers, static_cast<const uint8_t *>(registers),
|
||||
sizeof(_registers));
|
||||
}
|
||||
|
||||
inline Registers_mips_n64::Registers_mips_n64() {
|
||||
memset(&_registers, 0, sizeof(_registers));
|
||||
}
|
||||
|
||||
inline bool Registers_mips_n64::validRegister(int regNum) const {
|
||||
if (regNum == UNW_REG_IP)
|
||||
return true;
|
||||
if (regNum == UNW_REG_SP)
|
||||
return true;
|
||||
if (regNum < 0)
|
||||
return false;
|
||||
if (regNum <= UNW_MIPS_R31)
|
||||
return true;
|
||||
if (regNum == UNW_MIPS_HI)
|
||||
return true;
|
||||
if (regNum == UNW_MIPS_LO)
|
||||
return true;
|
||||
// FIXME: Hard float, DSP accumulator registers, MSA registers
|
||||
return false;
|
||||
}
|
||||
|
||||
inline uint64_t Registers_mips_n64::getRegister(int regNum) const {
|
||||
if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
|
||||
return _registers.__r[regNum - UNW_MIPS_R0];
|
||||
|
||||
switch (regNum) {
|
||||
case UNW_REG_IP:
|
||||
return _registers.__pc;
|
||||
case UNW_REG_SP:
|
||||
return _registers.__r[29];
|
||||
case UNW_MIPS_HI:
|
||||
return _registers.__hi;
|
||||
case UNW_MIPS_LO:
|
||||
return _registers.__lo;
|
||||
}
|
||||
_LIBUNWIND_ABORT("unsupported mips_n64 register");
|
||||
}
|
||||
|
||||
inline void Registers_mips_n64::setRegister(int regNum, uint64_t value) {
|
||||
if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
|
||||
_registers.__r[regNum - UNW_MIPS_R0] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (regNum) {
|
||||
case UNW_REG_IP:
|
||||
_registers.__pc = value;
|
||||
return;
|
||||
case UNW_REG_SP:
|
||||
_registers.__r[29] = value;
|
||||
return;
|
||||
case UNW_MIPS_HI:
|
||||
_registers.__hi = value;
|
||||
return;
|
||||
case UNW_MIPS_LO:
|
||||
_registers.__lo = value;
|
||||
return;
|
||||
}
|
||||
_LIBUNWIND_ABORT("unsupported mips_n64 register");
|
||||
}
|
||||
|
||||
inline bool Registers_mips_n64::validFloatRegister(int /* regNum */) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline double Registers_mips_n64::getFloatRegister(int /* regNum */) const {
|
||||
_LIBUNWIND_ABORT("mips_n64 float support not implemented");
|
||||
}
|
||||
|
||||
inline void Registers_mips_n64::setFloatRegister(int /* regNum */,
|
||||
double /* value */) {
|
||||
_LIBUNWIND_ABORT("mips_n64 float support not implemented");
|
||||
}
|
||||
|
||||
inline bool Registers_mips_n64::validVectorRegister(int /* regNum */) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline v128 Registers_mips_n64::getVectorRegister(int /* regNum */) const {
|
||||
_LIBUNWIND_ABORT("mips_n64 vector support not implemented");
|
||||
}
|
||||
|
||||
inline void Registers_mips_n64::setVectorRegister(int /* regNum */, v128 /* value */) {
|
||||
_LIBUNWIND_ABORT("mips_n64 vector support not implemented");
|
||||
}
|
||||
|
||||
inline const char *Registers_mips_n64::getRegisterName(int regNum) {
|
||||
switch (regNum) {
|
||||
case UNW_MIPS_R0:
|
||||
return "$0";
|
||||
case UNW_MIPS_R1:
|
||||
return "$1";
|
||||
case UNW_MIPS_R2:
|
||||
return "$2";
|
||||
case UNW_MIPS_R3:
|
||||
return "$3";
|
||||
case UNW_MIPS_R4:
|
||||
return "$4";
|
||||
case UNW_MIPS_R5:
|
||||
return "$5";
|
||||
case UNW_MIPS_R6:
|
||||
return "$6";
|
||||
case UNW_MIPS_R7:
|
||||
return "$7";
|
||||
case UNW_MIPS_R8:
|
||||
return "$8";
|
||||
case UNW_MIPS_R9:
|
||||
return "$9";
|
||||
case UNW_MIPS_R10:
|
||||
return "$10";
|
||||
case UNW_MIPS_R11:
|
||||
return "$11";
|
||||
case UNW_MIPS_R12:
|
||||
return "$12";
|
||||
case UNW_MIPS_R13:
|
||||
return "$13";
|
||||
case UNW_MIPS_R14:
|
||||
return "$14";
|
||||
case UNW_MIPS_R15:
|
||||
return "$15";
|
||||
case UNW_MIPS_R16:
|
||||
return "$16";
|
||||
case UNW_MIPS_R17:
|
||||
return "$17";
|
||||
case UNW_MIPS_R18:
|
||||
return "$18";
|
||||
case UNW_MIPS_R19:
|
||||
return "$19";
|
||||
case UNW_MIPS_R20:
|
||||
return "$20";
|
||||
case UNW_MIPS_R21:
|
||||
return "$21";
|
||||
case UNW_MIPS_R22:
|
||||
return "$22";
|
||||
case UNW_MIPS_R23:
|
||||
return "$23";
|
||||
case UNW_MIPS_R24:
|
||||
return "$24";
|
||||
case UNW_MIPS_R25:
|
||||
return "$25";
|
||||
case UNW_MIPS_R26:
|
||||
return "$26";
|
||||
case UNW_MIPS_R27:
|
||||
return "$27";
|
||||
case UNW_MIPS_R28:
|
||||
return "$28";
|
||||
case UNW_MIPS_R29:
|
||||
return "$29";
|
||||
case UNW_MIPS_R30:
|
||||
return "$30";
|
||||
case UNW_MIPS_R31:
|
||||
return "$31";
|
||||
case UNW_MIPS_HI:
|
||||
return "$hi";
|
||||
case UNW_MIPS_LO:
|
||||
return "$lo";
|
||||
default:
|
||||
return "unknown register";
|
||||
}
|
||||
}
|
||||
#endif // _LIBUNWIND_TARGET_MIPS_N64
|
||||
} // namespace libunwind
|
||||
|
||||
#endif // __REGISTERS_HPP__
|
||||
|
||||
@ -508,6 +508,18 @@ private:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_MIPS_O32)
|
||||
int stepWithCompactEncoding(Registers_mips_o32 &) {
|
||||
return UNW_EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_MIPS_N64)
|
||||
int stepWithCompactEncoding(Registers_mips_n64 &) {
|
||||
return UNW_EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool compactSaysUseDwarf(uint32_t *offset=NULL) const {
|
||||
R dummy;
|
||||
return compactSaysUseDwarf(dummy, offset);
|
||||
@ -551,6 +563,18 @@ private:
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_MIPS_O32)
|
||||
bool compactSaysUseDwarf(Registers_mips_o32 &, uint32_t *) const {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_LIBUNWIND_TARGET_MIPS_N64)
|
||||
bool compactSaysUseDwarf(Registers_mips_n64 &, uint32_t *) const {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
#endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
|
||||
|
||||
#if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
|
||||
@ -594,6 +618,18 @@ private:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (_LIBUNWIND_TARGET_MIPS_O32)
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_mips_o32 &) const {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (_LIBUNWIND_TARGET_MIPS_N64)
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_mips_n64 &) const {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
|
||||
|
||||
|
||||
|
||||
@ -534,6 +534,118 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv)
|
||||
l.jr r9
|
||||
l.nop
|
||||
|
||||
#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float)
|
||||
|
||||
//
|
||||
// void libunwind::Registers_mips_o32::jumpto()
|
||||
//
|
||||
// On entry:
|
||||
// thread state pointer is in a0 ($4)
|
||||
//
|
||||
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind18Registers_mips_o326jumptoEv)
|
||||
.set push
|
||||
.set noat
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
// restore hi and lo
|
||||
lw $8, (4 * 33)($4)
|
||||
mthi $8
|
||||
lw $8, (4 * 34)($4)
|
||||
mtlo $8
|
||||
// r0 is zero
|
||||
lw $1, (4 * 1)($4)
|
||||
lw $2, (4 * 2)($4)
|
||||
lw $3, (4 * 3)($4)
|
||||
// skip a0 for now
|
||||
lw $5, (4 * 5)($4)
|
||||
lw $6, (4 * 6)($4)
|
||||
lw $7, (4 * 7)($4)
|
||||
lw $8, (4 * 8)($4)
|
||||
lw $9, (4 * 9)($4)
|
||||
lw $10, (4 * 10)($4)
|
||||
lw $11, (4 * 11)($4)
|
||||
lw $12, (4 * 12)($4)
|
||||
lw $13, (4 * 13)($4)
|
||||
lw $14, (4 * 14)($4)
|
||||
lw $15, (4 * 15)($4)
|
||||
lw $16, (4 * 16)($4)
|
||||
lw $17, (4 * 17)($4)
|
||||
lw $18, (4 * 18)($4)
|
||||
lw $19, (4 * 19)($4)
|
||||
lw $20, (4 * 20)($4)
|
||||
lw $21, (4 * 21)($4)
|
||||
lw $22, (4 * 22)($4)
|
||||
lw $23, (4 * 23)($4)
|
||||
lw $24, (4 * 24)($4)
|
||||
lw $25, (4 * 25)($4)
|
||||
lw $26, (4 * 26)($4)
|
||||
lw $27, (4 * 27)($4)
|
||||
lw $28, (4 * 28)($4)
|
||||
lw $29, (4 * 29)($4)
|
||||
lw $30, (4 * 30)($4)
|
||||
// load new pc into ra
|
||||
lw $31, (4 * 32)($4)
|
||||
// jump to ra, load a0 in the delay slot
|
||||
jr $31
|
||||
lw $4, (4 * 4)($4)
|
||||
.set pop
|
||||
|
||||
#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float)
|
||||
|
||||
//
|
||||
// void libunwind::Registers_mips_n64::jumpto()
|
||||
//
|
||||
// On entry:
|
||||
// thread state pointer is in a0 ($4)
|
||||
//
|
||||
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind18Registers_mips_n646jumptoEv)
|
||||
.set push
|
||||
.set noat
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
// restore hi and lo
|
||||
ld $8, (8 * 33)($4)
|
||||
mthi $8
|
||||
ld $8, (8 * 34)($4)
|
||||
mtlo $8
|
||||
// r0 is zero
|
||||
ld $1, (8 * 1)($4)
|
||||
ld $2, (8 * 2)($4)
|
||||
ld $3, (8 * 3)($4)
|
||||
// skip a0 for now
|
||||
ld $5, (8 * 5)($4)
|
||||
ld $6, (8 * 6)($4)
|
||||
ld $7, (8 * 7)($4)
|
||||
ld $8, (8 * 8)($4)
|
||||
ld $9, (8 * 9)($4)
|
||||
ld $10, (8 * 10)($4)
|
||||
ld $11, (8 * 11)($4)
|
||||
ld $12, (8 * 12)($4)
|
||||
ld $13, (8 * 13)($4)
|
||||
ld $14, (8 * 14)($4)
|
||||
ld $15, (8 * 15)($4)
|
||||
ld $16, (8 * 16)($4)
|
||||
ld $17, (8 * 17)($4)
|
||||
ld $18, (8 * 18)($4)
|
||||
ld $19, (8 * 19)($4)
|
||||
ld $20, (8 * 20)($4)
|
||||
ld $21, (8 * 21)($4)
|
||||
ld $22, (8 * 22)($4)
|
||||
ld $23, (8 * 23)($4)
|
||||
ld $24, (8 * 24)($4)
|
||||
ld $25, (8 * 25)($4)
|
||||
ld $26, (8 * 26)($4)
|
||||
ld $27, (8 * 27)($4)
|
||||
ld $28, (8 * 28)($4)
|
||||
ld $29, (8 * 29)($4)
|
||||
ld $30, (8 * 30)($4)
|
||||
// load new pc into ra
|
||||
ld $31, (8 * 32)($4)
|
||||
// jump to ra, load a0 in the delay slot
|
||||
jr $31
|
||||
ld $4, (8 * 4)($4)
|
||||
.set pop
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */
|
||||
|
||||
@ -116,6 +116,118 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
|
||||
xorl %eax, %eax # return UNW_ESUCCESS
|
||||
ret
|
||||
|
||||
#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float)
|
||||
|
||||
#
|
||||
# extern int unw_getcontext(unw_context_t* thread_state)
|
||||
#
|
||||
# On entry:
|
||||
# thread_state pointer is in a0 ($4)
|
||||
#
|
||||
DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
|
||||
.set push
|
||||
.set noat
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
sw $1, (4 * 1)($4)
|
||||
sw $2, (4 * 2)($4)
|
||||
sw $3, (4 * 3)($4)
|
||||
sw $4, (4 * 4)($4)
|
||||
sw $5, (4 * 5)($4)
|
||||
sw $6, (4 * 6)($4)
|
||||
sw $7, (4 * 7)($4)
|
||||
sw $8, (4 * 8)($4)
|
||||
sw $9, (4 * 9)($4)
|
||||
sw $10, (4 * 10)($4)
|
||||
sw $11, (4 * 11)($4)
|
||||
sw $12, (4 * 12)($4)
|
||||
sw $13, (4 * 13)($4)
|
||||
sw $14, (4 * 14)($4)
|
||||
sw $15, (4 * 15)($4)
|
||||
sw $16, (4 * 16)($4)
|
||||
sw $17, (4 * 17)($4)
|
||||
sw $18, (4 * 18)($4)
|
||||
sw $19, (4 * 19)($4)
|
||||
sw $20, (4 * 20)($4)
|
||||
sw $21, (4 * 21)($4)
|
||||
sw $22, (4 * 22)($4)
|
||||
sw $23, (4 * 23)($4)
|
||||
sw $24, (4 * 24)($4)
|
||||
sw $25, (4 * 25)($4)
|
||||
sw $26, (4 * 26)($4)
|
||||
sw $27, (4 * 27)($4)
|
||||
sw $28, (4 * 28)($4)
|
||||
sw $29, (4 * 29)($4)
|
||||
sw $30, (4 * 30)($4)
|
||||
sw $31, (4 * 31)($4)
|
||||
# Store return address to pc
|
||||
sw $31, (4 * 32)($4)
|
||||
# hi and lo
|
||||
mfhi $8
|
||||
sw $8, (4 * 33)($4)
|
||||
mflo $8
|
||||
sw $8, (4 * 34)($4)
|
||||
jr $31
|
||||
# return UNW_ESUCCESS
|
||||
or $2, $0, $0
|
||||
.set pop
|
||||
|
||||
#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float)
|
||||
|
||||
#
|
||||
# extern int unw_getcontext(unw_context_t* thread_state)
|
||||
#
|
||||
# On entry:
|
||||
# thread_state pointer is in a0 ($4)
|
||||
#
|
||||
DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
|
||||
.set push
|
||||
.set noat
|
||||
.set noreorder
|
||||
.set nomacro
|
||||
sd $1, (8 * 1)($4)
|
||||
sd $2, (8 * 2)($4)
|
||||
sd $3, (8 * 3)($4)
|
||||
sd $4, (8 * 4)($4)
|
||||
sd $5, (8 * 5)($4)
|
||||
sd $6, (8 * 6)($4)
|
||||
sd $7, (8 * 7)($4)
|
||||
sd $8, (8 * 8)($4)
|
||||
sd $9, (8 * 9)($4)
|
||||
sd $10, (8 * 10)($4)
|
||||
sd $11, (8 * 11)($4)
|
||||
sd $12, (8 * 12)($4)
|
||||
sd $13, (8 * 13)($4)
|
||||
sd $14, (8 * 14)($4)
|
||||
sd $15, (8 * 15)($4)
|
||||
sd $16, (8 * 16)($4)
|
||||
sd $17, (8 * 17)($4)
|
||||
sd $18, (8 * 18)($4)
|
||||
sd $19, (8 * 19)($4)
|
||||
sd $20, (8 * 20)($4)
|
||||
sd $21, (8 * 21)($4)
|
||||
sd $22, (8 * 22)($4)
|
||||
sd $23, (8 * 23)($4)
|
||||
sd $24, (8 * 24)($4)
|
||||
sd $25, (8 * 25)($4)
|
||||
sd $26, (8 * 26)($4)
|
||||
sd $27, (8 * 27)($4)
|
||||
sd $28, (8 * 28)($4)
|
||||
sd $29, (8 * 29)($4)
|
||||
sd $30, (8 * 30)($4)
|
||||
sd $31, (8 * 31)($4)
|
||||
# Store return address to pc
|
||||
sd $31, (8 * 32)($4)
|
||||
# hi and lo
|
||||
mfhi $8
|
||||
sd $8, (8 * 33)($4)
|
||||
mflo $8
|
||||
sd $8, (8 * 34)($4)
|
||||
jr $31
|
||||
# return UNW_ESUCCESS
|
||||
or $2, $0, $0
|
||||
.set pop
|
||||
|
||||
# elif defined(__mips__)
|
||||
|
||||
#
|
||||
|
||||
@ -71,7 +71,7 @@
|
||||
defined(__ppc__) || defined(__ppc64__) || \
|
||||
(!defined(__APPLE__) && defined(__arm__)) || \
|
||||
(defined(__arm64__) || defined(__aarch64__)) || \
|
||||
(defined(__APPLE__) && defined(__mips__))
|
||||
defined(__mips__)
|
||||
#define _LIBUNWIND_BUILD_ZERO_COST_APIS
|
||||
#endif
|
||||
|
||||
|
||||
@ -59,8 +59,12 @@ _LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cursor,
|
||||
# define REGISTER_KIND Registers_arm
|
||||
#elif defined(__or1k__)
|
||||
# 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__)
|
||||
# warning The MIPS architecture is not supported.
|
||||
# warning The MIPS architecture is not supported with this ABI and environment!
|
||||
#else
|
||||
# error Architecture not supported
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user