Changeset View
Changeset View
Standalone View
Standalone View
src/Registers.hpp
Context not available. | |||||
} | } | ||||
} | } | ||||
#endif // _LIBUNWIND_TARGET_MIPS_NEWABI | #endif // _LIBUNWIND_TARGET_MIPS_NEWABI | ||||
#if defined(_LIBUNWIND_TARGET_SPARC) | |||||
/// Registers_sparc holds the register state of a thread in a 32-bit Sparc | |||||
/// process. | |||||
class _LIBUNWIND_HIDDEN Registers_sparc { | |||||
public: | |||||
Registers_sparc(); | |||||
Registers_sparc(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); | |||||
static const char *getRegisterName(int num); | |||||
void jumpto(); | |||||
static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC; } | |||||
uint64_t getSP() const { return _registers.__regs[UNW_SPARC_O6]; } | |||||
void setSP(uint32_t value) { _registers.__regs[UNW_SPARC_O6] = value; } | |||||
uint64_t getIP() const { return _registers.__regs[UNW_SPARC_O7]; } | |||||
compnerd: I guess as long as we don't care about async exceptions where the `%o7` is being twiddled… | |||||
void setIP(uint32_t value) { _registers.__regs[UNW_SPARC_O7] = value; } | |||||
private: | |||||
struct sparc_thread_state_t { | |||||
unsigned int __regs[32]; | |||||
}; | |||||
sparc_thread_state_t _registers; | |||||
}; | |||||
inline Registers_sparc::Registers_sparc(const void *registers) { | |||||
static_assert((check_fit<Registers_sparc, unw_context_t>::does_fit), | |||||
"sparc registers do not fit into unw_context_t"); | |||||
memcpy(&_registers, static_cast<const uint8_t *>(registers), | |||||
sizeof(_registers)); | |||||
} | |||||
inline Registers_sparc::Registers_sparc() { | |||||
memset(&_registers, 0, sizeof(_registers)); | |||||
} | |||||
inline bool Registers_sparc::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_SPARC_I7) | |||||
return true; | |||||
return false; | |||||
} | |||||
inline uint32_t Registers_sparc::getRegister(int regNum) const { | |||||
compnerdUnsubmitted Not Done ReplyInline ActionsSpurious empty line. compnerd: Spurious empty line. | |||||
if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) { | |||||
return _registers.__regs[regNum]; | |||||
} | |||||
switch (regNum) { | |||||
case UNW_REG_IP: | |||||
return _registers.__regs[UNW_SPARC_O7]; | |||||
case UNW_REG_SP: | |||||
return _registers.__regs[UNW_SPARC_O6]; | |||||
} | |||||
_LIBUNWIND_ABORT("unsupported sparc register"); | |||||
} | |||||
inline void Registers_sparc::setRegister(int regNum, uint32_t value) { | |||||
compnerdUnsubmitted Not Done ReplyInline ActionsSpurious empty line compnerd: Spurious empty line | |||||
if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) { | |||||
_registers.__regs[regNum] = value; | |||||
return; | |||||
} | |||||
switch (regNum) { | |||||
case UNW_REG_IP: | |||||
_registers.__regs[UNW_SPARC_O7] = value; | |||||
return; | |||||
case UNW_REG_SP: | |||||
_registers.__regs[UNW_SPARC_O6] = value; | |||||
return; | |||||
} | |||||
_LIBUNWIND_ABORT("unsupported sparc register"); | |||||
} | |||||
inline bool Registers_sparc::validFloatRegister(int regNum) const { | |||||
return false; | |||||
} | |||||
inline double Registers_sparc::getFloatRegister(int regNum) const { | |||||
_LIBUNWIND_ABORT("no Sparc float registers"); | |||||
} | |||||
inline void Registers_sparc::setFloatRegister(int regNum, double value) { | |||||
_LIBUNWIND_ABORT("no Sparc float registers"); | |||||
} | |||||
inline bool Registers_sparc::validVectorRegister(int regNum) const { | |||||
return false; | |||||
} | |||||
inline v128 Registers_sparc::getVectorRegister(int regNum) const { | |||||
_LIBUNWIND_ABORT("no Sparc vector registers"); | |||||
} | |||||
inline void Registers_sparc::setVectorRegister(int regNum, v128 value) { | |||||
_LIBUNWIND_ABORT("no Sparc vector registers"); | |||||
} | |||||
inline const char *Registers_sparc::getRegisterName(int regNum) { | |||||
switch (regNum) { | |||||
case UNW_REG_IP: | |||||
return "pc"; | |||||
case UNW_SPARC_G0: | |||||
return "g0"; | |||||
case UNW_SPARC_G1: | |||||
return "g1"; | |||||
case UNW_SPARC_G2: | |||||
return "g2"; | |||||
case UNW_SPARC_G3: | |||||
return "g3"; | |||||
case UNW_SPARC_G4: | |||||
return "g4"; | |||||
case UNW_SPARC_G5: | |||||
return "g5"; | |||||
case UNW_SPARC_G6: | |||||
return "g6"; | |||||
case UNW_SPARC_G7: | |||||
return "g7"; | |||||
case UNW_SPARC_O0: | |||||
return "o0"; | |||||
case UNW_SPARC_O1: | |||||
return "o1"; | |||||
case UNW_SPARC_O2: | |||||
return "o2"; | |||||
case UNW_SPARC_O3: | |||||
return "o3"; | |||||
case UNW_SPARC_O4: | |||||
return "o4"; | |||||
case UNW_SPARC_O5: | |||||
return "o5"; | |||||
case UNW_REG_SP: | |||||
case UNW_SPARC_O6: | |||||
return "sp"; | |||||
case UNW_SPARC_O7: | |||||
return "o7"; | |||||
case UNW_SPARC_L0: | |||||
return "l0"; | |||||
case UNW_SPARC_L1: | |||||
return "l1"; | |||||
case UNW_SPARC_L2: | |||||
return "l2"; | |||||
case UNW_SPARC_L3: | |||||
return "l3"; | |||||
case UNW_SPARC_L4: | |||||
return "l4"; | |||||
case UNW_SPARC_L5: | |||||
return "l5"; | |||||
case UNW_SPARC_L6: | |||||
return "l6"; | |||||
case UNW_SPARC_L7: | |||||
return "l7"; | |||||
case UNW_SPARC_I0: | |||||
return "i0"; | |||||
case UNW_SPARC_I1: | |||||
return "i1"; | |||||
case UNW_SPARC_I2: | |||||
return "i2"; | |||||
case UNW_SPARC_I3: | |||||
return "i3"; | |||||
case UNW_SPARC_I4: | |||||
return "i4"; | |||||
case UNW_SPARC_I5: | |||||
return "i5"; | |||||
case UNW_SPARC_I6: | |||||
return "fp"; | |||||
case UNW_SPARC_I7: | |||||
return "i7"; | |||||
default: | |||||
return "unknown register"; | |||||
} | |||||
} | |||||
#endif // _LIBUNWIND_TARGET_SPARC | |||||
} // namespace libunwind | } // namespace libunwind | ||||
#endif // __REGISTERS_HPP__ | #endif // __REGISTERS_HPP__ | ||||
Context not available. |
I guess as long as we don't care about async exceptions where the %o7 is being twiddled around for a call or being used as a temporary, this should be okay (IIRC, %o7 needs to be saved before call on SPARC).