9#if defined(__aarch64__) || defined(_M_ARM64)
22#include "llvm/ADT/STLExtras.h"
27#define REG_CONTEXT_SIZE sizeof(::CONTEXT)
51 "g_gpr_regnums_arm64 has wrong number of register infos");
53static const uint32_t g_fpr_regnums_arm64[] = {
82static_assert(((
sizeof g_fpr_regnums_arm64 /
sizeof g_fpr_regnums_arm64[0]) -
84 "g_fpu_regnums_arm64 has wrong number of register infos");
89 {
"Floating Point Registers",
"fpr", std::size(g_fpr_regnums_arm64) - 1,
98CreateRegisterInfoInterface(
const ArchSpec &target_arch) {
99 assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
100 "Register setting path assumes this is a 64-bit host");
106 PCONTEXT context_ptr,
107 const DWORD control_flag) {
108 Log *log =
GetLog(WindowsLog::Registers);
111 memset(context_ptr, 0,
sizeof(::CONTEXT));
112 context_ptr->ContextFlags = control_flag;
113 if (!::GetThreadContext(thread_handle, context_ptr)) {
114 error.SetError(GetLastError(), eErrorTypeWin32);
115 LLDB_LOG(log,
"{0} GetThreadContext failed with error {1}", __FUNCTION__,
123 PCONTEXT context_ptr) {
124 Log *log =
GetLog(WindowsLog::Registers);
127 if (!::SetThreadContext(thread_handle, context_ptr)) {
128 error.SetError(GetLastError(), eErrorTypeWin32);
129 LLDB_LOG(log,
"{0} SetThreadContext failed with error {1}", __FUNCTION__,
136std::unique_ptr<NativeRegisterContextWindows>
137NativeRegisterContextWindows::CreateHostNativeRegisterContextWindows(
140 return std::make_unique<NativeRegisterContextWindows_arm64>(target_arch,
144NativeRegisterContextWindows_arm64::NativeRegisterContextWindows_arm64(
147 CreateRegisterInfoInterface(target_arch)) {}
149bool NativeRegisterContextWindows_arm64::IsGPR(uint32_t reg_index)
const {
150 return (reg_index >= k_first_gpr_arm64 && reg_index <= k_last_gpr_arm64);
153bool NativeRegisterContextWindows_arm64::IsFPR(uint32_t reg_index)
const {
154 return (reg_index >= k_first_fpr_arm64 && reg_index <= k_last_fpr_arm64);
157uint32_t NativeRegisterContextWindows_arm64::GetRegisterSetCount()
const {
162NativeRegisterContextWindows_arm64::GetRegisterSet(uint32_t set_index)
const {
168Status NativeRegisterContextWindows_arm64::GPRRead(
const uint32_t reg,
170 ::CONTEXT tls_context;
171 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_INTEGER;
173 GetThreadContextHelper(GetThreadHandle(), &tls_context, context_flag);
207 reg_value.
SetUInt64(tls_context.X[reg - gpr_x0_arm64]);
256 static_cast<uint32_t
>(tls_context.X[reg - gpr_w0_arm64] & 0xffffffff));
264NativeRegisterContextWindows_arm64::GPRWrite(
const uint32_t reg,
266 ::CONTEXT tls_context;
267 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_INTEGER;
268 auto thread_handle = GetThreadHandle();
270 GetThreadContextHelper(thread_handle, &tls_context, context_flag);
356 return SetThreadContextHelper(thread_handle, &tls_context);
359Status NativeRegisterContextWindows_arm64::FPRRead(
const uint32_t reg,
361 ::CONTEXT tls_context;
362 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_FLOATING_POINT;
364 GetThreadContextHelper(GetThreadHandle(), &tls_context, context_flag);
401 reg_value.
SetBytes(tls_context.V[reg - fpu_v0_arm64].B, 16,
402 endian::InlHostByteOrder());
437 reg_value.
SetFloat(tls_context.V[reg - fpu_s0_arm64].S[0]);
472 reg_value.
SetDouble(tls_context.V[reg - fpu_d0_arm64].D[0]);
488NativeRegisterContextWindows_arm64::FPRWrite(
const uint32_t reg,
490 ::CONTEXT tls_context;
491 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_FLOATING_POINT;
492 auto thread_handle = GetThreadHandle();
494 GetThreadContextHelper(thread_handle, &tls_context, context_flag);
531 memcpy(tls_context.V[reg - fpu_v0_arm64].B, reg_value.
GetBytes(), 16);
613 return SetThreadContextHelper(thread_handle, &tls_context);
617NativeRegisterContextWindows_arm64::ReadRegister(
const RegisterInfo *reg_info,
621 error.SetErrorString(
"reg_info NULL");
629 error.SetErrorStringWithFormat(
"register \"%s\" is an internal-only lldb "
630 "register, cannot read directly",
636 return GPRRead(reg, reg_value);
639 return FPRRead(reg, reg_value);
641 return Status(
"unimplemented");
644Status NativeRegisterContextWindows_arm64::WriteRegister(
649 error.SetErrorString(
"reg_info NULL");
657 error.SetErrorStringWithFormat(
"register \"%s\" is an internal-only lldb "
658 "register, cannot write directly",
664 return GPRWrite(reg, reg_value);
667 return FPRWrite(reg, reg_value);
669 return Status(
"unimplemented");
672Status NativeRegisterContextWindows_arm64::ReadAllRegisterValues(
675 data_sp = std::make_shared<DataBufferHeap>(data_size, 0);
676 ::CONTEXT tls_context;
678 GetThreadContextHelper(GetThreadHandle(), &tls_context, CONTEXT_ALL);
682 uint8_t *dst = data_sp->GetBytes();
683 ::memcpy(dst, &tls_context, data_size);
687Status NativeRegisterContextWindows_arm64::WriteAllRegisterValues(
692 error.SetErrorStringWithFormat(
693 "NativeRegisterContextWindows_arm64::%s invalid data_sp provided",
698 if (data_sp->GetByteSize() != data_size) {
699 error.SetErrorStringWithFormatv(
700 "data_sp contained mismatched data size, expected {0}, actual {1}",
701 data_size, data_sp->GetByteSize());
705 ::CONTEXT tls_context;
706 memcpy(&tls_context, data_sp->GetBytes(), data_size);
707 return SetThreadContextHelper(GetThreadHandle(), &tls_context);
710Status NativeRegisterContextWindows_arm64::IsWatchpointHit(uint32_t wp_index,
712 return Status(
"unimplemented");
715Status NativeRegisterContextWindows_arm64::GetWatchpointHitIndex(
717 return Status(
"unimplemented");
720Status NativeRegisterContextWindows_arm64::IsWatchpointVacant(uint32_t wp_index,
722 return Status(
"unimplemented");
725Status NativeRegisterContextWindows_arm64::SetHardwareWatchpointWithIndex(
726 lldb::addr_t addr,
size_t size, uint32_t watch_flags, uint32_t wp_index) {
727 return Status(
"unimplemented");
730bool NativeRegisterContextWindows_arm64::ClearHardwareWatchpoint(
735Status NativeRegisterContextWindows_arm64::ClearAllHardwareWatchpoints() {
736 return Status(
"unimplemented");
739uint32_t NativeRegisterContextWindows_arm64::SetHardwareWatchpoint(
745NativeRegisterContextWindows_arm64::GetWatchpointAddress(uint32_t wp_index) {
749uint32_t NativeRegisterContextWindows_arm64::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_arm64[]
static const lldb_private::RegisterSet g_reg_sets_arm64[k_num_register_sets]
An architecture specification class.
RegisterInfo interface to patch RegisterInfo structure for archs.
void SetUInt64(uint64_t uint, Type t=eTypeUInt64)
double GetAsDouble(double fail_value=0.0, bool *success_ptr=nullptr) const
uint64_t GetAsUInt64(uint64_t fail_value=UINT64_MAX, bool *success_ptr=nullptr) const
float GetAsFloat(float fail_value=0.0f, 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_gpr_registers_arm64
@ k_num_fpr_registers_arm64
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.