9#if defined(__riscv) && __riscv_xlen == 64
30#define REG_CONTEXT_SIZE (GetGPRSize() + GetFPRSize())
36std::unique_ptr<NativeRegisterContextLinux>
37NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
40 case llvm::Triple::riscv64: {
42 auto register_info_up =
43 std::make_unique<RegisterInfoPOSIX_riscv64>(target_arch, opt_regsets);
44 return std::make_unique<NativeRegisterContextLinux_riscv64>(
45 target_arch, native_thread, std::move(register_info_up));
48 llvm_unreachable(
"have no register context for architecture");
52llvm::Expected<ArchSpec>
53NativeRegisterContextLinux::DetermineArchitecture(
lldb::tid_t tid) {
54 return HostInfo::GetArchitecture();
57NativeRegisterContextLinux_riscv64::NativeRegisterContextLinux_riscv64(
59 std::unique_ptr<RegisterInfoPOSIX_riscv64> register_info_up)
61 register_info_up.release()),
63 ::memset(&m_fpr, 0,
sizeof(m_fpr));
64 ::memset(&m_gpr, 0,
sizeof(m_gpr));
66 m_gpr_is_valid =
false;
67 m_fpu_is_valid =
false;
71NativeRegisterContextLinux_riscv64::GetRegisterInfo()
const {
73 NativeRegisterContextRegisterInfo::GetRegisterInfoInterface());
76uint32_t NativeRegisterContextLinux_riscv64::GetRegisterSetCount()
const {
77 return GetRegisterInfo().GetRegisterSetCount();
81NativeRegisterContextLinux_riscv64::GetRegisterSet(
uint32_t set_index)
const {
82 return GetRegisterInfo().GetRegisterSet(set_index);
85uint32_t NativeRegisterContextLinux_riscv64::GetUserRegisterCount()
const {
87 for (
uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
88 count += GetRegisterSet(set_index)->num_registers;
93NativeRegisterContextLinux_riscv64::ReadRegister(
const RegisterInfo *reg_info,
98 error.SetErrorString(
"reg_info NULL");
105 return Status(
"no lldb regnum for %s", reg_info && reg_info->name
107 :
"<unknown register>");
110 reg_value.
SetUInt(0, reg_info->byte_size);
114 uint8_t *src =
nullptr;
122 offset = reg_info->byte_offset;
123 assert(offset < GetGPRSize());
124 src = (uint8_t *)GetGPRBuffer() + offset;
126 }
else if (IsFPR(reg)) {
131 offset = CalculateFprOffset(reg_info);
132 assert(offset < GetFPRSize());
133 src = (uint8_t *)GetFPRBuffer() + offset;
135 return Status(
"failed - register wasn't recognized to be a GPR or an FPR, "
136 "write strategy unknown");
139 eByteOrderLittle,
error);
144Status NativeRegisterContextLinux_riscv64::WriteRegister(
145 const RegisterInfo *reg_info,
const RegisterValue ®_value) {
149 return Status(
"reg_info NULL");
154 return Status(
"no lldb regnum for %s", reg_info->name !=
nullptr
156 :
"<unknown register>");
163 uint8_t *dst =
nullptr;
171 assert(reg_info->byte_offset < GetGPRSize());
172 dst = (uint8_t *)GetGPRBuffer() + reg_info->byte_offset;
173 ::memcpy(dst, reg_value.
GetBytes(), reg_info->byte_size);
176 }
else if (IsFPR(reg)) {
181 offset = CalculateFprOffset(reg_info);
182 assert(offset < GetFPRSize());
183 dst = (uint8_t *)GetFPRBuffer() + offset;
184 ::memcpy(dst, reg_value.
GetBytes(), reg_info->byte_size);
189 return Status(
"Failed to write register value");
192Status NativeRegisterContextLinux_riscv64::ReadAllRegisterValues(
193 lldb::WritableDataBufferSP &data_sp) {
206 uint8_t *dst =
const_cast<uint8_t *
>(data_sp->GetBytes());
207 ::memcpy(dst, GetGPRBuffer(), GetGPRSize());
209 ::memcpy(dst, GetFPRBuffer(), GetFPRSize());
214Status NativeRegisterContextLinux_riscv64::WriteAllRegisterValues(
215 const lldb::DataBufferSP &data_sp) {
219 error.SetErrorStringWithFormat(
220 "NativeRegisterContextLinux_riscv64::%s invalid data_sp provided",
226 error.SetErrorStringWithFormat(
227 "NativeRegisterContextLinux_riscv64::%s data_sp contained mismatched "
228 "data size, expected %" PRIu64
", actual %" PRIu64,
233 uint8_t *src =
const_cast<uint8_t *
>(data_sp->GetBytes());
234 if (src ==
nullptr) {
235 error.SetErrorStringWithFormat(
"NativeRegisterContextLinux_riscv64::%s "
236 "DataBuffer::GetBytes() returned a null "
241 ::memcpy(GetGPRBuffer(), src, GetRegisterInfoInterface().GetGPRSize());
247 src += GetRegisterInfoInterface().GetGPRSize();
248 ::memcpy(GetFPRBuffer(), src, GetFPRSize());
257bool NativeRegisterContextLinux_riscv64::IsGPR(
unsigned reg)
const {
258 return GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
262bool NativeRegisterContextLinux_riscv64::IsFPR(
unsigned reg)
const {
263 return GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
267Status NativeRegisterContextLinux_riscv64::ReadGPR() {
274 ioVec.iov_base = GetGPRBuffer();
275 ioVec.iov_len = GetGPRSize();
277 error = ReadRegisterSet(&ioVec, GetGPRSize(), NT_PRSTATUS);
280 m_gpr_is_valid =
true;
285Status NativeRegisterContextLinux_riscv64::WriteGPR() {
291 ioVec.iov_base = GetGPRBuffer();
292 ioVec.iov_len = GetGPRSize();
294 m_gpr_is_valid =
false;
296 return WriteRegisterSet(&ioVec, GetGPRSize(), NT_PRSTATUS);
299Status NativeRegisterContextLinux_riscv64::ReadFPR() {
306 ioVec.iov_base = GetFPRBuffer();
307 ioVec.iov_len = GetFPRSize();
309 error = ReadRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
312 m_fpu_is_valid =
true;
317Status NativeRegisterContextLinux_riscv64::WriteFPR() {
323 ioVec.iov_base = GetFPRBuffer();
324 ioVec.iov_len = GetFPRSize();
326 m_fpu_is_valid =
false;
328 return WriteRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
331void NativeRegisterContextLinux_riscv64::InvalidateAllRegisters() {
332 m_gpr_is_valid =
false;
333 m_fpu_is_valid =
false;
336uint32_t NativeRegisterContextLinux_riscv64::CalculateFprOffset(
337 const RegisterInfo *reg_info)
const {
338 return reg_info->byte_offset - GetGPRSize();
341std::vector<uint32_t> NativeRegisterContextLinux_riscv64::GetExpeditedRegisters(
343 std::vector<uint32_t> expedited_reg_nums =
344 NativeRegisterContext::GetExpeditedRegisters(expType);
346 return expedited_reg_nums;
static llvm::raw_ostream & error(Stream &strm)
An architecture specification class.
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
A subclass of DataBuffer that stores a data buffer on the heap.
uint32_t SetFromMemoryData(const RegisterInfo ®_info, const void *src, uint32_t src_len, lldb::ByteOrder src_byte_order, Status &error)
bool SetUInt(uint64_t uint, uint32_t byte_size)
const void * GetBytes() const
#define LLDB_INVALID_INDEX32
#define LLDB_INVALID_REGNUM
A class that represents a running process on the host machine.
@ eRegisterKindLLDB
lldb's internal register numbers