9#if defined(__riscv) && __riscv_xlen == 64
26#include <sys/ptrace.h>
35std::unique_ptr<NativeRegisterContextLinux>
36NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux(
39 case llvm::Triple::riscv64: {
44 ioVec.iov_base = &fpr;
45 ioVec.iov_len =
sizeof(fpr);
46 unsigned int regset = NT_FPREGSET;
49 native_thread.
GetID(), ®set,
55 auto register_info_up =
56 std::make_unique<RegisterInfoPOSIX_riscv64>(target_arch, opt_regsets);
57 return std::make_unique<NativeRegisterContextLinux_riscv64>(
58 target_arch, native_thread, std::move(register_info_up));
61 llvm_unreachable(
"have no register context for architecture");
65llvm::Expected<ArchSpec>
66NativeRegisterContextLinux::DetermineArchitecture(
lldb::tid_t tid) {
67 return HostInfo::GetArchitecture();
70NativeRegisterContextLinux_riscv64::NativeRegisterContextLinux_riscv64(
72 std::unique_ptr<RegisterInfoPOSIX_riscv64> register_info_up)
74 register_info_up.release()),
76 ::memset(&m_fpr, 0,
sizeof(m_fpr));
77 ::memset(&m_gpr, 0,
sizeof(m_gpr));
79 m_gpr_is_valid =
false;
80 m_fpu_is_valid =
false;
84NativeRegisterContextLinux_riscv64::GetRegisterInfo()
const {
86 NativeRegisterContextRegisterInfo::GetRegisterInfoInterface());
89uint32_t NativeRegisterContextLinux_riscv64::GetRegisterSetCount()
const {
94NativeRegisterContextLinux_riscv64::GetRegisterSet(uint32_t set_index)
const {
95 return GetRegisterInfo().GetRegisterSet(set_index);
98uint32_t NativeRegisterContextLinux_riscv64::GetUserRegisterCount()
const {
100 for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index)
106NativeRegisterContextLinux_riscv64::ReadRegister(
const RegisterInfo *reg_info,
111 error = Status::FromErrorString(
"reg_info NULL");
118 return Status::FromErrorStringWithFormat(
119 "no lldb regnum for %s",
120 reg_info && reg_info->
name ? reg_info->
name :
"<unknown register>");
127 uint8_t *src =
nullptr;
136 assert(offset < GetGPRSize());
137 src = (uint8_t *)GetGPRBuffer() + offset;
139 }
else if (IsFPR(reg)) {
144 offset = CalculateFprOffset(reg_info);
145 assert(offset < GetFPRSize());
146 src = (uint8_t *)GetFPRBuffer() + offset;
148 return Status::FromErrorString(
149 "failed - register wasn't recognized to be a GPR or an FPR, "
150 "write strategy unknown");
153 eByteOrderLittle,
error);
158Status NativeRegisterContextLinux_riscv64::WriteRegister(
163 return Status::FromErrorString(
"reg_info NULL");
168 return Status::FromErrorStringWithFormat(
169 "no lldb regnum for %s",
170 reg_info->
name !=
nullptr ? reg_info->
name :
"<unknown register>");
177 uint8_t *dst =
nullptr;
186 dst = (uint8_t *)GetGPRBuffer() + reg_info->
byte_offset;
190 }
else if (IsFPR(reg)) {
195 offset = CalculateFprOffset(reg_info);
196 assert(offset < GetFPRSize());
197 dst = (uint8_t *)GetFPRBuffer() + offset;
203 return Status::FromErrorString(
"Failed to write register value");
206Status NativeRegisterContextLinux_riscv64::ReadAllRegisterValues(
216 if (GetRegisterInfo().IsFPPresent()) {
222 uint8_t *dst =
const_cast<uint8_t *
>(data_sp->GetBytes());
223 ::memcpy(dst, GetGPRBuffer(), GetGPRSize());
225 if (GetRegisterInfo().IsFPPresent())
226 ::memcpy(dst, GetFPRBuffer(), GetFPRSize());
231Status NativeRegisterContextLinux_riscv64::WriteAllRegisterValues(
236 error = Status::FromErrorStringWithFormat(
237 "NativeRegisterContextLinux_riscv64::%s invalid data_sp provided",
242 if (data_sp->GetByteSize() != GetRegContextSize()) {
243 error = Status::FromErrorStringWithFormat(
244 "NativeRegisterContextLinux_riscv64::%s data_sp contained mismatched "
245 "data size, expected %" PRIu64
", actual %" PRIu64,
246 __FUNCTION__, GetRegContextSize(), data_sp->GetByteSize());
250 uint8_t *src =
const_cast<uint8_t *
>(data_sp->GetBytes());
251 if (src ==
nullptr) {
252 error = Status::FromErrorStringWithFormat(
253 "NativeRegisterContextLinux_riscv64::%s "
254 "DataBuffer::GetBytes() returned a null "
259 ::memcpy(GetGPRBuffer(), src, GetRegisterInfoInterface().GetGPRSize());
265 src += GetRegisterInfoInterface().GetGPRSize();
267 if (GetRegisterInfo().IsFPPresent()) {
268 ::memcpy(GetFPRBuffer(), src, GetFPRSize());
278size_t NativeRegisterContextLinux_riscv64::GetRegContextSize() {
279 size_t size = GetGPRSize();
280 if (GetRegisterInfo().IsFPPresent())
281 size += GetFPRSize();
285bool NativeRegisterContextLinux_riscv64::IsGPR(
unsigned reg)
const {
286 return GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) ==
290bool NativeRegisterContextLinux_riscv64::IsFPR(
unsigned reg)
const {
291 return GetRegisterInfo().IsFPReg(reg);
294Status NativeRegisterContextLinux_riscv64::ReadGPR() {
301 ioVec.iov_base = GetGPRBuffer();
302 ioVec.iov_len = GetGPRSize();
304 error = ReadRegisterSet(&ioVec, GetGPRSize(), NT_PRSTATUS);
307 m_gpr_is_valid =
true;
312Status NativeRegisterContextLinux_riscv64::WriteGPR() {
318 ioVec.iov_base = GetGPRBuffer();
319 ioVec.iov_len = GetGPRSize();
321 m_gpr_is_valid =
false;
323 return WriteRegisterSet(&ioVec, GetGPRSize(), NT_PRSTATUS);
326Status NativeRegisterContextLinux_riscv64::ReadFPR() {
333 ioVec.iov_base = GetFPRBuffer();
334 ioVec.iov_len = GetFPRSize();
336 error = ReadRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
339 m_fpu_is_valid =
true;
344Status NativeRegisterContextLinux_riscv64::WriteFPR() {
350 ioVec.iov_base = GetFPRBuffer();
351 ioVec.iov_len = GetFPRSize();
353 m_fpu_is_valid =
false;
355 return WriteRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET);
358void NativeRegisterContextLinux_riscv64::InvalidateAllRegisters() {
359 m_gpr_is_valid =
false;
360 m_fpu_is_valid =
false;
363uint32_t NativeRegisterContextLinux_riscv64::CalculateFprOffset(
368std::vector<uint32_t> NativeRegisterContextLinux_riscv64::GetExpeditedRegisters(
370 std::vector<uint32_t> expedited_reg_nums =
371 NativeRegisterContext::GetExpeditedRegisters(expType);
373 return expedited_reg_nums;
static llvm::raw_ostream & error(Stream &strm)
size_t GetRegisterSetCount() const override
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.
lldb::tid_t GetID() const
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.
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::WritableDataBuffer > WritableDataBufferSP
@ eRegisterKindLLDB
lldb's internal register numbers
Every register is described in detail including its name, alternate name (optional),...
uint32_t byte_offset
The byte offset in the register context data where this register's value is found.
uint32_t byte_size
Size in bytes of the register.
uint32_t kinds[lldb::kNumRegisterKinds]
Holds all of the various register numbers for all register kinds.
const char * name
Name of this register, can't be NULL.
Registers are grouped into register sets.
size_t num_registers
The number of registers in REGISTERS array below.