diff options
Diffstat (limited to 'gdb/remote.c')
-rw-r--r-- | gdb/remote.c | 34 |
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 {}; } |