]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Add bool argument to fetch only one register
authorThiago Jung Bauermann <thiago.bauermann@linaro.org>
Fri, 25 Apr 2025 01:29:01 +0000 (22:29 -0300)
committerThiago Jung Bauermann <thiago.bauermann@linaro.org>
Thu, 23 Oct 2025 04:17:04 +0000 (01:17 -0300)
When trying to fetch the VG register in aarch64_fetch_tdesc_parameter,
remote_target::fetch_registers ends up fetching all registers using the
G packet.  This results in an infinite recursion because GDB will need
to get the VL parameter and thus fetch the VG register again.

To solve the problem, add a bool parameter signaling that the target
should try to get just the requested register.

This commit is incomplete because there are some fetch_register
implementations that were not changed to accept the extra argument.

A possibly better and less invasive option would be to add a new
fetch_registers method overload with the new argument to the target_ops
class with a default implementation that would just call the existing
2-arguments version.  This way, only the remote target would need to
override that implementation.  This isn't done here because
make-target-delegates.py doesn't support method overloads and would need
to be adapted.

20 files changed:
gdb/aarch64-linux-nat.c
gdb/aarch64-tdep.c
gdb/aix-thread.c
gdb/amd-dbgapi-target.c
gdb/amd64-linux-nat.c
gdb/bsd-uthread.c
gdb/corelow.c
gdb/inf-child.h
gdb/ravenscar-thread.c
gdb/record-btrace.c
gdb/record-full.c
gdb/regcache.c
gdb/regcache.h
gdb/remote.c
gdb/sol-thread.c
gdb/target-delegates-gen.c
gdb/target.c
gdb/target.h
gdb/tracectf.c
gdb/tracefile-tfile.c

