aboutsummaryrefslogtreecommitdiff
path: root/gdb/remote.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/remote.c')
-rw-r--r--gdb/remote.c34
1 files changed, 17 insertions, 17 deletions
diff --git a/gdb/remote.c b/gdb/remote.c
index 6208a90..10d2da6 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -893,7 +893,7 @@ public:
bool stopped_by_watchpoint () override;
- bool stopped_data_address (CORE_ADDR *) override;
+ std::vector<CORE_ADDR> stopped_data_addresses () override;
bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override;
@@ -1479,7 +1479,7 @@ struct stop_reply : public notif_event
enum target_stop_reason stop_reason;
- CORE_ADDR watch_data_address;
+ std::vector<CORE_ADDR> watch_data_address;
int core;
};
@@ -1637,9 +1637,13 @@ struct remote_thread_info : public private_thread_info
/* Whether the target stopped for a breakpoint/watchpoint. */
enum target_stop_reason stop_reason = TARGET_STOPPED_BY_NO_REASON;
- /* This is set to the data address of the access causing the target
- to stop for a watchpoint. */
- CORE_ADDR watch_data_address = 0;
+ /* This is set to all the watchpoint addresses of the access causing the
+ target to stop for a watchpoint. For some targets (e.g. AArch64)
+ targets cannot watch small (e.g. single byte) regions, so multiple
+ watchpoints could account for a stop. All possible watchpoint
+ addresses are reported back to GDB, and GDB must select between
+ them. */
+ std::vector<CORE_ADDR> watch_data_address;
/* Get the thread's resume state. */
enum resume_state get_resume_state () const
@@ -6881,7 +6885,7 @@ resume_clear_thread_private_info (struct thread_info *thread)
remote_thread_info *priv = get_remote_thread_info (thread);
priv->stop_reason = TARGET_STOPPED_BY_NO_REASON;
- priv->watch_data_address = 0;
+ priv->watch_data_address.clear ();
}
}
@@ -7497,7 +7501,7 @@ remote_target::remote_stop_ns (ptid_t ptid)
sr->ws.set_stopped (GDB_SIGNAL_0);
sr->arch = tp->inf->arch ();
sr->stop_reason = TARGET_STOPPED_BY_NO_REASON;
- sr->watch_data_address = 0;
+ sr->watch_data_address.clear ();
sr->core = 0;
this->push_stop_reply (std::move (sr));
@@ -8083,7 +8087,7 @@ Packet: '%s'\n"),
{
event->stop_reason = TARGET_STOPPED_BY_WATCHPOINT;
p = unpack_varlen_hex (++p1, &addr);
- event->watch_data_address = (CORE_ADDR) addr;
+ event->watch_data_address.push_back ((CORE_ADDR) addr);
}
else if (strprefix (p, p1, "swbreak"))
{
@@ -11401,20 +11405,16 @@ remote_target::stopped_by_watchpoint ()
== TARGET_STOPPED_BY_WATCHPOINT));
}
-bool
-remote_target::stopped_data_address (CORE_ADDR *addr_p)
+std::vector<CORE_ADDR>
+remote_target::stopped_data_addresses ()
{
struct thread_info *thread = inferior_thread ();
if (thread->priv != NULL
- && (get_remote_thread_info (thread)->stop_reason
- == TARGET_STOPPED_BY_WATCHPOINT))
- {
- *addr_p = get_remote_thread_info (thread)->watch_data_address;
- return true;
- }
+ && (get_remote_thread_info (thread)->stop_reason == TARGET_STOPPED_BY_WATCHPOINT))
+ return get_remote_thread_info (thread)->watch_data_address;
- return false;
+ return {};
}