From: Thiago Jung Bauermann Date: Sun, 27 Apr 2025 03:04:11 +0000 (-0300) Subject: gdb: remote: Save the stop reply packet from vRun and use it X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=db72c78647c9c9a16658478b078ebed4ebcf3aa3;p=thirdparty%2Fbinutils-gdb.git gdb: remote: Save the stop reply packet from vRun and use it The reply to the vRun packet is a stop reply, which may contain expedited registers. They are currently ignored and GDB will very soon have to request them again when setting up the new inferior. It's more efficient to save the reply and supply the expedited registers when a new regcache is created. This will also be useful for target description parameters, in the case when those parameters are derived from expedited registers. --- diff --git a/gdb/process-stratum-target.h b/gdb/process-stratum-target.h index 2545d4875bf..60fd5cc3e9e 100644 --- a/gdb/process-stratum-target.h +++ b/gdb/process-stratum-target.h @@ -54,6 +54,11 @@ public: gdbarch. */ struct gdbarch *thread_architecture (ptid_t ptid) override; + /* Supply to REGCACHE registers which may be already available when it's + first created. */ + virtual void supply_early_registers (regcache *regcache) + {}; + /* Default implementations for process_stratum targets. Return true if there's a selected inferior, false otherwise. */ bool has_all_memory () override; diff --git a/gdb/regcache.c b/gdb/regcache.c index a78dcd84bf6..ce99d4f5979 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -638,6 +638,8 @@ get_thread_arch_regcache (inferior *inf_for_target_calls, ptid_t ptid, constructor explicitly instead of implicitly. */ ptid_regc_map.insert (std::make_pair (ptid, regcache_up (new_regcache))); + proc_target->supply_early_registers (new_regcache); + return new_regcache; } diff --git a/gdb/remote.c b/gdb/remote.c index ae2404589ad..831c1d595ec 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -690,6 +690,9 @@ public: /* data */ immediately, so queue is not needed for them. */ std::vector stop_reply_queue; + /* Contains the stop reply packet when first starting the inferior. */ + gdb::char_vector first_stop_reply; + /* FIXME: cagney/1999-09-23: Even though getpkt was called with ``forever'' still use the normal timeout mechanism. This is currently used by the ASYNC code to guarantee that target reads @@ -1225,6 +1228,8 @@ public: /* Remote specific methods. */ ptid_t select_thread_for_ambiguous_stop_reply (const struct target_waitstatus &status); + void supply_early_registers (regcache *regcache) override; + void remote_notice_new_inferior (ptid_t currthread, bool executing); void print_one_stopped_thread (thread_info *thread); @@ -1424,6 +1429,9 @@ private: bool start_remote_1 (int from_tty, int extended_p); + void supply_expedited_registers (regcache *regcache, + std::vector &expedited_regs); + /* The remote state. Don't reference this directly. Use the get_remote_state method instead. */ remote_state m_remote_state; @@ -8585,6 +8593,21 @@ remote_target::select_thread_for_ambiguous_stop_reply return first_resumed_thread->ptid; } +/* Supply the contents of EXPEDITED_REGS to REGCACHE. */ + +void +remote_target::supply_expedited_registers (regcache *regcache, + std::vector &expedited_regs) +{ + remote_state *rs = get_remote_state (); + + for (cached_reg_t ® : expedited_regs) + { + regcache->raw_supply (reg.num, reg.data); + rs->last_seen_expedited_registers.insert (reg.num); + } +} + /* Called when it is decided that STOP_REPLY holds the info of the event that is to be returned to the core. This function always destroys STOP_REPLY. */ @@ -8623,12 +8646,7 @@ remote_target::process_stop_reply (stop_reply_up stop_reply, regcache *regcache = get_thread_arch_regcache (find_inferior_ptid (this, ptid), ptid, stop_reply->arch); - - for (cached_reg_t ® : stop_reply->regcache) - { - regcache->raw_supply (reg.num, reg.data); - rs->last_seen_expedited_registers.insert (reg.num); - } + supply_expedited_registers (regcache, stop_reply->regcache); } remote_thread_info *remote_thr = get_remote_thread_info (this, ptid); @@ -8654,6 +8672,28 @@ remote_target::process_stop_reply (stop_reply_up stop_reply, return ptid; } +/* See gdb/process-stratum-target.h. */ + +void +remote_target::supply_early_registers (regcache *regcache) +{ + remote_state *rs = get_remote_state (); + + if (rs->first_stop_reply.empty ()) + return; + + notif_event_up reply + = remote_notif_parse (this, ¬if_client_stop, + rs->first_stop_reply.data ()); + std::vector &expedited_regs + = ((struct stop_reply *) reply.get ())->regcache; + + if (!expedited_regs.empty ()) + supply_expedited_registers (regcache, expedited_regs); + + rs->first_stop_reply.clear (); +} + /* The non-stop mode version of target_wait. */ ptid_t @@ -11032,7 +11072,6 @@ extended_remote_target::create_inferior (const char *exec_file, char **env, int from_tty) { int run_worked; - char *stop_reply; struct remote_state *rs = get_remote_state (); const char *remote_exec_file = get_remote_exec_file (); @@ -11065,7 +11104,10 @@ Remote replied unexpectedly while setting startup-with-shell: %s"), /* Now restart the remote server. */ run_worked = extended_remote_run (args) != -1; - if (!run_worked) + if (run_worked) + /* vRun's success return is a stop reply. */ + rs->first_stop_reply = rs->buf; + else { /* vRun was not supported. Fail if we need it to do what the user requested. */ @@ -11078,9 +11120,7 @@ Remote replied unexpectedly while setting startup-with-shell: %s"), extended_remote_restart (); } - /* vRun's success return is a stop reply. */ - stop_reply = run_worked ? rs->buf.data () : NULL; - add_current_inferior_and_thread (stop_reply); + add_current_inferior_and_thread (run_worked ? rs->buf.data () : nullptr); /* Get updated offsets, if the stub uses qOffsets. */ get_offsets ();