diff options
4 files changed, 95 insertions, 27 deletions
diff --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp index 153f1e50bc3..54c339deb3e 100644 --- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp +++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp @@ -625,6 +625,19 @@ DNBArchImplI386::NotifyException(MachException::Data& exc) return true; } } + else if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 1) + { + // exc_code = EXC_I386_SGL + // + // Check whether this corresponds to a watchpoint hit event. + // If yes, set the exc_sub_code to the data break address. + nub_addr_t addr = 0; + uint32_t hw_index = GetHardwareWatchpointHit(addr); + if (hw_index != INVALID_NUB_HW_INDEX) + exc.exc_data[1] = addr; + + return true; + } break; case EXC_SYSCALL: break; @@ -636,29 +649,6 @@ 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() { @@ -790,6 +780,23 @@ DNBArchImplI386::IsWatchpointHit(const DBG &debug_state, uint32_t hw_index) return (debug_state.__dr6 & (1 << hw_index)); } +nub_addr_t +DNBArchImplI386::GetWatchAddress(const DBG &debug_state, uint32_t hw_index) +{ + switch (hw_index) { + case 0: + return debug_state.__dr0; + case 1: + return debug_state.__dr1; + case 2: + return debug_state.__dr2; + case 3: + return debug_state.__dr3; + default: + assert(0 && "invalid hardware register index, must be one of 0, 1, 2, or 3"); + } +} + uint32_t DNBArchImplI386::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write) { @@ -865,6 +872,32 @@ DNBArchImplI386::DisableHardwareWatchpoint (uint32_t hw_index) return false; } +// Iterate through the debug status register; return the index of the first hit. +uint32_t +DNBArchImplI386::GetHardwareWatchpointHit(nub_addr_t &addr) +{ + // 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)) + { + addr = GetWatchAddress(debug_state, i); + DNBLogThreadedIf(LOG_WATCHPOINTS, + "DNBArchImplI386::GetHardwareWatchpointHit() found => %u (addr = %8.8p).", + i, addr); + return i; + } + } + } + return INVALID_NUB_HW_INDEX; +} + // Set the single step bit in the processor status register. kern_return_t DNBArchImplI386::EnableHardwareSingleStep (bool enable) diff --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h index 9a00e004466..bbe3643ecab 100644 --- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h +++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.h @@ -54,7 +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(); + virtual uint32_t GetHardwareWatchpointHit(nub_addr_t &addr); protected: kern_return_t EnableHardwareSingleStep (bool enable); @@ -233,6 +233,7 @@ protected: static bool IsWatchpointVacant(const DBG &debug_state, uint32_t hw_index); static void ClearWatchpointHits(DBG &debug_state); static bool IsWatchpointHit(const DBG &debug_state, uint32_t hw_index); + static nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index); MachThread *m_thread; State m_state; 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 014aff9606d..87400d3d5b8 100644 --- a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp +++ b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp @@ -554,6 +554,19 @@ DNBArchImplX86_64::NotifyException(MachException::Data& exc) return true; } } + else if (exc.exc_data.size() >= 2 && exc.exc_data[0] == 1) + { + // exc_code = EXC_I386_SGL + // + // Check whether this corresponds to a watchpoint hit event. + // If yes, set the exc_sub_code to the data break address. + nub_addr_t addr = 0; + uint32_t hw_index = GetHardwareWatchpointHit(addr); + if (hw_index != INVALID_NUB_HW_INDEX) + exc.exc_data[1] = addr; + + return true; + } break; case EXC_SYSCALL: break; @@ -695,6 +708,23 @@ DNBArchImplX86_64::IsWatchpointHit(const DBG &debug_state, uint32_t hw_index) return (debug_state.__dr6 & (1 << hw_index)); } +nub_addr_t +DNBArchImplX86_64::GetWatchAddress(const DBG &debug_state, uint32_t hw_index) +{ + switch (hw_index) { + case 0: + return debug_state.__dr0; + case 1: + return debug_state.__dr1; + case 2: + return debug_state.__dr2; + case 3: + return debug_state.__dr3; + default: + assert(0 && "invalid hardware register index, must be one of 0, 1, 2, or 3"); + } +} + uint32_t DNBArchImplX86_64::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write) { @@ -772,7 +802,7 @@ DNBArchImplX86_64::DisableHardwareWatchpoint (uint32_t hw_index) // Iterate through the debug status register; return the index of the first hit. uint32_t -DNBArchImplX86_64::GetHardwareWatchpointHit() +DNBArchImplX86_64::GetHardwareWatchpointHit(nub_addr_t &addr) { // Read the debug state kern_return_t kret = GetDBGState(false); @@ -785,7 +815,10 @@ DNBArchImplX86_64::GetHardwareWatchpointHit() { if (IsWatchpointHit(debug_state, i)) { - DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchImplX86_64::GetHardwareWatchpointHit() found => %u.", i); + addr = GetWatchAddress(debug_state, i); + DNBLogThreadedIf(LOG_WATCHPOINTS, + "DNBArchImplX86_64::GetHardwareWatchpointHit() found => %u (addr = %8.8p).", + i, addr); return i; } } 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 ac1def91621..661a9d894a6 100644 --- a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h +++ b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.h @@ -53,7 +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(); + virtual uint32_t GetHardwareWatchpointHit(nub_addr_t &addr); protected: kern_return_t EnableHardwareSingleStep (bool enable); @@ -240,6 +240,7 @@ protected: static bool IsWatchpointVacant(const DBG &debug_state, uint32_t hw_index); static void ClearWatchpointHits(DBG &debug_state); static bool IsWatchpointHit(const DBG &debug_state, uint32_t hw_index); + static nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index); MachThread *m_thread; State m_state; |

