diff options
author | Omair Javaid <omair.javaid@linaro.org> | 2017-02-24 13:27:31 +0000 |
---|---|---|
committer | Omair Javaid <omair.javaid@linaro.org> | 2017-02-24 13:27:31 +0000 |
commit | d5ffbad275c8800fcd4e0c1d5efe813352d5977e (patch) | |
tree | bd9128ea1c1057a32bfd04c9e480c2597ebed628 /lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp | |
parent | d224c08efcccd1f9db912c30774ffbab5c3be063 (diff) | |
download | bcm5719-llvm-d5ffbad275c8800fcd4e0c1d5efe813352d5977e.tar.gz bcm5719-llvm-d5ffbad275c8800fcd4e0c1d5efe813352d5977e.zip |
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
Diffstat (limited to 'lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp')
-rw-r--r-- | lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp index a50ea7e3d0a..d46a3da3a59 100644 --- a/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp +++ b/lldb/source/Plugins/Process/Linux/NativeThreadLinux.cpp @@ -190,6 +190,38 @@ Error NativeThreadLinux::RemoveWatchpoint(lldb::addr_t addr) { 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 @@ Error NativeThreadLinux::Resume(uint32_t signo) { } } + // 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) |