forked from OSchip/llvm-project
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
This commit is contained in:
parent
7aa58f1eea
commit
1bd08dd878
|
@ -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; }
|
||||
};
|
||||
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue