]> 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>
Sun, 27 Apr 2025 03:29:09 +0000 (00:29 -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 2545d4875bfdbe966a3e3758147d2a51834172c2..60fd5cc3e9ef658aac431ae61f9b8a3320eed85c 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 a78dcd84bf6fa72bb049b0737f834efd7277ec05..ce99d4f59795c118e93e3888365a1ee28a8d4946 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 ae2404589ad863af052d468418d5c221cb9aac6a..831c1d595ec7477c3c827d286e5a9bdb8ae4a5c8 100644 (file)
@@ -690,6 +690,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
@@ -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<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;
@@ -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<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);
+    }
+}
+
 /* 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 &reg : 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, &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
@@ -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 ();