9#if defined(__aarch64__) || defined(_M_ARM64)
21#include "llvm/ADT/STLExtras.h"
26#define REG_CONTEXT_SIZE sizeof(::CONTEXT)
50 "g_gpr_regnums_arm64 has wrong number of register infos");
52static const uint32_t g_fpr_regnums_arm64[] = {
81static_assert(((
sizeof g_fpr_regnums_arm64 /
sizeof g_fpr_regnums_arm64[0]) -
83 "g_fpu_regnums_arm64 has wrong number of register infos");
88 {
"Floating Point Registers",
"fpr", std::size(g_fpr_regnums_arm64) - 1,
97CreateRegisterInfoInterface(
const ArchSpec &target_arch) {
98 assert((HostInfo::GetArchitecture().GetAddressByteSize() == 8) &&
99 "Register setting path assumes this is a 64-bit host");
105 PCONTEXT context_ptr,
106 const DWORD control_flag) {
110 memset(context_ptr, 0,
sizeof(::CONTEXT));
111 context_ptr->ContextFlags = control_flag;
112 if (!::GetThreadContext(thread_handle, context_ptr)) {
114 LLDB_LOG(log,
"{0} GetThreadContext failed with error {1}", __FUNCTION__,
122 PCONTEXT context_ptr) {
126 if (!::SetThreadContext(thread_handle, context_ptr)) {
128 LLDB_LOG(log,
"{0} SetThreadContext failed with error {1}", __FUNCTION__,
135std::unique_ptr<NativeRegisterContextWindows>
139 return std::make_unique<NativeRegisterContextWindows_arm64>(target_arch,
143NativeRegisterContextWindows_arm64::NativeRegisterContextWindows_arm64(
146 native_thread, CreateRegisterInfoInterface(target_arch)) {
150 m_max_hwp_supported = 1;
153bool NativeRegisterContextWindows_arm64::IsGPR(uint32_t reg_index)
const {
157bool NativeRegisterContextWindows_arm64::IsFPR(uint32_t reg_index)
const {
161uint32_t NativeRegisterContextWindows_arm64::GetRegisterSetCount()
const {
166NativeRegisterContextWindows_arm64::GetRegisterSet(uint32_t set_index)
const {
172Status NativeRegisterContextWindows_arm64::GPRRead(
const uint32_t reg,
174 ::CONTEXT tls_context;
175 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_INTEGER;
177 GetThreadContextHelper(GetThreadHandle(), &tls_context, context_flag);
260 static_cast<uint32_t
>(tls_context.X[reg -
gpr_w0_arm64] & 0xffffffff));
268NativeRegisterContextWindows_arm64::GPRWrite(
const uint32_t reg,
270 ::CONTEXT tls_context;
271 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_INTEGER;
272 auto thread_handle = GetThreadHandle();
274 GetThreadContextHelper(thread_handle, &tls_context, context_flag);
360 return SetThreadContextHelper(thread_handle, &tls_context);
363Status NativeRegisterContextWindows_arm64::FPRRead(
const uint32_t reg,
365 ::CONTEXT tls_context;
366 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_FLOATING_POINT;
368 GetThreadContextHelper(GetThreadHandle(), &tls_context, context_flag);
492NativeRegisterContextWindows_arm64::FPRWrite(
const uint32_t reg,
494 ::CONTEXT tls_context;
495 DWORD context_flag = CONTEXT_CONTROL | CONTEXT_FLOATING_POINT;
496 auto thread_handle = GetThreadHandle();
498 GetThreadContextHelper(thread_handle, &tls_context, context_flag);
617 return SetThreadContextHelper(thread_handle, &tls_context);
621NativeRegisterContextWindows_arm64::ReadRegister(
const RegisterInfo *reg_info,
634 "register \"%s\" is an internal-only lldb "
635 "register, cannot read directly",
641 return GPRRead(reg, reg_value);
644 return FPRRead(reg, reg_value);
649Status NativeRegisterContextWindows_arm64::WriteRegister(
663 "register \"%s\" is an internal-only lldb "
664 "register, cannot write directly",
670 return GPRWrite(reg, reg_value);
673 return FPRWrite(reg, reg_value);
678Status NativeRegisterContextWindows_arm64::ReadAllRegisterValues(
681 data_sp = std::make_shared<DataBufferHeap>(data_size, 0);
682 ::CONTEXT tls_context;
684 GetThreadContextHelper(GetThreadHandle(), &tls_context, CONTEXT_ALL);
688 uint8_t *dst = data_sp->GetBytes();
689 ::memcpy(dst, &tls_context, data_size);
693Status NativeRegisterContextWindows_arm64::WriteAllRegisterValues(
699 "NativeRegisterContextWindows_arm64::%s invalid data_sp provided",
704 if (data_sp->GetByteSize() != data_size) {
706 "data_sp contained mismatched data size, expected {0}, actual {1}",
707 data_size, data_sp->GetByteSize());
711 ::CONTEXT tls_context;
712 memcpy(&tls_context, data_sp->GetBytes(), data_size);
713 return SetThreadContextHelper(GetThreadHandle(), &tls_context);
716llvm::Error NativeRegisterContextWindows_arm64::ReadHardwareDebugInfo() {
717 ::CONTEXT tls_context;
718 Status error = GetThreadContextHelper(GetThreadHandle(), &tls_context,
719 CONTEXT_DEBUG_REGISTERS);
721 return error.ToError();
723 for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
724 m_hwp_regs[i].address = tls_context.Wvr[i];
725 m_hwp_regs[i].control = tls_context.Wcr[i];
728 return llvm::Error::success();
732NativeRegisterContextWindows_arm64::WriteHardwareDebugRegs(DREGType hwbType) {
733 ::CONTEXT tls_context;
734 Status error = GetThreadContextHelper(GetThreadHandle(), &tls_context,
735 CONTEXT_DEBUG_REGISTERS);
737 return error.ToError();
739 if (hwbType == eDREGTypeWATCH) {
740 for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
741 tls_context.Wvr[i] = m_hwp_regs[i].address;
742 tls_context.Wcr[i] = m_hwp_regs[i].control;
746 return SetThreadContextHelper(GetThreadHandle(), &tls_context).ToError();
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]
static std::unique_ptr< NativeRegisterContextWindows > CreateHostNativeRegisterContextWindows(const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
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)
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
static Status FromErrorString(const char *str)
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
#define LLDB_INVALID_REGNUM
lldb::ByteOrder InlHostByteOrder()
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
@ eErrorTypeWin32
Standard Win32 error codes.
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.