Hardware breakpoints for Linux on Arm/AArch64 targets
Please look at below differential link for upstream discussion.
Differential revision: https://reviews.llvm.org/D29669
llvm-svn: 296119
diff --git a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
index a50ea7e..d46a3da 100644
--- a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp
@@ -190,6 +190,38 @@
return Error("Clearing hardware watchpoint failed.");
}
+Error NativeThreadLinux::SetHardwareBreakpoint(lldb::addr_t addr, size_t size) {
+ if (m_state == eStateLaunching)
+ return Error();
+
+ Error error = RemoveHardwareBreakpoint(addr);
+ if (error.Fail())
+ return error;
+
+ NativeRegisterContextSP reg_ctx = GetRegisterContext();
+ uint32_t bp_index = reg_ctx->SetHardwareBreakpoint(addr, size);
+
+ if (bp_index == LLDB_INVALID_INDEX32)
+ return Error("Setting hardware breakpoint failed.");
+
+ m_hw_break_index_map.insert({addr, bp_index});
+ return Error();
+}
+
+Error NativeThreadLinux::RemoveHardwareBreakpoint(lldb::addr_t addr) {
+ auto bp = m_hw_break_index_map.find(addr);
+ if (bp == m_hw_break_index_map.end())
+ return Error();
+
+ uint32_t bp_index = bp->second;
+ if (GetRegisterContext()->ClearHardwareBreakpoint(bp_index)) {
+ m_hw_break_index_map.erase(bp);
+ return Error();
+ }
+
+ return Error("Clearing hardware breakpoint failed.");
+}
+
Error NativeThreadLinux::Resume(uint32_t signo) {
const StateType new_state = StateType::eStateRunning;
MaybeLogStateChange(new_state);
@@ -211,6 +243,18 @@
}
}
+ // Set all active hardware breakpoint on all threads.
+ if (m_hw_break_index_map.empty()) {
+ NativeProcessLinux &process = GetProcess();
+
+ const auto &hw_breakpoint_map = process.GetHardwareBreakpointMap();
+ GetRegisterContext()->ClearAllHardwareBreakpoints();
+ for (const auto &pair : hw_breakpoint_map) {
+ const auto &bp = pair.second;
+ SetHardwareBreakpoint(bp.m_addr, bp.m_size);
+ }
+ }
+
intptr_t data = 0;
if (signo != LLDB_INVALID_SIGNAL_NUMBER)