diff options
author | Johnny Chen <johnny.chen@apple.com> | 2012-03-23 01:24:52 +0000 |
---|---|---|
committer | Johnny Chen <johnny.chen@apple.com> | 2012-03-23 01:24:52 +0000 |
commit | 3f8140a6d8c5cfbc75a6c2c38aba64c55f9c3a6e (patch) | |
tree | 7d8b62021403cf3a86302c95e8e96c6d939f08da /lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp | |
parent | aaaec7cf1f89c47e957c660a37fe6f944f251941 (diff) | |
download | bcm5719-llvm-3f8140a6d8c5cfbc75a6c2c38aba64c55f9c3a6e.tar.gz bcm5719-llvm-3f8140a6d8c5cfbc75a6c2c38aba64c55f9c3a6e.zip |
Make arm debugserver handle setting a watchpoint on, for example, (uint64_t)variable.
We do this by delegating to two available Watchpoint Register Pairs (wvr, wcr). With
each pair handling the 4 bytes of (uint64_t)variable.
llvm-svn: 153300
Diffstat (limited to 'lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp')
-rw-r--r-- | lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp | 117 |
1 files changed, 79 insertions, 38 deletions
diff --git a/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp b/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp index c64ca01c217..1ed63ee975d 100644 --- a/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp +++ b/lldb/tools/debugserver/source/MacOSX/arm/DNBArchImpl.cpp @@ -366,7 +366,16 @@ DNBArchMachARM::ThreadWillResume() { if (m_watchpoint_hw_index >= 0) { - DisableHardwareWatchpoint(m_watchpoint_hw_index); + kern_return_t kret = GetDBGState(false); + if (kret == KERN_SUCCESS && !IsWatchpointEnabled(m_state.dbg, m_watchpoint_hw_index)) { + // The watchpoint might have been disabled by the user. We don't need to do anything at all + // to enable hardware single stepping. + m_watchpoint_did_occur = false; + m_watchpoint_hw_index = -1; + return; + } + + DisableHardwareWatchpoint0(m_watchpoint_hw_index, true); DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::ThreadWillResume() DisableHardwareWatchpoint(%d) called", m_watchpoint_hw_index); @@ -403,7 +412,7 @@ DNBArchMachARM::ThreadDidStop() { if (m_watchpoint_did_occur && m_watchpoint_hw_index >= 0) { - EnableHardwareWatchpoint(m_watchpoint_hw_index); + EnableHardwareWatchpoint0(m_watchpoint_hw_index, true); m_watchpoint_resume_single_step_enabled = false; m_watchpoint_did_occur = false; m_watchpoint_hw_index = -1; @@ -2383,6 +2392,10 @@ DNBArchMachARM::DisableHardwareBreakpoint (uint32_t hw_index) return false; } +// This stores the lo->hi mappings. It's safe to initialize to all 0's +// since hi > lo and therefore LoHi[i] cannot be 0. +static uint32_t LoHi[16] = { 0 }; + uint32_t DNBArchMachARM::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool read, bool write) { @@ -2398,7 +2411,24 @@ DNBArchMachARM::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool if (read == false && write == false) return INVALID_NUB_HW_INDEX; - // Can't watch more than 4 bytes per WVR/WCR pair + // Divide-and-conquer for size == 8. + if (size == 8) + { + uint32_t lo = EnableHardwareWatchpoint(addr, 4, read, write); + if (lo == INVALID_NUB_HW_INDEX) + return INVALID_NUB_HW_INDEX; + uint32_t hi = EnableHardwareWatchpoint(addr+4, 4, read, write); + if (hi == INVALID_NUB_HW_INDEX) + { + DisableHardwareWatchpoint(lo); + return INVALID_NUB_HW_INDEX; + } + // Tag thsi lo->hi mapping in our database. + LoHi[lo] = hi; + return lo; + } + + // Otherwise, can't watch more than 4 bytes per WVR/WCR pair if (size > 4) return INVALID_NUB_HW_INDEX; @@ -2475,57 +2505,68 @@ DNBArchMachARM::EnableHardwareWatchpoint (nub_addr_t addr, nub_size_t size, bool } bool -DNBArchMachARM::EnableHardwareWatchpoint (uint32_t hw_index) +DNBArchMachARM::EnableHardwareWatchpoint0 (uint32_t hw_index, bool Delegate) { kern_return_t kret = GetDBGState(false); + if (kret != KERN_SUCCESS) + return false; const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); - if (kret == KERN_SUCCESS) - { - if (hw_index < num_hw_points) - { - m_state.dbg.__wcr[hw_index] |= (nub_addr_t)WCR_ENABLE; - DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x WCR%u = 0x%8.8x", - hw_index, - hw_index, - m_state.dbg.__wvr[hw_index], - hw_index, - m_state.dbg.__wcr[hw_index]); - - kret = SetDBGState(); + if (hw_index >= num_hw_points) + return false; - if (kret == KERN_SUCCESS) - return true; - } + if (Delegate && LoHi[hw_index]) { + // Enable lo and hi watchpoint hardware indexes. + return EnableHardwareWatchpoint0(hw_index, false) && + EnableHardwareWatchpoint0(LoHi[hw_index], false); } - return false; + + m_state.dbg.__wcr[hw_index] |= (nub_addr_t)WCR_ENABLE; + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::EnableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x WCR%u = 0x%8.8x", + hw_index, + hw_index, + m_state.dbg.__wvr[hw_index], + hw_index, + m_state.dbg.__wcr[hw_index]); + + kret = SetDBGState(); + + return (kret == KERN_SUCCESS); } bool DNBArchMachARM::DisableHardwareWatchpoint (uint32_t hw_index) { + return DisableHardwareWatchpoint0(hw_index, true); +} +bool +DNBArchMachARM::DisableHardwareWatchpoint0 (uint32_t hw_index, bool Delegate) +{ kern_return_t kret = GetDBGState(false); + if (kret != KERN_SUCCESS) + return false; const uint32_t num_hw_points = NumSupportedHardwareWatchpoints(); - if (kret == KERN_SUCCESS) - { - if (hw_index < num_hw_points) - { - m_state.dbg.__wcr[hw_index] &= ~((nub_addr_t)WCR_ENABLE); - DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::DisableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x WCR%u = 0x%8.8x", - hw_index, - hw_index, - m_state.dbg.__wvr[hw_index], - hw_index, - m_state.dbg.__wcr[hw_index]); - - kret = SetDBGState(); + if (hw_index >= num_hw_points) + return false; - if (kret == KERN_SUCCESS) - return true; - } + if (Delegate && LoHi[hw_index]) { + // Disable lo and hi watchpoint hardware indexes. + return DisableHardwareWatchpoint0(hw_index, false) && + DisableHardwareWatchpoint0(LoHi[hw_index], false); } - return false; + + m_state.dbg.__wcr[hw_index] &= ~((nub_addr_t)WCR_ENABLE); + DNBLogThreadedIf(LOG_WATCHPOINTS, "DNBArchMachARM::DisableHardwareWatchpoint( %u ) - WVR%u = 0x%8.8x WCR%u = 0x%8.8x", + hw_index, + hw_index, + m_state.dbg.__wvr[hw_index], + hw_index, + m_state.dbg.__wcr[hw_index]); + + kret = SetDBGState(); + + return (kret == KERN_SUCCESS); } // {0} -> __bvr[16], {0} -> __bcr[16], {0} --> __wvr[16], {0} -> __wcr{16} |