9#if defined(__arm__) || defined(_M_ARM)
22#include "llvm/ADT/STLExtras.h"
27#define REG_CONTEXT_SIZE sizeof(::CONTEXT)
39 "g_gpr_regnums_arm has wrong number of register infos");
41static const uint32_t g_fpr_regnums_arm[] = {
66static_assert(((
sizeof g_fpr_regnums_arm /
sizeof g_fpr_regnums_arm[0]) - 1) ==
68 "g_fpu_regnums_arm has wrong number of register infos");
73 {
"Floating Point Registers",
"fpr", std::size(g_fpr_regnums_arm) - 1,
82CreateRegisterInfoInterface(
const ArchSpec &target_arch) {
83 assert((HostInfo::GetArchitecture().GetAddressByteSize() == 4) &&
84 "Register setting path assumes this is a 32-bit host");
90 const DWORD control_flag) {
94 memset(context_ptr, 0,
sizeof(::CONTEXT));
95 context_ptr->ContextFlags = control_flag;
96 if (!::GetThreadContext(thread_handle, context_ptr)) {
98 LLDB_LOG(log,
"{0} GetThreadContext failed with error {1}", __FUNCTION__,
106 PCONTEXT context_ptr) {
107 Log *log =
GetLog(WindowsLog::Registers);
110 if (!::SetThreadContext(thread_handle, context_ptr)) {
112 LLDB_LOG(log,
"{0} SetThreadContext failed with error {1}", __FUNCTION__,
119std::unique_ptr<NativeRegisterContextWindows>
120NativeRegisterContextWindows::CreateHostNativeRegisterContextWindows(
125 return std::make_unique<NativeRegisterContextWindows_arm>(target_arch,
129NativeRegisterContextWindows_arm::NativeRegisterContextWindows_arm(
132 CreateRegisterInfoInterface(target_arch)) {}
134bool NativeRegisterContextWindows_arm::IsGPR(uint32_t reg_index)
const {
135 return (reg_index >= k_first_gpr_arm && reg_index <= k_last_gpr_arm);
138bool NativeRegisterContextWindows_arm::IsFPR(uint32_t reg_index)
const {
139 return (reg_index >= k_first_fpr_arm && reg_index <= k_last_fpr_arm);
142uint32_t NativeRegisterContextWindows_arm::GetRegisterSetCount()
const {
147NativeRegisterContextWindows_arm::GetRegisterSet(uint32_t set_index)
const {
153Status NativeRegisterContextWindows_arm::GPRRead(
const uint32_t reg,
155 ::CONTEXT tls_context;
156 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_INTEGER;
158 GetThreadContextHelper(GetThreadHandle(), &tls_context, context_flag);
220NativeRegisterContextWindows_arm::GPRWrite(
const uint32_t reg,
222 ::CONTEXT tls_context;
223 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_INTEGER;
224 auto thread_handle = GetThreadHandle();
226 GetThreadContextHelper(thread_handle, &tls_context, context_flag);
284 return SetThreadContextHelper(thread_handle, &tls_context);
287Status NativeRegisterContextWindows_arm::FPRRead(
const uint32_t reg,
289 ::CONTEXT tls_context;
290 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_FLOATING_POINT;
292 GetThreadContextHelper(GetThreadHandle(), &tls_context, context_flag);
329 reg_value.
SetUInt32(tls_context.S[reg - fpu_s0_arm],
330 RegisterValue::eTypeFloat);
365 reg_value.
SetUInt64(tls_context.D[reg - fpu_d0_arm],
366 RegisterValue::eTypeDouble);
385 reg_value.
SetBytes(&tls_context.Q[reg - fpu_q0_arm], 16,
386 endian::InlHostByteOrder());
398NativeRegisterContextWindows_arm::FPRWrite(
const uint32_t reg,
400 ::CONTEXT tls_context;
401 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_FLOATING_POINT;
402 auto thread_handle = GetThreadHandle();
404 GetThreadContextHelper(thread_handle, &tls_context, context_flag);
495 memcpy(&tls_context.Q[reg - fpu_q0_arm], reg_value.
GetBytes(), 16);
503 return SetThreadContextHelper(thread_handle, &tls_context);
507NativeRegisterContextWindows_arm::ReadRegister(
const RegisterInfo *reg_info,
511 error = Status::FromErrorString(
"reg_info NULL");
519 error = Status::FromErrorStringWithFormat(
520 "register \"%s\" is an internal-only lldb "
521 "register, cannot read directly",
527 return GPRRead(reg, reg_value);
530 return FPRRead(reg, reg_value);
532 return Status::FromErrorString(
"unimplemented");
535Status NativeRegisterContextWindows_arm::WriteRegister(
540 error = Status::FromErrorString(
"reg_info NULL");
548 error = Status::FromErrorStringWithFormat(
549 "register \"%s\" is an internal-only lldb "
550 "register, cannot write directly",
556 return GPRWrite(reg, reg_value);
559 return FPRWrite(reg, reg_value);
561 return Status::FromErrorString(
"unimplemented");
564Status NativeRegisterContextWindows_arm::ReadAllRegisterValues(
567 data_sp = std::make_shared<DataBufferHeap>(data_size, 0);
568 ::CONTEXT tls_context;
570 GetThreadContextHelper(GetThreadHandle(), &tls_context, CONTEXT_ALL);
574 uint8_t *dst = data_sp->GetBytes();
575 ::memcpy(dst, &tls_context, data_size);
579Status NativeRegisterContextWindows_arm::WriteAllRegisterValues(
584 error = Status::FromErrorStringWithFormat(
585 "NativeRegisterContextWindows_arm::%s invalid data_sp provided",
590 if (data_sp->GetByteSize() != data_size) {
591 error = Status::FromErrorStringWithFormatv(
592 "data_sp contained mismatched data size, expected {0}, actual {1}",
593 data_size, data_sp->GetByteSize());
597 ::CONTEXT tls_context;
598 memcpy(&tls_context, data_sp->GetBytes(), data_size);
599 return SetThreadContextHelper(GetThreadHandle(), &tls_context);
602Status NativeRegisterContextWindows_arm::IsWatchpointHit(uint32_t wp_index,
604 return Status::FromErrorString(
"unimplemented");
607Status NativeRegisterContextWindows_arm::GetWatchpointHitIndex(
609 return Status::FromErrorString(
"unimplemented");
612Status NativeRegisterContextWindows_arm::IsWatchpointVacant(uint32_t wp_index,
614 return Status::FromErrorString(
"unimplemented");
617Status NativeRegisterContextWindows_arm::SetHardwareWatchpointWithIndex(
618 lldb::addr_t addr,
size_t size, uint32_t watch_flags, uint32_t wp_index) {
619 return Status::FromErrorString(
"unimplemented");
622bool NativeRegisterContextWindows_arm::ClearHardwareWatchpoint(
627Status NativeRegisterContextWindows_arm::ClearAllHardwareWatchpoints() {
628 return Status::FromErrorString(
"unimplemented");
631uint32_t NativeRegisterContextWindows_arm::SetHardwareWatchpoint(
637NativeRegisterContextWindows_arm::GetWatchpointAddress(uint32_t wp_index) {
641uint32_t NativeRegisterContextWindows_arm::NumSupportedHardwareWatchpoints() {
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
constexpr size_t k_num_register_sets
static const uint32_t g_gpr_regnums_arm[]
static const RegisterSet g_reg_sets_arm[k_num_register_sets]
An architecture specification class.
RegisterInfo interface to patch RegisterInfo structure for archs.
void SetUInt64(uint64_t uint, Type t=eTypeUInt64)
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
void SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order)
const void * GetBytes() const
uint32_t GetAsUInt32(uint32_t fail_value=UINT32_MAX, bool *success_ptr=nullptr) const
void SetUInt32(uint32_t uint, Type t=eTypeUInt32)
#define LLDB_INVALID_INDEX32
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_REGNUM
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
@ k_num_fpr_registers_arm
@ k_num_gpr_registers_arm
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 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.