Add stubs for RISC-V ISA so libunwind can be compiled.
Reviewed by: emaste Sponsored by: DARPA, AFRL Sponsored by: HEIF5 Differential Revision: https://reviews.freebsd.org/D5035
This commit is contained in:
parent
87eab6d83d
commit
a75e74c454
@ -295,6 +295,77 @@ enum {
|
||||
UNW_PPC_SPEFSCR = 112
|
||||
};
|
||||
|
||||
// 64-bit RISC-V registers
|
||||
enum {
|
||||
UNW_RISCV_X0 = 0,
|
||||
UNW_RISCV_X1 = 1,
|
||||
UNW_RISCV_RA = 1,
|
||||
UNW_RISCV_X2 = 2,
|
||||
UNW_RISCV_SP = 2,
|
||||
UNW_RISCV_X3 = 3,
|
||||
UNW_RISCV_X4 = 4,
|
||||
UNW_RISCV_X5 = 5,
|
||||
UNW_RISCV_X6 = 6,
|
||||
UNW_RISCV_X7 = 7,
|
||||
UNW_RISCV_X8 = 8,
|
||||
UNW_RISCV_X9 = 9,
|
||||
UNW_RISCV_X10 = 10,
|
||||
UNW_RISCV_X11 = 11,
|
||||
UNW_RISCV_X12 = 12,
|
||||
UNW_RISCV_X13 = 13,
|
||||
UNW_RISCV_X14 = 14,
|
||||
UNW_RISCV_X15 = 15,
|
||||
UNW_RISCV_X16 = 16,
|
||||
UNW_RISCV_X17 = 17,
|
||||
UNW_RISCV_X18 = 18,
|
||||
UNW_RISCV_X19 = 19,
|
||||
UNW_RISCV_X20 = 20,
|
||||
UNW_RISCV_X21 = 21,
|
||||
UNW_RISCV_X22 = 22,
|
||||
UNW_RISCV_X23 = 23,
|
||||
UNW_RISCV_X24 = 24,
|
||||
UNW_RISCV_X25 = 25,
|
||||
UNW_RISCV_X26 = 26,
|
||||
UNW_RISCV_X27 = 27,
|
||||
UNW_RISCV_X28 = 28,
|
||||
UNW_RISCV_X29 = 29,
|
||||
UNW_RISCV_X30 = 30,
|
||||
UNW_RISCV_X31 = 31,
|
||||
// reserved block
|
||||
UNW_RISCV_D0 = 64,
|
||||
UNW_RISCV_D1 = 65,
|
||||
UNW_RISCV_D2 = 66,
|
||||
UNW_RISCV_D3 = 67,
|
||||
UNW_RISCV_D4 = 68,
|
||||
UNW_RISCV_D5 = 69,
|
||||
UNW_RISCV_D6 = 70,
|
||||
UNW_RISCV_D7 = 71,
|
||||
UNW_RISCV_D8 = 72,
|
||||
UNW_RISCV_D9 = 73,
|
||||
UNW_RISCV_D10 = 74,
|
||||
UNW_RISCV_D11 = 75,
|
||||
UNW_RISCV_D12 = 76,
|
||||
UNW_RISCV_D13 = 77,
|
||||
UNW_RISCV_D14 = 78,
|
||||
UNW_RISCV_D15 = 79,
|
||||
UNW_RISCV_D16 = 80,
|
||||
UNW_RISCV_D17 = 81,
|
||||
UNW_RISCV_D18 = 82,
|
||||
UNW_RISCV_D19 = 83,
|
||||
UNW_RISCV_D20 = 84,
|
||||
UNW_RISCV_D21 = 85,
|
||||
UNW_RISCV_D22 = 86,
|
||||
UNW_RISCV_D23 = 87,
|
||||
UNW_RISCV_D24 = 88,
|
||||
UNW_RISCV_D25 = 89,
|
||||
UNW_RISCV_D26 = 90,
|
||||
UNW_RISCV_D27 = 91,
|
||||
UNW_RISCV_D28 = 92,
|
||||
UNW_RISCV_D29 = 93,
|
||||
UNW_RISCV_D30 = 94,
|
||||
UNW_RISCV_D31 = 95,
|
||||
};
|
||||
|
||||
// 64-bit ARM64 registers
|
||||
enum {
|
||||
UNW_ARM64_X0 = 0,
|
||||
|
@ -1024,6 +1024,264 @@ inline const char *Registers_ppc::getRegisterName(int regNum) {
|
||||
|
||||
}
|
||||
|
||||
/// Registers_riscv holds the register state of a thread in a 64-bit RISC-V
|
||||
/// process.
|
||||
class _LIBUNWIND_HIDDEN Registers_riscv {
|
||||
public:
|
||||
Registers_riscv();
|
||||
Registers_riscv(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 95; }
|
||||
|
||||
uint64_t getSP() const { return _registers.__x[2]; }
|
||||
void setSP(uint64_t value) { _registers.__x[2] = value; }
|
||||
uint64_t getIP() const { return _registers.__x[1]; }
|
||||
void setIP(uint64_t value) { _registers.__x[1] = value; }
|
||||
|
||||
private:
|
||||
struct GPRs {
|
||||
uint64_t __x[32]; // x0-x31
|
||||
};
|
||||
|
||||
GPRs _registers;
|
||||
double _vectorHalfRegisters[32];
|
||||
// Currently only the lower double in 128-bit vectore registers
|
||||
// is perserved during unwinding. We could define new register
|
||||
// numbers (> 96) which mean whole vector registers, then this
|
||||
// struct would need to change to contain whole vector registers.
|
||||
};
|
||||
|
||||
inline Registers_riscv::Registers_riscv(const void *registers) {
|
||||
static_assert(sizeof(Registers_riscv) < sizeof(unw_context_t),
|
||||
"riscv registers do not fit into unw_context_t");
|
||||
memcpy(&_registers, registers, sizeof(_registers));
|
||||
static_assert(sizeof(GPRs) == 0x100,
|
||||
"expected VFP registers to be at offset 256");
|
||||
memcpy(_vectorHalfRegisters,
|
||||
static_cast<const uint8_t *>(registers) + sizeof(GPRs),
|
||||
sizeof(_vectorHalfRegisters));
|
||||
}
|
||||
|
||||
inline Registers_riscv::Registers_riscv() {
|
||||
memset(&_registers, 0, sizeof(_registers));
|
||||
memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
|
||||
}
|
||||
|
||||
inline bool Registers_riscv::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 > 95)
|
||||
return false;
|
||||
if ((regNum > 31) && (regNum < 64))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline uint64_t Registers_riscv::getRegister(int regNum) const {
|
||||
if (regNum == UNW_REG_IP)
|
||||
return _registers.__x[1];
|
||||
if (regNum == UNW_REG_SP)
|
||||
return _registers.__x[2];
|
||||
if ((regNum >= 0) && (regNum < 32))
|
||||
return _registers.__x[regNum];
|
||||
_LIBUNWIND_ABORT("unsupported riscv register");
|
||||
}
|
||||
|
||||
inline void Registers_riscv::setRegister(int regNum, uint64_t value) {
|
||||
if (regNum == UNW_REG_IP)
|
||||
_registers.__x[1] = value;
|
||||
else if (regNum == UNW_REG_SP)
|
||||
_registers.__x[2] = value;
|
||||
else if ((regNum >= 0) && (regNum < 32))
|
||||
_registers.__x[regNum] = value;
|
||||
else
|
||||
_LIBUNWIND_ABORT("unsupported riscv register");
|
||||
}
|
||||
|
||||
inline const char *Registers_riscv::getRegisterName(int regNum) {
|
||||
switch (regNum) {
|
||||
case UNW_REG_IP:
|
||||
return "ra";
|
||||
case UNW_REG_SP:
|
||||
return "sp";
|
||||
case UNW_RISCV_X0:
|
||||
return "x0";
|
||||
case UNW_RISCV_X1:
|
||||
return "ra";
|
||||
case UNW_RISCV_X2:
|
||||
return "sp";
|
||||
case UNW_RISCV_X3:
|
||||
return "x3";
|
||||
case UNW_RISCV_X4:
|
||||
return "x4";
|
||||
case UNW_RISCV_X5:
|
||||
return "x5";
|
||||
case UNW_RISCV_X6:
|
||||
return "x6";
|
||||
case UNW_RISCV_X7:
|
||||
return "x7";
|
||||
case UNW_RISCV_X8:
|
||||
return "x8";
|
||||
case UNW_RISCV_X9:
|
||||
return "x9";
|
||||
case UNW_RISCV_X10:
|
||||
return "x10";
|
||||
case UNW_RISCV_X11:
|
||||
return "x11";
|
||||
case UNW_RISCV_X12:
|
||||
return "x12";
|
||||
case UNW_RISCV_X13:
|
||||
return "x13";
|
||||
case UNW_RISCV_X14:
|
||||
return "x14";
|
||||
case UNW_RISCV_X15:
|
||||
return "x15";
|
||||
case UNW_RISCV_X16:
|
||||
return "x16";
|
||||
case UNW_RISCV_X17:
|
||||
return "x17";
|
||||
case UNW_RISCV_X18:
|
||||
return "x18";
|
||||
case UNW_RISCV_X19:
|
||||
return "x19";
|
||||
case UNW_RISCV_X20:
|
||||
return "x20";
|
||||
case UNW_RISCV_X21:
|
||||
return "x21";
|
||||
case UNW_RISCV_X22:
|
||||
return "x22";
|
||||
case UNW_RISCV_X23:
|
||||
return "x23";
|
||||
case UNW_RISCV_X24:
|
||||
return "x24";
|
||||
case UNW_RISCV_X25:
|
||||
return "x25";
|
||||
case UNW_RISCV_X26:
|
||||
return "x26";
|
||||
case UNW_RISCV_X27:
|
||||
return "x27";
|
||||
case UNW_RISCV_X28:
|
||||
return "x28";
|
||||
case UNW_RISCV_X29:
|
||||
return "x29";
|
||||
case UNW_RISCV_X30:
|
||||
return "x30";
|
||||
case UNW_RISCV_X31:
|
||||
return "x31";
|
||||
case UNW_RISCV_D0:
|
||||
return "d0";
|
||||
case UNW_RISCV_D1:
|
||||
return "d1";
|
||||
case UNW_RISCV_D2:
|
||||
return "d2";
|
||||
case UNW_RISCV_D3:
|
||||
return "d3";
|
||||
case UNW_RISCV_D4:
|
||||
return "d4";
|
||||
case UNW_RISCV_D5:
|
||||
return "d5";
|
||||
case UNW_RISCV_D6:
|
||||
return "d6";
|
||||
case UNW_RISCV_D7:
|
||||
return "d7";
|
||||
case UNW_RISCV_D8:
|
||||
return "d8";
|
||||
case UNW_RISCV_D9:
|
||||
return "d9";
|
||||
case UNW_RISCV_D10:
|
||||
return "d10";
|
||||
case UNW_RISCV_D11:
|
||||
return "d11";
|
||||
case UNW_RISCV_D12:
|
||||
return "d12";
|
||||
case UNW_RISCV_D13:
|
||||
return "d13";
|
||||
case UNW_RISCV_D14:
|
||||
return "d14";
|
||||
case UNW_RISCV_D15:
|
||||
return "d15";
|
||||
case UNW_RISCV_D16:
|
||||
return "d16";
|
||||
case UNW_RISCV_D17:
|
||||
return "d17";
|
||||
case UNW_RISCV_D18:
|
||||
return "d18";
|
||||
case UNW_RISCV_D19:
|
||||
return "d19";
|
||||
case UNW_RISCV_D20:
|
||||
return "d20";
|
||||
case UNW_RISCV_D21:
|
||||
return "d21";
|
||||
case UNW_RISCV_D22:
|
||||
return "d22";
|
||||
case UNW_RISCV_D23:
|
||||
return "d23";
|
||||
case UNW_RISCV_D24:
|
||||
return "d24";
|
||||
case UNW_RISCV_D25:
|
||||
return "d25";
|
||||
case UNW_RISCV_D26:
|
||||
return "d26";
|
||||
case UNW_RISCV_D27:
|
||||
return "d27";
|
||||
case UNW_RISCV_D28:
|
||||
return "d28";
|
||||
case UNW_RISCV_D29:
|
||||
return "d29";
|
||||
case UNW_RISCV_D30:
|
||||
return "d30";
|
||||
case UNW_RISCV_D31:
|
||||
return "d31";
|
||||
default:
|
||||
return "unknown register";
|
||||
}
|
||||
}
|
||||
|
||||
inline bool Registers_riscv::validFloatRegister(int regNum) const {
|
||||
if (regNum < UNW_RISCV_D0)
|
||||
return false;
|
||||
if (regNum > UNW_RISCV_D31)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline double Registers_riscv::getFloatRegister(int regNum) const {
|
||||
assert(validFloatRegister(regNum));
|
||||
return _vectorHalfRegisters[regNum - UNW_RISCV_D0];
|
||||
}
|
||||
|
||||
inline void Registers_riscv::setFloatRegister(int regNum, double value) {
|
||||
assert(validFloatRegister(regNum));
|
||||
_vectorHalfRegisters[regNum - UNW_RISCV_D0] = value;
|
||||
}
|
||||
|
||||
inline bool Registers_riscv::validVectorRegister(int) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline v128 Registers_riscv::getVectorRegister(int) const {
|
||||
_LIBUNWIND_ABORT("no riscv vector register support yet");
|
||||
}
|
||||
|
||||
inline void Registers_riscv::setVectorRegister(int, v128) {
|
||||
_LIBUNWIND_ABORT("no riscv vector register support yet");
|
||||
}
|
||||
|
||||
|
||||
/// Registers_arm64 holds the register state of a thread in a 64-bit arm
|
||||
/// process.
|
||||
|
@ -562,6 +562,10 @@ class UnwindCursor : public AbstractUnwindCursor{
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_or1k &) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_riscv &) const {
|
||||
return 0;
|
||||
}
|
||||
#endif // _LIBUNWIND_SUPPORT_DWARF_UNWIND
|
||||
|
||||
|
||||
|
@ -478,4 +478,8 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv)
|
||||
l.jr r9
|
||||
l.nop
|
||||
|
||||
#elif defined(__riscv__)
|
||||
|
||||
/* RISCVTODO */
|
||||
|
||||
#endif
|
||||
|
@ -463,4 +463,9 @@ DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
|
||||
l.sw 116(r3), r29
|
||||
l.sw 120(r3), r30
|
||||
l.sw 124(r3), r31
|
||||
|
||||
#elif defined(__riscv__)
|
||||
|
||||
/* RISCVTODO */
|
||||
|
||||
#endif
|
||||
|
@ -74,7 +74,8 @@
|
||||
#define _LIBUNWIND_BUILD_ZERO_COST_APIS (defined(__i386__) || \
|
||||
defined(__x86_64__) || \
|
||||
defined(__arm__) || \
|
||||
defined(__aarch64__))
|
||||
defined(__aarch64__) || \
|
||||
defined(__riscv__))
|
||||
#define _LIBUNWIND_BUILD_SJLJ_APIS 0
|
||||
#define _LIBUNWIND_SUPPORT_FRAME_APIS (defined(__i386__) || \
|
||||
defined(__x86_64__))
|
||||
|
@ -66,6 +66,9 @@ _LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cursor,
|
||||
context, LocalAddressSpace::sThisAddressSpace);
|
||||
#elif defined(__mips__)
|
||||
#warning The MIPS architecture is not supported.
|
||||
#elif defined(__riscv__)
|
||||
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_riscv>(
|
||||
context, LocalAddressSpace::sThisAddressSpace);
|
||||
#else
|
||||
#error Architecture not supported
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user