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)) {
97 error.SetError(GetLastError(), eErrorTypeWin32);
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)) {
111 error.SetError(GetLastError(), eErrorTypeWin32);
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.SetErrorString(
"reg_info NULL");
519 error.SetErrorStringWithFormat(
"register \"%s\" is an internal-only lldb "
520 "register, cannot read directly",
526 return GPRRead(reg, reg_value);
529 return FPRRead(reg, reg_value);
531 return Status(
"unimplemented");
534Status NativeRegisterContextWindows_arm::WriteRegister(
535 const RegisterInfo *reg_info,
const RegisterValue ®_value) {
539 error.SetErrorString(
"reg_info NULL");
547 error.SetErrorStringWithFormat(
"register \"%s\" is an internal-only lldb "
548 "register, cannot write directly",
554 return GPRWrite(reg, reg_value);
557 return FPRWrite(reg, reg_value);
559 return Status(
"unimplemented");
562Status NativeRegisterContextWindows_arm::ReadAllRegisterValues(
563 lldb::WritableDataBufferSP &data_sp) {
565 data_sp = std::make_shared<DataBufferHeap>(data_size, 0);
566 ::CONTEXT tls_context;
568 GetThreadContextHelper(GetThreadHandle(), &tls_context, CONTEXT_ALL);
572 uint8_t *dst = data_sp->GetBytes();
573 ::memcpy(dst, &tls_context, data_size);
577Status NativeRegisterContextWindows_arm::WriteAllRegisterValues(
578 const lldb::DataBufferSP &data_sp) {
582 error.SetErrorStringWithFormat(
583 "NativeRegisterContextWindows_arm::%s invalid data_sp provided",
588 if (data_sp->GetByteSize() != data_size) {
589 error.SetErrorStringWithFormatv(
590 "data_sp contained mismatched data size, expected {0}, actual {1}",
591 data_size, data_sp->GetByteSize());
595 ::CONTEXT tls_context;
596 memcpy(&tls_context, data_sp->GetBytes(), data_size);
597 return SetThreadContextHelper(GetThreadHandle(), &tls_context);
600Status NativeRegisterContextWindows_arm::IsWatchpointHit(
uint32_t wp_index,
602 return Status(
"unimplemented");
605Status NativeRegisterContextWindows_arm::GetWatchpointHitIndex(
607 return Status(
"unimplemented");
610Status NativeRegisterContextWindows_arm::IsWatchpointVacant(
uint32_t wp_index,
612 return Status(
"unimplemented");
615Status NativeRegisterContextWindows_arm::SetHardwareWatchpointWithIndex(
617 return Status(
"unimplemented");
620bool NativeRegisterContextWindows_arm::ClearHardwareWatchpoint(
625Status NativeRegisterContextWindows_arm::ClearAllHardwareWatchpoints() {
626 return Status(
"unimplemented");
629uint32_t NativeRegisterContextWindows_arm::SetHardwareWatchpoint(
635NativeRegisterContextWindows_arm::GetWatchpointAddress(
uint32_t wp_index) {
639uint32_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
@ eRegisterKindLLDB
lldb's internal register numbers