]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb: remote: Save the stop reply packet from vRun and use it
authorThiago Jung Bauermann <thiago.bauermann@linaro.org>
Sun, 27 Apr 2025 03:04:11 +0000 (00:04 -0300)
committerThiago Jung Bauermann <thiago.bauermann@linaro.org>
Thu, 23 Oct 2025 04:17:04 +0000 (01:17 -0300)
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.

gdb/process-stratum-target.h
gdb/regcache.c
gdb/remote.c

index b646c117501bc604a9aa20b4bb28a087d2f76032..dc50e8fe453444013d7c3610040436dab0052d30 100644 (file)
@@ -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;
index d18feb1c3d06c7ddd55391b6761479c356e315f7..41f8fedf8b64f7cb2054ba2792e1260abd2f0614 100644 (file)
@@ -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;
 }
 
index 44afc7f0a506a02b9640e4a600b60f2b765faff7..7619126e12b81585c41ebae1b6db92fb87258e73 100644 (file)
@@ -700,6 +700,9 @@ public: /* data */
      immediately, so queue is not needed for them.  */
   std::vector<stop_reply_up> 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
@@ -1324,6 +1327,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);
@@ -1527,6 +1532,9 @@ private:
 
   bool start_remote_1 (int from_tty, int extended_p);
 
+  void supply_expedited_registers (regcache *regcache,
+                                  std::vector<cached_reg_t> &expedited_regs);
+
   /* The remote state.  Don't reference this directly.  Use the
      get_remote_state method instead.  */
   remote_state m_remote_state;
@@ -8931,6 +8939,25 @@ 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<cached_reg_t> &expedited_regs)
+{
+  remote_state *rs = get_remote_state ();
+
+  for (cached_reg_t &reg : expedited_regs)
+    {
+      regcache->raw_supply (reg.num, reg.data);
+      rs->last_seen_expedited_registers.insert (reg.num);
+    }
+
+  if (regcache->has_variable_size_registers ())
+    rs->get_remote_arch_state (regcache->arch ())
+      ->update_packet_size (regcache, rs);
+}
+
 /* 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.  */
@@ -8969,16 +8996,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 &reg : stop_reply->regcache)
-           {
-             regcache->raw_supply (reg.num, reg.data);
-             rs->last_seen_expedited_registers.insert (reg.num);
-           }
-
-         if (regcache->has_variable_size_registers ())
-           rs->get_remote_arch_state (regcache->arch ())
-             ->update_packet_size (regcache, rs);
+         supply_expedited_registers (regcache, stop_reply->regcache);
        }
 
       remote_thread_info *remote_thr = get_remote_thread_info (this, ptid);
@@ -9004,6 +9022,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, &notif_client_stop,
+                         rs->first_stop_reply.data ());
+  std::vector<cached_reg_t> &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
@@ -11386,7 +11426,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 std::string &remote_exec_file = get_remote_exec_file ();
 
@@ -11419,7 +11458,10 @@ Remote replied unexpectedly while setting startup-with-shell: %s"),
 
   /* Now restart the remote server.  */
   run_worked = extended_remote_run (remote_exec_file, 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.  */
@@ -11432,9 +11474,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 ();