index 829a591628b0a5d74036de7231988261d19fc21e..b1c96f311cc7b6b77249fe46c1910c4d0e74d780 100644 (file)
@@ -68,7 +68,7 @@ class aarch64_linux_nat_target final
 {
 public:
   /* Add our register access methods.  */
-  void fetch_registers (struct regcache *, int) override;
+  void fetch_registers (struct regcache *, int, bool) override;
   void store_registers (struct regcache *, int) override;
 
   const struct target_desc *read_description () override;
@@ -740,7 +740,7 @@ aarch32_fetch_registers (struct regcache *regcache, int regno)
 
 void
 aarch64_linux_nat_target::fetch_registers (struct regcache *regcache,
-                                          int regno)
+                                          int regno, bool only_this)
 {
   if (gdbarch_bfd_arch_info (regcache->arch ())->bits_per_word == 32)
     aarch32_fetch_registers (regcache, regno);
index 58a09180a1c5fd2e7615ba1db85e927b05986d8d..30af583476c7453535d029914f1e4999c172580c 100644 (file)
@@ -4398,7 +4398,7 @@ aarch64_fetch_tdesc_parameter (gdbarch *gdbarch, readable_regcache *regcache,
       register_status status;
       gdb_byte buf[8];
 
-      status = regcache->raw_read (AARCH64_SVE_VG_REGNUM, buf);
+      status = regcache->raw_read (AARCH64_SVE_VG_REGNUM, buf, true);
       if (status != REG_VALID)
        return;
 
@@ -4417,7 +4417,7 @@ aarch64_fetch_tdesc_parameter (gdbarch *gdbarch, readable_regcache *regcache,
       register_status status;
       gdb_byte buf[8];
 
-      status = regcache->raw_read (AARCH64_SVE_VG_REGNUM, buf);
+      status = regcache->raw_read (AARCH64_SVE_VG_REGNUM, buf, true);
       if (status != REG_VALID)
        return;
 
index d81a0dc851c2700b531c8a3c468d5e99b006fa00..cb2018ac7753ff735399a22a13282feed12b552a 100644 (file)
@@ -116,7 +116,7 @@ public:
   void resume (ptid_t, int, enum gdb_signal) override;
   ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
 
-  void fetch_registers (struct regcache *, int) override;
+  void fetch_registers (struct regcache *, int, bool) override;
   void store_registers (struct regcache *, int) override;
 
   enum target_xfer_status xfer_partial (enum target_object object,
@@ -1443,7 +1443,8 @@ fetch_regs_kernel_thread (struct regcache *regcache, int regno,
    thread/process connected to REGCACHE.  */
 
 void
-aix_thread_target::fetch_registers (struct regcache *regcache, int regno)
+aix_thread_target::fetch_registers (struct regcache *regcache, int regno,
+                                   bool only_this)
 {
   struct thread_info *thread;
   pthdb_tid_t tid;
@@ -1453,7 +1454,7 @@ aix_thread_target::fetch_registers (struct regcache *regcache, int regno)
      exists.  */
 
   if (regcache->ptid ().tid () == 0)
-    beneath ()->fetch_registers (regcache, regno);
+    beneath ()->fetch_registers (regcache, regno, only_this);
   else
     {
       thread = current_inferior ()->find_thread (regcache->ptid ());
index d296f28300639a146ce271826e28db6359c37ee4..c705ec005c1eb47a572c19a85530c1afcb08b82e 100644 (file)
@@ -284,7 +284,7 @@ struct amd_dbgapi_target final : public target_ops
   void commit_resumed () override;
   void stop (ptid_t ptid) override;
 
-  void fetch_registers (struct regcache *, int) override;
+  void fetch_registers (struct regcache *, int, bool) override;
   void store_registers (struct regcache *, int) override;
 
   void update_thread_list () override;
@@ -1726,11 +1726,12 @@ amd_dbgapi_target::detach (inferior *inf, int from_tty)
 }
 
 void
-amd_dbgapi_target::fetch_registers (struct regcache *regcache, int regno)
+amd_dbgapi_target::fetch_registers (struct regcache *regcache, int regno,
+                                   bool only_this)
 {
   if (!ptid_is_gpu (regcache->ptid ()))
     {
-      beneath ()->fetch_registers (regcache, regno);
+      beneath ()->fetch_registers (regcache, regno, only_this);
       return;
     }
 
index 96acfda7d009b8656d49913a2e762cb45ec45a2c..631e2c315110b8767a43bd4a5d480f9fac0798b5 100644 (file)
@@ -48,7 +48,7 @@
 struct amd64_linux_nat_target final : public x86_linux_nat_target
 {
   /* Add our register access methods.  */
-  void fetch_registers (struct regcache *, int) override;
+  void fetch_registers (struct regcache *, int, bool) override;
   void store_registers (struct regcache *, int) override;
 
   bool low_siginfo_fixup (siginfo_t *ptrace, gdb_byte *inf, int direction)
@@ -211,7 +211,8 @@ fill_fpregset (const struct regcache *regcache,
    registers).  */
 
 void
-amd64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum)
+amd64_linux_nat_target::fetch_registers (struct regcache *regcache, int regnum,
+                                        bool only_this)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   const i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
index 4509376b8c62eaf8a525b484cb23b97c0d6d5b4f..3231f016dcda15b531c0907db86ee10034a3c294 100644 (file)
@@ -49,7 +49,7 @@ struct bsd_uthread_target final : public target_ops
 
   void mourn_inferior () override;
 
-  void fetch_registers (struct regcache *, int) override;
+  void fetch_registers (struct regcache *, int, bool) override;
   void store_registers (struct regcache *, int) override;
 
   ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
@@ -311,7 +311,8 @@ bsd_uthread_target::mourn_inferior ()
 }
 
 void
-bsd_uthread_target::fetch_registers (struct regcache *regcache, int regnum)
+bsd_uthread_target::fetch_registers (struct regcache *regcache, int regnum,
+                                    bool only_this)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   struct bsd_uthread_ops *uthread_ops = get_bsd_uthread (gdbarch);
@@ -325,7 +326,7 @@ bsd_uthread_target::fetch_registers (struct regcache *regcache, int regnum)
   inferior_ptid = ptid;
 
   /* Always fetch the appropriate registers from the layer beneath.  */
-  beneath ()->fetch_registers (regcache, regnum);
+  beneath ()->fetch_registers (regcache, regnum, only_this);
 
   /* FIXME: That might have gotten us more than we asked for.  Make
      sure we overwrite all relevant registers with values from the
index 218504bcdc85db51e4731771cfd05deab9d75d90..5f5089115f5f4957f645addd271498681775925d 100644 (file)
@@ -196,7 +196,7 @@ public:
 
   void close () override;
   void detach (inferior *, int) override;
-  void fetch_registers (struct regcache *, int) override;
+  void fetch_registers (struct regcache *, int, bool) override;
 
   enum target_xfer_status xfer_partial (enum target_object object,
                                        const char *annex,
@@ -1371,10 +1371,11 @@ get_core_registers_cb (const char *sect_name, int supply_size, int collect_size,
    part, typically implemented in the xm-file for each
    architecture.  */
 
-/* We just get all the registers, so we don't use regno.  */
+/* We just get all the registers, so we don't use regno nor only_this.  */
 
 void
-core_target::fetch_registers (struct regcache *regcache, int regno)
+core_target::fetch_registers (struct regcache *regcache, int regno,
+                             bool only_this)
 {
   if (!(m_core_gdbarch != nullptr
        && gdbarch_iterate_over_regset_sections_p (m_core_gdbarch)))
index 70de39328743e80bacfe774365fbb697fdd95d54..b27af8bf8f07c546837ec40b35093e72094792e1 100644 (file)
@@ -39,7 +39,7 @@ public:
 
   void disconnect (const char *, int) override;
 
-  void fetch_registers (struct regcache *, int) override = 0;
+  void fetch_registers (struct regcache *, int, bool) override = 0;
   void store_registers (struct regcache *, int) override = 0;
 
   void prepare_to_store (struct regcache *) override;
index 4d79b3d06e02cd0a1372510f838a091a5835f293..fd2270c74584ba8bcebf0de6b67a2932f3a77ab7 100644 (file)
@@ -90,7 +90,7 @@ struct ravenscar_thread_target final : public target_ops
   ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
   void resume (ptid_t, int, enum gdb_signal) override;
 
-  void fetch_registers (struct regcache *, int) override;
+  void fetch_registers (struct regcache *, int, bool) override;
   void store_registers (struct regcache *, int) override;
 
   void prepare_to_store (struct regcache *) override;
@@ -676,7 +676,7 @@ ravenscar_thread_target::get_fpu_state (struct regcache *regcache,
 
 void
 ravenscar_thread_target::fetch_registers (struct regcache *regcache,
-                                         int regnum)
+                                         int regnum, bool only_this)
 {
   ptid_t ptid = regcache->ptid ();
 
@@ -710,14 +710,14 @@ ravenscar_thread_target::fetch_registers (struct regcache *regcache,
          if (use_beneath)
            {
              temporarily_change_regcache_ptid changer (regcache, base);
-             beneath ()->fetch_registers (regcache, i);
+             beneath ()->fetch_registers (regcache, i, only_this);
            }
          else
            arch_ops->fetch_register (regcache, i);
        }
     }
   else
-    beneath ()->fetch_registers (regcache, regnum);
+    beneath ()->fetch_registers (regcache, regnum, only_this);
 }
 
 void
index be3a3955974a89f647cbb6cd129f5c09f1ad20bc..e07b725443f4459e95ec9883d3a9b88026c39dea 100644 (file)
@@ -110,7 +110,7 @@ public:
   int remove_breakpoint (struct gdbarch *, struct bp_target_info *,
                         enum remove_bp_reason) override;
 
-  void fetch_registers (struct regcache *, int) override;
+  void fetch_registers (struct regcache *, int, bool) override;
 
   void store_registers (struct regcache *, int) override;
   void prepare_to_store (struct regcache *) override;
@@ -1586,7 +1586,8 @@ record_btrace_target::remove_breakpoint (struct gdbarch *gdbarch,
 /* The fetch_registers method of target record-btrace.  */
 
 void
-record_btrace_target::fetch_registers (struct regcache *regcache, int regno)
+record_btrace_target::fetch_registers (struct regcache *regcache, int regno,
+                                      bool only_this)
 {
   btrace_insn_iterator *replay = nullptr;
 
@@ -1619,7 +1620,7 @@ record_btrace_target::fetch_registers (struct regcache *regcache, int regno)
       regcache->raw_supply (regno, &insn->pc);
     }
   else
-    this->beneath ()->fetch_registers (regcache, regno);
+    this->beneath ()->fetch_registers (regcache, regno, only_this);
 }
 
 /* The store_registers method of target record-btrace.  */
index afe91a57aeb54462007d4fdea8b643038f1d2a1c..2da56d45e67c197d60d76d64ff8c5d1b4f43f689 100644 (file)
@@ -309,7 +309,7 @@ public:
   void resume (ptid_t, int, enum gdb_signal) override;
   void disconnect (const char *, int) override;
   void kill () override;
-  void fetch_registers (struct regcache *regcache, int regno) override;
+  void fetch_registers (struct regcache *regcache, int regno, bool) override;
   void prepare_to_store (struct regcache *regcache) override;
   void store_registers (struct regcache *, int) override;
   enum target_xfer_status xfer_partial (enum target_object object,
@@ -2103,7 +2103,7 @@ record_full_core_target::kill ()
 
 void
 record_full_core_target::fetch_registers (struct regcache *regcache,
-                                         int regno)
+                                         int regno, bool only_this)
 {
   if (regno < 0)
     {
index 03856ab867a75a01f64853b03e0e219b0f46688a..d18feb1c3d06c7ddd55391b6761479c356e315f7 100644 (file)
@@ -830,7 +830,7 @@ registers_changed (void)
 }
 
 void
-regcache::raw_update (int regnum)
+regcache::raw_update (int regnum, bool only_this)
 {
   assert_regnum (regnum);
 
@@ -844,7 +844,7 @@ regcache::raw_update (int regnum)
       std::optional<scoped_restore_current_thread> maybe_restore_thread
        = maybe_switch_inferior (m_inf_for_target_calls);
 
-      target_fetch_registers (this, regnum);
+      target_fetch_registers (this, regnum, only_this);
 
       /* A number of targets can't access the whole set of raw
         registers (because the debug API provides no means to get at
@@ -855,12 +855,13 @@ regcache::raw_update (int regnum)
 }
 
 register_status
-readable_regcache::raw_read (int regnum, gdb::array_view<gdb_byte> dst)
+readable_regcache::raw_read (int regnum, gdb::array_view<gdb_byte> dst,
+                            bool only_this)
 {
   assert_regnum (regnum);
   gdb_assert (dst.size () == register_size (regnum));
 
-  raw_update (regnum);
+  raw_update (regnum, only_this);
 
   if (m_register_status[regnum] != REG_VALID)
     memset (dst.data (), 0, dst.size ());
@@ -2159,7 +2160,7 @@ public:
     xfer_partial_called = 0;
   }
 
-  void fetch_registers (regcache *regs, int regno) override;
+  void fetch_registers (regcache *regs, int regno, bool) override;
   void store_registers (regcache *regs, int regno) override;
 
   enum target_xfer_status xfer_partial (enum target_object object,
@@ -2174,7 +2175,8 @@ public:
 };
 
 void
-target_ops_no_register::fetch_registers (regcache *regs, int regno)
+target_ops_no_register::fetch_registers (regcache *regs, int regno,
+                                        bool only_this)
 {
   /* Mark register available.  */
   regs->raw_supply_zeroed (regno);
index db650f855c396ad6dfb83297ada8c3951aca2320..a8ee90f12ab08e3d1b0443b5233c1500421bdd98 100644 (file)
@@ -348,8 +348,13 @@ public:
   {}
 
   /* Transfer a raw register [0..NUM_REGS) from core-gdb to this regcache,
-     return its value in *BUF and return its availability status.  */
-  register_status raw_read (int regnum, gdb::array_view<gdb_byte> dst);
+     return its value in *BUF and return its availability status.
+
+     If ONLY_THIS is true, then don't try to fetch other registers in the
+     process of updating REGNUM.  This may be required when REGNUM is used
+     by a target_description parameter.  */
+  register_status raw_read (int regnum, gdb::array_view<gdb_byte> dst,
+                           bool only_this = false);
 
   /* Deprecated overload of the above.  */
   register_status raw_read (int regnum, gdb_byte *dst);
@@ -366,8 +371,12 @@ public:
                                 gdb_byte *dst)
   { return raw_read_part (regnum, offset, gdb::make_array_view (dst, len)); }
 
-  /* Make certain that the register REGNUM is up-to-date.  */
-  virtual void raw_update (int regnum) = 0;
+  /* Make certain that the register REGNUM is up-to-date.
+
+     If ONLY_THIS is true, then don't try to fetch other registers in the
+     process of updating REGNUM.  This may be required when REGNUM is used
+     by a target_description parameter.  */
+  virtual void raw_update (int regnum, bool only_this = false) = 0;
 
   /* Transfer a raw register [0..NUM_REGS+NUM_PSEUDO_REGS) from core-gdb to
      this regcache, return its value in DST and return its availability status.  */
@@ -416,7 +425,7 @@ public:
     : readable_regcache (gdbarch, has_pseudo)
   {}
 
-  void raw_update (int regnum) override
+  void raw_update (int regnum, bool only_this) override
   {}
 
   DISABLE_COPY_AND_ASSIGN (detached_regcache);
@@ -457,7 +466,7 @@ public:
   template<typename T, typename = RequireLongest<T>>
   void cooked_write (int regnum, T val);
 
-  void raw_update (int regnum) override;
+  void raw_update (int regnum, bool only_this = false) override;
 
   /* Partial transfer of raw registers.  Perform read, modify, write style
      operations.  */
@@ -579,7 +588,7 @@ public:
 
   DISABLE_COPY_AND_ASSIGN (readonly_detached_regcache);
 
-  void raw_update (int regnum) override
+  void raw_update (int regnum, bool only_this = false) override
   {}
 };
 
index e75a5a664b73e204b079f2ad15280a2ad8c9d46c..44afc7f0a506a02b9640e4a600b60f2b765faff7 100644 (file)
@@ -971,7 +971,7 @@ public:
   ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
   bool has_pending_events () override;
 
-  void fetch_registers (struct regcache *, int) override;
+  void fetch_registers (struct regcache *, int, bool) override;
   void store_registers (struct regcache *, int) override;
   void prepare_to_store (struct regcache *) override;
 
@@ -9495,7 +9495,8 @@ remote_target::set_remote_traceframe ()
 }
 
 void
-remote_target::fetch_registers (struct regcache *regcache, int regnum)
+remote_target::fetch_registers (struct regcache *regcache, int regnum,
+                               bool only_this)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   struct remote_state *rs = get_remote_state ();
@@ -9515,7 +9516,7 @@ remote_target::fetch_registers (struct regcache *regcache, int regnum)
         we are likely to read more than one register.  If this is the
         first 'g' packet, we might be overly optimistic about its
         contents, so fall back to 'p'.  */
-      if (reg->in_g_packet)
+      if (!only_this && reg->in_g_packet)
        {
          fetch_registers_using_g (regcache);
          if (reg->in_g_packet)
index 0aa45950696e1d42ab31a052c11215c00129a013..49500eeacf8a1f96c94007b30a048b3705102c45 100644 (file)
@@ -89,7 +89,7 @@ public:
   std::string pid_to_str (ptid_t) override;
   ptid_t get_ada_task_ptid (long lwp, ULONGEST thread) override;
 
-  void fetch_registers (struct regcache *, int) override;
+  void fetch_registers (struct regcache *, int, bool) override;
   void store_registers (struct regcache *, int) override;
 
   enum target_xfer_status xfer_partial (enum target_object object,
@@ -468,7 +468,8 @@ sol_thread_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus,
 }
 
 void
-sol_thread_target::fetch_registers (struct regcache *regcache, int regnum)
+sol_thread_target::fetch_registers (struct regcache *regcache, int regnum,
+                                   bool only_this)
 {
   thread_t thread;
   td_thrhandle_t thandle;
@@ -482,7 +483,7 @@ sol_thread_target::fetch_registers (struct regcache *regcache, int regnum)
   if (!ptid.tid_p ())
     {
       /* It's an LWP; pass the request on to the layer beneath.  */
-      beneath ()->fetch_registers (regcache, regnum);
+      beneath ()->fetch_registers (regcache, regnum, only_this);
       return;
     }
 
index 164ddbb9a2ea2da5fe4e02f78c3fa82d5e9eaf18..716a444478674a4027110d165a5dcbd7fc9f75c2 100644 (file)
@@ -36,7 +36,7 @@ struct dummy_target : public target_ops
   void resume (ptid_t arg0, int arg1, enum gdb_signal arg2) override;
   void commit_resumed () override;
   ptid_t wait (ptid_t arg0, struct target_waitstatus *arg1, target_wait_flags arg2) override;
-  void fetch_registers (struct regcache *arg0, int arg1) override;
+  void fetch_registers (struct regcache *arg0, int arg1, bool arg2) override;
   void store_registers (struct regcache *arg0, int arg1) override;
   void prepare_to_store (struct regcache *arg0) override;
   void files_info () override;
@@ -217,7 +217,7 @@ struct debug_target : public target_ops
   void resume (ptid_t arg0, int arg1, enum gdb_signal arg2) override;
   void commit_resumed () override;
   ptid_t wait (ptid_t arg0, struct target_waitstatus *arg1, target_wait_flags arg2) override;
-  void fetch_registers (struct regcache *arg0, int arg1) override;
+  void fetch_registers (struct regcache *arg0, int arg1, bool arg2) override;
   void store_registers (struct regcache *arg0, int arg1) override;
   void prepare_to_store (struct regcache *arg0) override;
   void files_info () override;
@@ -524,25 +524,26 @@ debug_target::wait (ptid_t arg0, struct target_waitstatus *arg1, target_wait_fla
 }
 
 void
-target_ops::fetch_registers (struct regcache *arg0, int arg1)
+target_ops::fetch_registers (struct regcache *arg0, int arg1, bool arg2)
 {
-  this->beneath ()->fetch_registers (arg0, arg1);
+  this->beneath ()->fetch_registers (arg0, arg1, arg2);
 }
 
 void
-dummy_target::fetch_registers (struct regcache *arg0, int arg1)
+dummy_target::fetch_registers (struct regcache *arg0, int arg1, bool arg2)
 {
 }
 
 void
-debug_target::fetch_registers (struct regcache *arg0, int arg1)
+debug_target::fetch_registers (struct regcache *arg0, int arg1, bool arg2)
 {
   target_debug_printf_nofunc ("-> %s->fetch_registers (...)", this->beneath ()->shortname ());
-  this->beneath ()->fetch_registers (arg0, arg1);
-  target_debug_printf_nofunc ("<- %s->fetch_registers (%s, %s)",
+  this->beneath ()->fetch_registers (arg0, arg1, arg2);
+  target_debug_printf_nofunc ("<- %s->fetch_registers (%s, %s, %s)",
              this->beneath ()->shortname (),
              target_debug_print_regcache_p (arg0).c_str (),
-             target_debug_print_int (arg1).c_str ());
+             target_debug_print_int (arg1).c_str (),
+             target_debug_print_bool (arg2).c_str ());
 }
 
 void
index 641ec1d7e72aad0fd67101fe3b2d5c9dd437461b..dc377f78f3f0d62bcecc0dea67c5dc22762a56ce 100644 (file)
@@ -3918,9 +3918,10 @@ target_options_to_string (target_wait_flags target_options)
 }
 
 void
-target_fetch_registers (struct regcache *regcache, int regno)
+target_fetch_registers (struct regcache *regcache, int regno, bool only_this)
 {
-  current_inferior ()->top_target ()->fetch_registers (regcache, regno);
+  current_inferior ()->top_target ()->fetch_registers (regcache, regno,
+                                                      only_this);
   target_debug_printf ("%s", regcache->register_debug_string (regno).c_str ());
 }
 
index 40823253a0f8c8ab949d6f685644f8bcc13ea8c0..c1a3d781abe9d6683965d4ec8b1dc6b94c1037bd 100644 (file)
@@ -526,7 +526,7 @@ struct target_ops
     virtual ptid_t wait (ptid_t, struct target_waitstatus *,
                         target_wait_flags options)
       TARGET_DEFAULT_FUNC (default_target_wait);
-    virtual void fetch_registers (struct regcache *, int)
+    virtual void fetch_registers (struct regcache *, int, bool)
       TARGET_DEFAULT_IGNORE ();
     virtual void store_registers (struct regcache *, int)
       TARGET_DEFAULT_NORETURN (noprocess ());
@@ -1601,9 +1601,15 @@ extern ptid_t default_target_wait (struct target_ops *ops,
 
 extern bool target_has_pending_events ();
 
-/* Fetch at least register REGNO, or all regs if regno == -1.  No result.  */
+/* Fetch at least register REGNO, or all regs if regno == -1.  No result.
 
-extern void target_fetch_registers (struct regcache *regcache, int regno);
+   If ONLY_THIS is true, then try to minimize the number of registers
+   fetched in the process of updating REGNUM.  This may be required when
+   REGNUM is used by a target_description parameter.
+   */
+
+extern void target_fetch_registers (struct regcache *regcache, int regno,
+                                   bool only_this = false);
 
 /* Store at least register REGNO, or all regs if REGNO == -1.
    It can store as many registers as it wants to, so target_prepare_to_store
index c2231ff32d23fff66507a0b7946149d6f5818d0f..9d829127ed5b7d9e8f22e4f8685b0e1acaa9bff8 100644 (file)
@@ -838,7 +838,7 @@ public:
   { return ctf_target_info; }
 
   void close () override;
-  void fetch_registers (struct regcache *, int) override;
+  void fetch_registers (struct regcache *, int, bool) override;
   enum target_xfer_status xfer_partial (enum target_object object,
                                                const char *annex,
                                                gdb_byte *readbuf,
@@ -1206,7 +1206,8 @@ ctf_target::files_info ()
    If no matched events are found, mark registers unavailable.  */
 
 void
-ctf_target::fetch_registers (struct regcache *regcache, int regno)
+ctf_target::fetch_registers (struct regcache *regcache, int regno,
+                            bool only_this)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   struct bt_ctf_event *event = NULL;
index a45001cf318fdb2ff9c1c71fa118148248755ee8..c98a4c191ba93847f07917eeaa2cc0215825ac31 100644 (file)
@@ -54,7 +54,7 @@ class tfile_target final : public tracefile_target
   { return tfile_target_info; }
 
   void close () override;
-  void fetch_registers (struct regcache *, int) override;
+  void fetch_registers (struct regcache *, int, bool) override;
   enum target_xfer_status xfer_partial (enum target_object object,
                                                const char *annex,
                                                gdb_byte *readbuf,
@@ -847,7 +847,8 @@ traceframe_find_block_type (char type_wanted, int pos)
    requested register from it.  */
 
 void
-tfile_target::fetch_registers (struct regcache *regcache, int regno)
+tfile_target::fetch_registers (struct regcache *regcache, int regno,
+                              bool only_this)
 {
   struct gdbarch *gdbarch = regcache->arch ();
   int offset, regn, regsize, dummy;