[Lldb-commits] [lldb] [lldb][Windows] WoA HW Watchpoint support in LLDB (PR #108072)
Omair Javaid via lldb-commits
lldb-commits at lists.llvm.org
Wed Oct 9 01:51:39 PDT 2024
https://github.com/omjavaid updated https://github.com/llvm/llvm-project/pull/108072
>From ac61e5a75ce59f7834034494a03b43e81bf02d41 Mon Sep 17 00:00:00 2001
From: Muhammad Omair Javaid <omair.javaid at linaro.org>
Date: Tue, 10 Sep 2024 18:03:29 +0500
Subject: [PATCH 1/4] WoA hardware breakpoint/watchpoint support
---
.../Windows/Common/NativeProcessWindows.cpp | 52 ++++++++---
.../Common/NativeRegisterContextWindows.cpp | 3 -
.../Common/NativeRegisterContextWindows.h | 6 +-
.../NativeRegisterContextWindows_WoW64.cpp | 4 +-
.../NativeRegisterContextWindows_arm.cpp | 4 +-
.../NativeRegisterContextWindows_arm64.cpp | 86 ++++++++++---------
.../NativeRegisterContextWindows_arm64.h | 32 ++-----
.../NativeRegisterContextWindows_i386.cpp | 4 +-
.../NativeRegisterContextWindows_x86_64.cpp | 4 +-
.../Windows/Common/NativeThreadWindows.cpp | 32 +++++++
10 files changed, 135 insertions(+), 92 deletions(-)
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
index 24c9aa6b32659d..87a811123d5de8 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
@@ -491,24 +491,47 @@ NativeProcessWindows::OnDebugException(bool first_chance,
return ExceptionResult::MaskException;
}
case DWORD(STATUS_BREAKPOINT):
- case STATUS_WX86_BREAKPOINT:
- if (FindSoftwareBreakpoint(record.GetExceptionAddress())) {
- LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
- record.GetExceptionAddress());
-
- StopThread(record.GetThreadID(), StopReason::eStopReasonBreakpoint);
-
- if (NativeThreadWindows *stop_thread =
- GetThreadByID(record.GetThreadID())) {
- auto ®ister_context = stop_thread->GetRegisterContext();
+ case STATUS_WX86_BREAKPOINT: {
+ bool breakpoint_hit = false;
+ NativeThreadWindows *stop_thread = GetThreadByID(record.GetThreadID());
+
+ if (stop_thread) {
+ uint32_t hw_id = LLDB_INVALID_INDEX32;
+ auto ®_ctx = stop_thread->GetRegisterContext();
+ reg_ctx.GetHardwareBreakHitIndex(hw_id, record.GetExceptionAddress());
+ if (hw_id != LLDB_INVALID_INDEX32) {
+ breakpoint_hit = true;
+ LLDB_LOG(log, "Hit hardware breakpoint at address {0:x}.",
+ record.GetExceptionAddress());
+ } else if (FindSoftwareBreakpoint(record.GetExceptionAddress())) {
+ breakpoint_hit = true;
+ LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
+ record.GetExceptionAddress());
uint32_t breakpoint_size = GetSoftwareBreakpointPCOffset();
// The current PC is AFTER the BP opcode, on all architectures.
- uint64_t pc = register_context.GetPC() - breakpoint_size;
- register_context.SetPC(pc);
+ uint64_t pc = reg_ctx.GetPC() - breakpoint_size;
+ reg_ctx.SetPC(pc);
}
- SetState(eStateStopped, true);
- return ExceptionResult::MaskException;
+ if (breakpoint_hit) {
+ StopThread(record.GetThreadID(), StopReason::eStopReasonBreakpoint);
+ SetState(eStateStopped, true);
+ return ExceptionResult::MaskException;
+ } else {
+ const std::vector<ULONG_PTR> &args = record.GetExceptionArguments();
+ if (args.size() >= 2) {
+ reg_ctx.GetWatchpointHitIndex(hw_id, args[1]);
+ if (hw_id != LLDB_INVALID_INDEX32) {
+ addr_t wp_pc = record.GetExceptionAddress();
+ std::string desc =
+ formatv("{0} {1} {2}", args[1], hw_id, wp_pc).str();
+ StopThread(record.GetThreadID(), StopReason::eStopReasonWatchpoint,
+ desc);
+ SetState(eStateStopped, true);
+ return ExceptionResult::MaskException;
+ }
+ }
+ }
}
if (!initial_stop) {
@@ -531,6 +554,7 @@ NativeProcessWindows::OnDebugException(bool first_chance,
// Hit the initial stop. Continue the application.
return ExceptionResult::BreakInDebugger;
}
+ }
[[fallthrough]];
default:
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.cpp
index 9128363eaa577a..95be1183abb759 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.cpp
@@ -18,9 +18,6 @@
using namespace lldb;
using namespace lldb_private;
-NativeRegisterContextWindows::NativeRegisterContextWindows(
- NativeThreadProtocol &thread, RegisterInfoInterface *reg_info_interface_p)
- : NativeRegisterContextRegisterInfo(thread, reg_info_interface_p) {}
lldb::thread_t NativeRegisterContextWindows::GetThreadHandle() const {
auto wthread = static_cast<NativeThreadWindows *>(&m_thread);
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.h b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.h
index 841b8547f3e904..d00595251f41de 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.h
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.h
@@ -17,11 +17,9 @@ namespace lldb_private {
class NativeThreadWindows;
-class NativeRegisterContextWindows : public NativeRegisterContextRegisterInfo {
+class NativeRegisterContextWindows
+ : public virtual NativeRegisterContextRegisterInfo {
public:
- NativeRegisterContextWindows(
- NativeThreadProtocol &native_thread,
- RegisterInfoInterface *reg_info_interface_p);
static std::unique_ptr<NativeRegisterContextWindows>
CreateHostNativeRegisterContextWindows(const ArchSpec &target_arch,
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_WoW64.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_WoW64.cpp
index a9642d1c5e48da..069c327ee2f9a6 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_WoW64.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_WoW64.cpp
@@ -88,8 +88,8 @@ static Status SetWoW64ThreadContextHelper(lldb::thread_t thread_handle,
NativeRegisterContextWindows_WoW64::NativeRegisterContextWindows_WoW64(
const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
- : NativeRegisterContextWindows(native_thread,
- CreateRegisterInfoInterface(target_arch)) {}
+ : NativeRegisterContextRegisterInfo(
+ native_thread, CreateRegisterInfoInterface(target_arch)) {}
bool NativeRegisterContextWindows_WoW64::IsGPR(uint32_t reg_index) const {
return (reg_index >= k_first_gpr_i386 && reg_index < k_first_alias_i386);
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm.cpp
index 4209fdf3c7109a..fd8a0c05c1b25c 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm.cpp
@@ -128,8 +128,8 @@ NativeRegisterContextWindows::CreateHostNativeRegisterContextWindows(
NativeRegisterContextWindows_arm::NativeRegisterContextWindows_arm(
const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
- : NativeRegisterContextWindows(native_thread,
- CreateRegisterInfoInterface(target_arch)) {}
+ : NativeRegisterContextRegisterInfo(
+ native_thread, CreateRegisterInfoInterface(target_arch)) {}
bool NativeRegisterContextWindows_arm::IsGPR(uint32_t reg_index) const {
return (reg_index >= k_first_gpr_arm && reg_index <= k_last_gpr_arm);
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp
index 080a9140e36a64..547ddcc4035d46 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp
@@ -10,7 +10,6 @@
#include "NativeRegisterContextWindows_arm64.h"
#include "NativeThreadWindows.h"
-#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
#include "ProcessWindowsLog.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/HostThread.h"
@@ -143,8 +142,14 @@ NativeRegisterContextWindows::CreateHostNativeRegisterContextWindows(
NativeRegisterContextWindows_arm64::NativeRegisterContextWindows_arm64(
const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
- : NativeRegisterContextWindows(native_thread,
- CreateRegisterInfoInterface(target_arch)) {}
+ : NativeRegisterContextRegisterInfo(
+ native_thread, CreateRegisterInfoInterface(target_arch)) {
+ // Currently, there is no API to query the maximum supported hardware
+ // breakpoints and watchpoints on Windows. The values set below are based
+ // on tests conducted on Windows 11 with Snapdragon Elite X hardware.
+ m_max_hwp_supported = 1;
+ m_max_hbp_supported = 6;
+}
bool NativeRegisterContextWindows_arm64::IsGPR(uint32_t reg_index) const {
return (reg_index >= k_first_gpr_arm64 && reg_index <= k_last_gpr_arm64);
@@ -709,48 +714,49 @@ Status NativeRegisterContextWindows_arm64::WriteAllRegisterValues(
return SetThreadContextHelper(GetThreadHandle(), &tls_context);
}
-Status NativeRegisterContextWindows_arm64::IsWatchpointHit(uint32_t wp_index,
- bool &is_hit) {
- return Status::FromErrorString("unimplemented");
-}
-
-Status NativeRegisterContextWindows_arm64::GetWatchpointHitIndex(
- uint32_t &wp_index, lldb::addr_t trap_addr) {
- return Status::FromErrorString("unimplemented");
-}
-
-Status NativeRegisterContextWindows_arm64::IsWatchpointVacant(uint32_t wp_index,
- bool &is_vacant) {
- return Status::FromErrorString("unimplemented");
-}
-
-Status NativeRegisterContextWindows_arm64::SetHardwareWatchpointWithIndex(
- lldb::addr_t addr, size_t size, uint32_t watch_flags, uint32_t wp_index) {
- return Status::FromErrorString("unimplemented");
-}
-
-bool NativeRegisterContextWindows_arm64::ClearHardwareWatchpoint(
- uint32_t wp_index) {
- return false;
-}
+llvm::Error NativeRegisterContextWindows_arm64::ReadHardwareDebugInfo() {
+ ::CONTEXT tls_context;
+ Status error = GetThreadContextHelper(GetThreadHandle(), &tls_context,
+ CONTEXT_DEBUG_REGISTERS);
+ if (error.Fail())
+ return error.ToError();
-Status NativeRegisterContextWindows_arm64::ClearAllHardwareWatchpoints() {
- return Status::FromErrorString("unimplemented");
-}
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ m_hwp_regs[i].address = tls_context.Wvr[i];
+ m_hwp_regs[i].control = tls_context.Wcr[i];
+ }
-uint32_t NativeRegisterContextWindows_arm64::SetHardwareWatchpoint(
- lldb::addr_t addr, size_t size, uint32_t watch_flags) {
- return LLDB_INVALID_INDEX32;
+ for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
+ m_hbp_regs[i].address = tls_context.Bvr[i];
+ m_hbp_regs[i].control = tls_context.Bcr[i];
+ }
+ return llvm::Error::success();
}
-lldb::addr_t
-NativeRegisterContextWindows_arm64::GetWatchpointAddress(uint32_t wp_index) {
- return LLDB_INVALID_ADDRESS;
-}
+llvm::Error
+NativeRegisterContextWindows_arm64::WriteHardwareDebugRegs(DREGType hwbType) {
+ ::CONTEXT tls_context;
+ Status error = GetThreadContextHelper(GetThreadHandle(), &tls_context,
+ CONTEXT_DEBUG_REGISTERS);
+ if (error.Fail())
+ return error.ToError();
+
+ switch (hwbType) {
+ case eDREGTypeWATCH:
+ for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
+ tls_context.Wvr[i] = m_hwp_regs[i].address;
+ tls_context.Wcr[i] = m_hwp_regs[i].control;
+ }
+ break;
+ case eDREGTypeBREAK:
+ for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
+ tls_context.Bvr[i] = m_hbp_regs[i].address;
+ tls_context.Bcr[i] = m_hbp_regs[i].control;
+ }
+ break;
+ }
-uint32_t NativeRegisterContextWindows_arm64::NumSupportedHardwareWatchpoints() {
- // Not implemented
- return 0;
+ return SetThreadContextHelper(GetThreadHandle(), &tls_context).ToError();
}
#endif // defined(__aarch64__) || defined(_M_ARM64)
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.h b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.h
index 88afc1e7b18a2f..e73a6af4cbf805 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.h
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.h
@@ -10,6 +10,8 @@
#ifndef liblldb_NativeRegisterContextWindows_arm64_h_
#define liblldb_NativeRegisterContextWindows_arm64_h_
+#include "Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h"
#include "Plugins/Process/Utility/lldb-arm64-register-enums.h"
#include "NativeRegisterContextWindows.h"
@@ -18,7 +20,9 @@ namespace lldb_private {
class NativeThreadWindows;
-class NativeRegisterContextWindows_arm64 : public NativeRegisterContextWindows {
+class NativeRegisterContextWindows_arm64
+ : public NativeRegisterContextWindows,
+ public NativeRegisterContextDBReg_arm64 {
public:
NativeRegisterContextWindows_arm64(const ArchSpec &target_arch,
NativeThreadProtocol &native_thread);
@@ -37,28 +41,6 @@ class NativeRegisterContextWindows_arm64 : public NativeRegisterContextWindows {
Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override;
- Status IsWatchpointHit(uint32_t wp_index, bool &is_hit) override;
-
- Status GetWatchpointHitIndex(uint32_t &wp_index,
- lldb::addr_t trap_addr) override;
-
- Status IsWatchpointVacant(uint32_t wp_index, bool &is_vacant) override;
-
- bool ClearHardwareWatchpoint(uint32_t wp_index) override;
-
- Status ClearAllHardwareWatchpoints() override;
-
- Status SetHardwareWatchpointWithIndex(lldb::addr_t addr, size_t size,
- uint32_t watch_flags,
- uint32_t wp_index);
-
- uint32_t SetHardwareWatchpoint(lldb::addr_t addr, size_t size,
- uint32_t watch_flags) override;
-
- lldb::addr_t GetWatchpointAddress(uint32_t wp_index) override;
-
- uint32_t NumSupportedHardwareWatchpoints() override;
-
protected:
Status GPRRead(const uint32_t reg, RegisterValue ®_value);
@@ -72,6 +54,10 @@ class NativeRegisterContextWindows_arm64 : public NativeRegisterContextWindows {
bool IsGPR(uint32_t reg_index) const;
bool IsFPR(uint32_t reg_index) const;
+
+ llvm::Error ReadHardwareDebugInfo() override;
+
+ llvm::Error WriteHardwareDebugRegs(DREGType hwbType) override;
};
} // namespace lldb_private
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_i386.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_i386.cpp
index 53df9866793946..7c13759df462da 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_i386.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_i386.cpp
@@ -92,8 +92,8 @@ NativeRegisterContextWindows::CreateHostNativeRegisterContextWindows(
NativeRegisterContextWindows_i386::NativeRegisterContextWindows_i386(
const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
- : NativeRegisterContextWindows(native_thread,
- CreateRegisterInfoInterface(target_arch)) {}
+ : NativeRegisterContextRegisterInfo(
+ native_thread, CreateRegisterInfoInterface(target_arch)) {}
bool NativeRegisterContextWindows_i386::IsGPR(uint32_t reg_index) const {
return (reg_index < k_first_alias_i386);
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_x86_64.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_x86_64.cpp
index 4c59273b845aaa..c54c31e48e4e5f 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_x86_64.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_x86_64.cpp
@@ -110,8 +110,8 @@ NativeRegisterContextWindows::CreateHostNativeRegisterContextWindows(
NativeRegisterContextWindows_x86_64::NativeRegisterContextWindows_x86_64(
const ArchSpec &target_arch, NativeThreadProtocol &native_thread)
- : NativeRegisterContextWindows(native_thread,
- CreateRegisterInfoInterface(target_arch)) {}
+ : NativeRegisterContextRegisterInfo(
+ native_thread, CreateRegisterInfoInterface(target_arch)) {}
bool NativeRegisterContextWindows_x86_64::IsGPR(uint32_t reg_index) const {
return (reg_index >= k_first_gpr_x86_64 && reg_index < k_first_alias_x86_64);
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp
index 8ad59cd1ece887..cade9c09ffb192 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp
@@ -178,9 +178,41 @@ Status NativeThreadWindows::RemoveWatchpoint(lldb::addr_t addr) {
Status NativeThreadWindows::SetHardwareBreakpoint(lldb::addr_t addr,
size_t size) {
+#if defined(__aarch64__) || defined(_M_ARM64)
+ if (m_state == eStateLaunching)
+ return Status();
+
+ Status error = RemoveHardwareBreakpoint(addr);
+ if (error.Fail())
+ return error;
+
+ uint32_t bp_index = m_reg_context_up->SetHardwareBreakpoint(addr, size);
+
+ if (bp_index == LLDB_INVALID_INDEX32)
+ return Status::FromErrorString("Setting hardware breakpoint failed.");
+
+ m_hw_breakpoint_index_map.insert({addr, bp_index});
+
+ return Status();
+#else
return Status::FromErrorString("unimplemented.");
+#endif
}
Status NativeThreadWindows::RemoveHardwareBreakpoint(lldb::addr_t addr) {
+#if defined(__aarch64__) || defined(_M_ARM64)
+ auto bp = m_hw_breakpoint_index_map.find(addr);
+ if (bp == m_hw_breakpoint_index_map.end())
+ return Status();
+
+ uint32_t bp_index = bp->second;
+ if (m_reg_context_up->ClearHardwareBreakpoint(bp_index)) {
+ m_hw_breakpoint_index_map.erase(bp);
+ return Status();
+ }
+
+ return Status::FromErrorString("Clearing hardware breakpoint failed.");
+#else
return Status::FromErrorString("unimplemented.");
+#endif
}
>From 895f09f6f765eaa28e938ff41f994f2495534139 Mon Sep 17 00:00:00 2001
From: Muhammad Omair Javaid <omair.javaid at linaro.org>
Date: Wed, 9 Oct 2024 12:29:39 +0500
Subject: [PATCH 2/4] Remove HW breakpoint support
---
.../Windows/Common/NativeProcessWindows.cpp | 39 +++++++------------
.../NativeRegisterContextWindows_arm64.cpp | 18 ++-------
.../Windows/Common/NativeThreadWindows.cpp | 32 ---------------
3 files changed, 17 insertions(+), 72 deletions(-)
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
index 87a811123d5de8..0c65473d3d3f10 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeProcessWindows.cpp
@@ -491,42 +491,32 @@ NativeProcessWindows::OnDebugException(bool first_chance,
return ExceptionResult::MaskException;
}
case DWORD(STATUS_BREAKPOINT):
- case STATUS_WX86_BREAKPOINT: {
- bool breakpoint_hit = false;
- NativeThreadWindows *stop_thread = GetThreadByID(record.GetThreadID());
+ case STATUS_WX86_BREAKPOINT:
- if (stop_thread) {
- uint32_t hw_id = LLDB_INVALID_INDEX32;
+ if (NativeThreadWindows *stop_thread =
+ GetThreadByID(record.GetThreadID())) {
auto ®_ctx = stop_thread->GetRegisterContext();
- reg_ctx.GetHardwareBreakHitIndex(hw_id, record.GetExceptionAddress());
- if (hw_id != LLDB_INVALID_INDEX32) {
- breakpoint_hit = true;
- LLDB_LOG(log, "Hit hardware breakpoint at address {0:x}.",
- record.GetExceptionAddress());
- } else if (FindSoftwareBreakpoint(record.GetExceptionAddress())) {
- breakpoint_hit = true;
+ const auto exception_addr = record.GetExceptionAddress();
+ const auto thread_id = record.GetThreadID();
+
+ if (FindSoftwareBreakpoint(exception_addr)) {
LLDB_LOG(log, "Hit non-loader breakpoint at address {0:x}.",
- record.GetExceptionAddress());
- uint32_t breakpoint_size = GetSoftwareBreakpointPCOffset();
- // The current PC is AFTER the BP opcode, on all architectures.
- uint64_t pc = reg_ctx.GetPC() - breakpoint_size;
- reg_ctx.SetPC(pc);
- }
+ exception_addr);
- if (breakpoint_hit) {
- StopThread(record.GetThreadID(), StopReason::eStopReasonBreakpoint);
+ reg_ctx.SetPC(reg_ctx.GetPC() - GetSoftwareBreakpointPCOffset());
+ StopThread(thread_id, StopReason::eStopReasonBreakpoint);
SetState(eStateStopped, true);
return ExceptionResult::MaskException;
} else {
const std::vector<ULONG_PTR> &args = record.GetExceptionArguments();
if (args.size() >= 2) {
+ uint32_t hw_id = LLDB_INVALID_INDEX32;
reg_ctx.GetWatchpointHitIndex(hw_id, args[1]);
+
if (hw_id != LLDB_INVALID_INDEX32) {
- addr_t wp_pc = record.GetExceptionAddress();
std::string desc =
- formatv("{0} {1} {2}", args[1], hw_id, wp_pc).str();
- StopThread(record.GetThreadID(), StopReason::eStopReasonWatchpoint,
- desc);
+ formatv("{0} {1} {2}", args[1], hw_id, exception_addr).str();
+ StopThread(thread_id, StopReason::eStopReasonWatchpoint, desc);
SetState(eStateStopped, true);
return ExceptionResult::MaskException;
}
@@ -554,7 +544,6 @@ NativeProcessWindows::OnDebugException(bool first_chance,
// Hit the initial stop. Continue the application.
return ExceptionResult::BreakInDebugger;
}
- }
[[fallthrough]];
default:
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp
index 547ddcc4035d46..fb2997eb37b429 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp
@@ -147,8 +147,8 @@ NativeRegisterContextWindows_arm64::NativeRegisterContextWindows_arm64(
// Currently, there is no API to query the maximum supported hardware
// breakpoints and watchpoints on Windows. The values set below are based
// on tests conducted on Windows 11 with Snapdragon Elite X hardware.
- m_max_hwp_supported = 1;
- m_max_hbp_supported = 6;
+ m_max_hwp_supported = 2;
+ m_max_hbp_supported = 0;
}
bool NativeRegisterContextWindows_arm64::IsGPR(uint32_t reg_index) const {
@@ -726,10 +726,6 @@ llvm::Error NativeRegisterContextWindows_arm64::ReadHardwareDebugInfo() {
m_hwp_regs[i].control = tls_context.Wcr[i];
}
- for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
- m_hbp_regs[i].address = tls_context.Bvr[i];
- m_hbp_regs[i].control = tls_context.Bcr[i];
- }
return llvm::Error::success();
}
@@ -741,19 +737,11 @@ NativeRegisterContextWindows_arm64::WriteHardwareDebugRegs(DREGType hwbType) {
if (error.Fail())
return error.ToError();
- switch (hwbType) {
- case eDREGTypeWATCH:
+ if (hwbType == eDREGTypeWATCH) {
for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
tls_context.Wvr[i] = m_hwp_regs[i].address;
tls_context.Wcr[i] = m_hwp_regs[i].control;
}
- break;
- case eDREGTypeBREAK:
- for (uint32_t i = 0; i < m_max_hbp_supported; i++) {
- tls_context.Bvr[i] = m_hbp_regs[i].address;
- tls_context.Bcr[i] = m_hbp_regs[i].control;
- }
- break;
}
return SetThreadContextHelper(GetThreadHandle(), &tls_context).ToError();
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp
index cade9c09ffb192..8ad59cd1ece887 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeThreadWindows.cpp
@@ -178,41 +178,9 @@ Status NativeThreadWindows::RemoveWatchpoint(lldb::addr_t addr) {
Status NativeThreadWindows::SetHardwareBreakpoint(lldb::addr_t addr,
size_t size) {
-#if defined(__aarch64__) || defined(_M_ARM64)
- if (m_state == eStateLaunching)
- return Status();
-
- Status error = RemoveHardwareBreakpoint(addr);
- if (error.Fail())
- return error;
-
- uint32_t bp_index = m_reg_context_up->SetHardwareBreakpoint(addr, size);
-
- if (bp_index == LLDB_INVALID_INDEX32)
- return Status::FromErrorString("Setting hardware breakpoint failed.");
-
- m_hw_breakpoint_index_map.insert({addr, bp_index});
-
- return Status();
-#else
return Status::FromErrorString("unimplemented.");
-#endif
}
Status NativeThreadWindows::RemoveHardwareBreakpoint(lldb::addr_t addr) {
-#if defined(__aarch64__) || defined(_M_ARM64)
- auto bp = m_hw_breakpoint_index_map.find(addr);
- if (bp == m_hw_breakpoint_index_map.end())
- return Status();
-
- uint32_t bp_index = bp->second;
- if (m_reg_context_up->ClearHardwareBreakpoint(bp_index)) {
- m_hw_breakpoint_index_map.erase(bp);
- return Status();
- }
-
- return Status::FromErrorString("Clearing hardware breakpoint failed.");
-#else
return Status::FromErrorString("unimplemented.");
-#endif
}
>From b5f2913360cc9e0c2a1fc8ce9e7bd526b8418c9e Mon Sep 17 00:00:00 2001
From: Muhammad Omair Javaid <omair.javaid at linaro.org>
Date: Wed, 9 Oct 2024 13:39:17 +0500
Subject: [PATCH 3/4] Run clang-format and fix issues
---
.../Process/Windows/Common/NativeRegisterContextWindows.cpp | 1 -
.../Process/Windows/Common/NativeRegisterContextWindows.h | 1 -
2 files changed, 2 deletions(-)
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.cpp
index 95be1183abb759..effe6df36b5765 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.cpp
@@ -18,7 +18,6 @@
using namespace lldb;
using namespace lldb_private;
-
lldb::thread_t NativeRegisterContextWindows::GetThreadHandle() const {
auto wthread = static_cast<NativeThreadWindows *>(&m_thread);
return wthread->GetHostThread().GetNativeThread().GetSystemHandle();
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.h b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.h
index d00595251f41de..0f9e37dbd9f527 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.h
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows.h
@@ -20,7 +20,6 @@ class NativeThreadWindows;
class NativeRegisterContextWindows
: public virtual NativeRegisterContextRegisterInfo {
public:
-
static std::unique_ptr<NativeRegisterContextWindows>
CreateHostNativeRegisterContextWindows(const ArchSpec &target_arch,
NativeThreadProtocol &native_thread);
>From 2b55cfa0c61abb20424beead641d8a06ded1e845 Mon Sep 17 00:00:00 2001
From: Muhammad Omair Javaid <omair.javaid at linaro.org>
Date: Wed, 9 Oct 2024 13:50:05 +0500
Subject: [PATCH 4/4] Fix typo: only one watchpoint available at max
---
.../Windows/Common/NativeRegisterContextWindows_arm64.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp
index fb2997eb37b429..b63a3040870cd9 100644
--- a/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp
+++ b/lldb/source/Plugins/Process/Windows/Common/NativeRegisterContextWindows_arm64.cpp
@@ -147,7 +147,7 @@ NativeRegisterContextWindows_arm64::NativeRegisterContextWindows_arm64(
// Currently, there is no API to query the maximum supported hardware
// breakpoints and watchpoints on Windows. The values set below are based
// on tests conducted on Windows 11 with Snapdragon Elite X hardware.
- m_max_hwp_supported = 2;
+ m_max_hwp_supported = 1;
m_max_hbp_supported = 0;
}
More information about the lldb-commits
mailing list