From 1bd08dd87839ab2318fcc05818bbca7328f09869 Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Fri, 2 Sep 2011 21:13:07 +0000 Subject: [PATCH] Watchpoint work in progress: Add a virtual method GetHardwareWatchpointHit() to the DNBArchProtocol base class which consults the architecture to return the watchpoint hit; otherwise return an invalid index. Add impl. of the method to X86_64 and I386 subclasses, plus reset the debug status register before we resume execution of the inferior thread. llvm-svn: 139034 --- lldb/tools/debugserver/source/DNBArch.h | 1 + .../source/MacOSX/i386/DNBArchImplI386.cpp | 34 +++++++++++++++++++ .../source/MacOSX/i386/DNBArchImplI386.h | 1 + .../MacOSX/x86_64/DNBArchImplX86_64.cpp | 34 +++++++++++++++++++ .../source/MacOSX/x86_64/DNBArchImplX86_64.h | 1 + 5 files changed, 71 insertions(+) diff --git a/lldb/tools/debugserver/source/DNBArch.h b/lldb/tools/debugserver/source/DNBArch.h index b27877120b8c..3b6133d8d989 100644 --- a/lldb/tools/debugserver/source/DNBArch.h +++ b/lldb/tools/debugserver/source/DNBArch.h @@ -79,6 +79,7 @@ public: virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write) { return INVALID_NUB_HW_INDEX; } virtual bool DisableHardwareBreakpoint (uint32_t hw_index) { return false; } virtual bool DisableHardwareWatchpoint (uint32_t hw_index) { return false; } + virtual uint32_t GetHardwareWatchpointHit() { return INVALID_NUB_HW_INDEX; } virtual bool StepNotComplete () { return false; } }; diff --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp index 1761b8bf9a2c..153f1e50bc30 100644 --- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp +++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp @@ -545,6 +545,17 @@ DNBArchImplI386::ThreadWillResume() // This is the primary thread, let the arch do anything it needs EnableHardwareSingleStep(true); } + + // Reset the debug status register before we resume. + kern_return_t kret = GetDBGState(false); + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::ThreadWillResume() GetDBGState() => 0x%8.8x.", kret); + if (kret == KERN_SUCCESS) + { + DBG debug_state = m_state.context.dbg; + ClearWatchpointHits(debug_state); + kret = SetDBGState(); + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::ThreadWillResume() SetDBGState() => 0x%8.8x.", kret); + } } bool @@ -625,6 +636,29 @@ DNBArchImplI386::NotifyException(MachException::Data& exc) return false; } +// Iterate through the debug status register; return the index of the first hit. +uint32_t +DNBArchImplI386::GetHardwareWatchpointHit() +{ + // Read the debug state + kern_return_t kret = GetDBGState(false); + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplI386::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.", kret); + if (kret == KERN_SUCCESS) + { + DBG debug_state = m_state.context.dbg; + uint32_t i, num = NumSupportedHardwareWatchpoints(); + for (i = 0; i < num; ++i) + { + if (IsWatchpointHit(debug_state, i)) + { + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::GetHardwareWatchpointHit() found => %u.", i); + return i; + } + } + } + return INVALID_NUB_HW_INDEX; +} + uint32_t DNBArchImplI386::NumSupportedHardwareWatchpoints() { diff --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h index bb952243d7d6..9a00e004466f 100644 --- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h +++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h @@ -54,6 +54,7 @@ public: virtual uint32_t NumSupportedHardwareWatchpoints(); virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write); virtual bool DisableHardwareWatchpoint (uint32_t hw_break_index); + virtual uint32_t GetHardwareWatchpointHit(); protected: kern_return_t EnableHardwareSingleStep (bool enable); diff --git a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp index 9a536f3a8f3c..014aff9606d6 100644 --- a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp +++ b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp @@ -474,6 +474,17 @@ DNBArchImplX86_64::ThreadWillResume() // This is the primary thread, let the arch do anything it needs EnableHardwareSingleStep(true); } + + // Reset the debug status register before we resume. + kern_return_t kret = GetDBGState(false); + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::ThreadWillResume() GetDBGState() => 0x%8.8x.", kret); + if (kret == KERN_SUCCESS) + { + DBG debug_state = m_state.context.dbg; + ClearWatchpointHits(debug_state); + kret = SetDBGState(); + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::ThreadWillResume() SetDBGState() => 0x%8.8x.", kret); + } } bool @@ -759,6 +770,29 @@ DNBArchImplX86_64::DisableHardwareWatchpoint (uint32_t hw_index) return false; } +// Iterate through the debug status register; return the index of the first hit. +uint32_t +DNBArchImplX86_64::GetHardwareWatchpointHit() +{ + // Read the debug state + kern_return_t kret = GetDBGState(false); + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::GetHardwareWatchpointHit() GetDBGState() => 0x%8.8x.", kret); + if (kret == KERN_SUCCESS) + { + DBG debug_state = m_state.context.dbg; + uint32_t i, num = NumSupportedHardwareWatchpoints(); + for (i = 0; i < num; ++i) + { + if (IsWatchpointHit(debug_state, i)) + { + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::GetHardwareWatchpointHit() found => %u.", i); + return i; + } + } + } + return INVALID_NUB_HW_INDEX; +} + // Set the single step bit in the processor status register. kern_return_t DNBArchImplX86_64::EnableHardwareSingleStep (bool enable) diff --git a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h index 27156e3e8fbb..ac1def91621f 100644 --- a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h +++ b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h @@ -53,6 +53,7 @@ public: virtual uint32_t NumSupportedHardwareWatchpoints(); virtual uint32_t EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write); virtual bool DisableHardwareWatchpoint (uint32_t hw_break_index); + virtual uint32_t GetHardwareWatchpointHit(); protected: kern_return_t EnableHardwareSingleStep (bool enable);