summaryrefslogtreecommitdiffstats
path: root/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp')
-rw-r--r--lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp79
1 files changed, 56 insertions, 23 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)
OpenPOWER on IntegriCloud