[LLDB][MIPS] Handle false positives for MIPS hardware watchpoints
SUMMARY:
Last 3bits of the watchpoint address are masked by the kernel. For example, n is
at 0x120010d00 and m is 0x120010d04. When a watchpoint is set at m, then watch
exception is generated even when n is read/written. To handle this case, instruction
at PC is emulated to find the base address of the load/store instruction. This address
is then appended to the description of the stop-info packet. Client then reads this
information to check whether the user has set a watchpoint on this address.
Reviewers: jingham, clayborg
Subscribers: nitesh.jain, mohit.bhakkad, sagar, bhushan and lldb-commits
Differential Revision: http://reviews.llvm.org/D11672
llvm-svn: 244864
diff --git a/lldb/source/Target/StopInfo.cpp b/lldb/source/Target/StopInfo.cpp
index 64bbe80..ed8025f 100644
--- a/lldb/source/Target/StopInfo.cpp
+++ b/lldb/source/Target/StopInfo.cpp
@@ -614,10 +614,11 @@
Watchpoint *watchpoint;
};
- StopInfoWatchpoint (Thread &thread, break_id_t watch_id) :
+ StopInfoWatchpoint (Thread &thread, break_id_t watch_id, lldb::addr_t watch_hit_addr) :
StopInfo(thread, watch_id),
m_should_stop(false),
- m_should_stop_is_valid(false)
+ m_should_stop_is_valid(false),
+ m_watch_hit_addr(watch_hit_addr)
{
}
@@ -744,6 +745,21 @@
}
}
+ /*
+ * MIPS: Last 3bits of the watchpoint address are masked by the kernel. For example:
+ * 'n' is at 0x120010d00 and 'm' is 0x120010d04. When a watchpoint is set at 'm', then
+ * watch exception is generated even when 'n' is read/written. To handle this case,
+ * server emulates the instruction at PC and finds the base address of the load/store
+ * instruction and appends it in the description of the stop-info packet. If watchpoint
+ * is not set on this address by user then this do not stop.
+ */
+ if (m_watch_hit_addr != LLDB_INVALID_ADDRESS)
+ {
+ WatchpointSP wp_hit_sp = thread_sp->CalculateTarget()->GetWatchpointList().FindByAddress(m_watch_hit_addr);
+ if (!wp_hit_sp)
+ m_should_stop = false;
+ }
+
if (m_should_stop && wp_sp->GetConditionText() != NULL)
{
// We need to make sure the user sees any parse errors in their condition, so we'll hook the
@@ -856,6 +872,7 @@
private:
bool m_should_stop;
bool m_should_stop_is_valid;
+ lldb::addr_t m_watch_hit_addr;
};
@@ -1153,9 +1170,9 @@
}
StopInfoSP
-StopInfo::CreateStopReasonWithWatchpointID (Thread &thread, break_id_t watch_id)
+StopInfo::CreateStopReasonWithWatchpointID (Thread &thread, break_id_t watch_id, lldb::addr_t watch_hit_addr)
{
- return StopInfoSP (new StopInfoWatchpoint (thread, watch_id));
+ return StopInfoSP (new StopInfoWatchpoint (thread, watch_id, watch_hit_addr));
}
StopInfoSP