Class readonly_detached_regcache
authorYao Qi <yao.qi@linaro.org>
Wed, 21 Feb 2018 11:20:03 +0000 (11:20 +0000)
committerYao Qi <yao.qi@linaro.org>
Wed, 21 Feb 2018 11:20:03 +0000 (11:20 +0000)
This patch adds a new class (type) for readonly regcache, which is
created via regcache::save.  readonly_detached_regcache inherits
readable_regcache.

gdb:

2018-02-21  Yao Qi  <yao.qi@linaro.org>

* dummy-frame.c (dummy_frame_cache) <prev_regcache>: Use
readonly_detached_regcache.
(dummy_frame_prev_register): Use regcache->cooked_read.
* frame.c (frame_save_as_regcache): Change return type.
(frame_pop): Update.
* frame.h (frame_save_as_regcache): Update declaration.
* inferior.h (get_infcall_suspend_state_regcache): Update
declaration.
* infrun.c (infcall_suspend_state) <registers>: use
readonly_detached_regcache.
(save_infcall_suspend_state): Don't use regcache_dup.
(get_infcall_suspend_state_regcache): Change return type.
* linux-fork.c (struct fork_info) <savedregs>: Change to
readonly_detached_regcache.
<pc>: New field.
(fork_save_infrun_state): Don't use regcache_dup.
(info_checkpoints_command): Adjust.
* mi/mi-main.c (register_changed_p): Update declaration.
(mi_cmd_data_list_changed_registers): Use
readonly_detached_regcache.
(register_changed_p): Change parameter type to
readonly_detached_regcache.
* ppc-linux-tdep.c (ppu2spu_cache) <regcache>: Use
readonly_detached_regcache.
(ppu2spu_sniffer): Construct a new readonly_detached_regcache.
* regcache.c (readonly_detached_regcache::readonly_detached_regcache):
New.
(regcache::save): Move it to reg_buffer.
(regcache::restore): Change parameter type.
(regcache_dup): Remove.
* regcache.h (reg_buffer) <save>: New method.
(readonly_detached_regcache): New class.
* spu-tdep.c (spu2ppu_cache) <regcache>: Use
readonly_detached_regcache.
(spu2ppu_sniffer): Construct a new readonly_detached_regcache.

12 files changed:
gdb/ChangeLog
gdb/dummy-frame.c
gdb/frame.c
gdb/frame.h
gdb/inferior.h
gdb/infrun.c
gdb/linux-fork.c
gdb/mi/mi-main.c
gdb/ppc-linux-tdep.c
gdb/regcache.c
gdb/regcache.h
gdb/spu-tdep.c

index a7da794070b692529a9776cfc72e230fb47f643d..bb59b311b2b214169b4df545e41faa1acf368e8d 100644 (file)
@@ -1,3 +1,41 @@
+2018-02-21  Yao Qi  <yao.qi@linaro.org>
+
+       * dummy-frame.c (dummy_frame_cache) <prev_regcache>: Use
+       readonly_detached_regcache.
+       (dummy_frame_prev_register): Use regcache->cooked_read.
+       * frame.c (frame_save_as_regcache): Change return type.
+       (frame_pop): Update.
+       * frame.h (frame_save_as_regcache): Update declaration.
+       * inferior.h (get_infcall_suspend_state_regcache): Update
+       declaration.
+       * infrun.c (infcall_suspend_state) <registers>: use
+       readonly_detached_regcache.
+       (save_infcall_suspend_state): Don't use regcache_dup.
+       (get_infcall_suspend_state_regcache): Change return type.
+       * linux-fork.c (struct fork_info) <savedregs>: Change to
+       readonly_detached_regcache.
+       <pc>: New field.
+       (fork_save_infrun_state): Don't use regcache_dup.
+       (info_checkpoints_command): Adjust.
+       * mi/mi-main.c (register_changed_p): Update declaration.
+       (mi_cmd_data_list_changed_registers): Use
+       readonly_detached_regcache.
+       (register_changed_p): Change parameter type to
+       readonly_detached_regcache.
+       * ppc-linux-tdep.c (ppu2spu_cache) <regcache>: Use
+       readonly_detached_regcache.
+       (ppu2spu_sniffer): Construct a new readonly_detached_regcache.
+       * regcache.c (readonly_detached_regcache::readonly_detached_regcache):
+       New.
+       (regcache::save): Move it to reg_buffer.
+       (regcache::restore): Change parameter type.
+       (regcache_dup): Remove.
+       * regcache.h (reg_buffer) <save>: New method.
+       (readonly_detached_regcache): New class.
+       * spu-tdep.c (spu2ppu_cache) <regcache>: Use
+       readonly_detached_regcache.
+       (spu2ppu_sniffer): Construct a new readonly_detached_regcache.
+
 2018-02-21  Yao Qi  <yao.qi@linaro.org>
 
        * frame.c (frame_save_as_regcache): Use regcache method save.
index db8ba1b8e0b8b1fd7b85738d5b759c0ce0ae6c1c..a67033e6f2cca89b91acdb43c9fcc669740de5a2 100644 (file)
@@ -282,7 +282,7 @@ cleanup_dummy_frames (struct target_ops *target, int from_tty)
 struct dummy_frame_cache
 {
   struct frame_id this_id;
-  struct regcache *prev_regcache;
+  readonly_detached_regcache *prev_regcache;
 };
 
 static int
@@ -352,8 +352,8 @@ dummy_frame_prev_register (struct frame_info *this_frame,
   /* Use the regcache_cooked_read() method so that it, on the fly,
      constructs either a raw or pseudo register from the raw
      register cache.  */
-  regcache_cooked_read (cache->prev_regcache, regnum,
-                       value_contents_writeable (reg_val));
+  cache->prev_regcache->cooked_read (regnum,
+                                    value_contents_writeable (reg_val));
   return reg_val;
 }
 
index 773fd0449d3fde2bcbafcfeb2179713a79eb4ad5..0b04a4ebacb2d0c2a7e56c9506c745160af2cdaf 100644 (file)
@@ -1017,13 +1017,13 @@ do_frame_register_read (void *src, int regnum, gdb_byte *buf)
     return REG_VALID;
 }
 
-std::unique_ptr<struct regcache>
+std::unique_ptr<readonly_detached_regcache>
 frame_save_as_regcache (struct frame_info *this_frame)
 {
-  std::unique_ptr<struct regcache> regcache
-    (new struct regcache (get_frame_arch (this_frame)));
+  std::unique_ptr<readonly_detached_regcache> regcache
+    (new readonly_detached_regcache (get_frame_arch (this_frame),
+                                    do_frame_register_read, this_frame));
 
-  regcache->save (do_frame_register_read, this_frame);
   return regcache;
 }
 
@@ -1057,7 +1057,7 @@ frame_pop (struct frame_info *this_frame)
      Save them in a scratch buffer so that there isn't a race between
      trying to extract the old values from the current regcache while
      at the same time writing new values into that same cache.  */
-  std::unique_ptr<struct regcache> scratch
+  std::unique_ptr<readonly_detached_regcache> scratch
     = frame_save_as_regcache (prev_frame);
 
   /* FIXME: cagney/2003-03-16: It should be possible to tell the
index 8293a49ec238c7ff4e2cfce84b4aeadf49bd0a3b..d5800b78c2568b19c9a943dc3661b730b76f69ab 100644 (file)
@@ -680,8 +680,9 @@ extern void *frame_obstack_zalloc (unsigned long size);
 #define FRAME_OBSTACK_CALLOC(NUMBER,TYPE) \
   ((TYPE *) frame_obstack_zalloc ((NUMBER) * sizeof (TYPE)))
 
+class readonly_detached_regcache;
 /* Create a regcache, and copy the frame's registers into it.  */
-std::unique_ptr<struct regcache> frame_save_as_regcache
+std::unique_ptr<readonly_detached_regcache> frame_save_as_regcache
     (struct frame_info *this_frame);
 
 extern const struct block *get_frame_block (struct frame_info *,
index 22008a005b98c030185e404b0fc4c9571ba4984e..391a5fdaa5c4cf18f453f2f70113948e2b514056 100644 (file)
@@ -70,7 +70,7 @@ extern struct cleanup *make_cleanup_restore_infcall_control_state
 extern void discard_infcall_suspend_state (struct infcall_suspend_state *);
 extern void discard_infcall_control_state (struct infcall_control_state *);
 
-extern struct regcache *
+extern readonly_detached_regcache *
   get_infcall_suspend_state_regcache (struct infcall_suspend_state *);
 
 extern void set_sigint_trap (void);
index b4e6c6b6916eaba2cab220efdb0e46fec1322984..c6639085681a6400bfddcb1f09ff46332d1b5864 100644 (file)
@@ -8805,7 +8805,7 @@ struct infcall_suspend_state
 
   /* Other fields:  */
   CORE_ADDR stop_pc;
-  struct regcache *registers;
+  readonly_detached_regcache *registers;
 
   /* Format of SIGINFO_DATA or NULL if it is not present.  */
   struct gdbarch *siginfo_gdbarch;
@@ -8861,7 +8861,7 @@ save_infcall_suspend_state (void)
 
   inf_state->stop_pc = stop_pc;
 
-  inf_state->registers = regcache_dup (regcache);
+  inf_state->registers = new readonly_detached_regcache (*regcache);
 
   return inf_state;
 }
@@ -8918,7 +8918,7 @@ discard_infcall_suspend_state (struct infcall_suspend_state *inf_state)
   xfree (inf_state);
 }
 
-struct regcache *
+readonly_detached_regcache *
 get_infcall_suspend_state_regcache (struct infcall_suspend_state *inf_state)
 {
   return inf_state->registers;
index df7ea4e17104e004010d508500e8ed996c4bffe0..9ffab1ff6c26077d9044a0313ea03c509524a545 100644 (file)
@@ -45,8 +45,9 @@ struct fork_info
   ptid_t ptid;
   ptid_t parent_ptid;
   int num;                     /* Convenient handle (GDB fork id).  */
-  struct regcache *savedregs;  /* Convenient for info fork, saves
+  readonly_detached_regcache *savedregs;       /* Convenient for info fork, saves
                                   having to actually switch contexts.  */
+  CORE_ADDR pc;
   int clobber_regs;            /* True if we should restore saved regs.  */
   off_t *filepos;              /* Set of open file descriptors' offsets.  */
   int maxfd;
@@ -294,7 +295,8 @@ fork_save_infrun_state (struct fork_info *fp, int clobber_regs)
   if (fp->savedregs)
     delete fp->savedregs;
 
-  fp->savedregs = regcache_dup (get_current_regcache ());
+  fp->savedregs = new readonly_detached_regcache (*get_current_regcache ());
+  fp->pc = regcache_read_pc (get_current_regcache ());
   fp->clobber_regs = clobber_regs;
 
   if (clobber_regs)
@@ -590,15 +592,11 @@ info_checkpoints_command (const char *arg, int from_tty)
 
       printed = fp;
       if (ptid_equal (fp->ptid, inferior_ptid))
-       {
-         printf_filtered ("* ");
-         pc = regcache_read_pc (get_current_regcache ());
-       }
+       printf_filtered ("* ");
       else
-       {
-         printf_filtered ("  ");
-         pc = regcache_read_pc (fp->savedregs);
-       }
+       printf_filtered ("  ");
+
+      pc = fp->pc;
       printf_filtered ("%d %s", fp->num, target_pid_to_str (fp->ptid));
       if (fp->num == 0)
        printf_filtered (_(" (main process)"));
index 51d33c9e9ff9cd6758e3ae0826afad6b57b3b778..1716a7fe443fa414fc803c8ba18d4427eb80a5c7 100644 (file)
@@ -96,8 +96,8 @@ static void mi_execute_cli_command (const char *cmd, int args_p,
                                    const char *args);
 static void mi_execute_async_cli_command (const char *cli_command,
                                          char **argv, int argc);
-static bool register_changed_p (int regnum, regcache *,
-                               regcache *);
+static bool register_changed_p (int regnum, readonly_detached_regcache *,
+                              readonly_detached_regcache *);
 static void output_register (struct frame_info *, int regnum, int format,
                             int skip_unavailable);
 
@@ -931,9 +931,9 @@ mi_cmd_data_list_register_names (const char *command, char **argv, int argc)
 void
 mi_cmd_data_list_changed_registers (const char *command, char **argv, int argc)
 {
-  static std::unique_ptr<struct regcache> this_regs;
+  static std::unique_ptr<readonly_detached_regcache> this_regs;
   struct ui_out *uiout = current_uiout;
-  std::unique_ptr<struct regcache> prev_regs;
+  std::unique_ptr<readonly_detached_regcache> prev_regs;
   struct gdbarch *gdbarch;
   int regnum, numregs;
   int i;
@@ -995,8 +995,8 @@ mi_cmd_data_list_changed_registers (const char *command, char **argv, int argc)
 }
 
 static bool
-register_changed_p (int regnum, struct regcache *prev_regs,
-                   struct regcache *this_regs)
+register_changed_p (int regnum, readonly_detached_regcache *prev_regs,
+                   readonly_detached_regcache *this_regs)
 {
   struct gdbarch *gdbarch = this_regs->arch ();
   struct value *prev_value, *this_value;
index 13a50d6756308724b2de93929d81ce01f924d681..d6a98fc0dbfe6caff51967c2a970d4af53815621 100644 (file)
@@ -1262,7 +1262,7 @@ ppc_linux_spe_context (int wordsize, enum bfd_endian byte_order,
 struct ppu2spu_cache
 {
   struct frame_id frame_id;
-  struct regcache *regcache;
+  readonly_detached_regcache *regcache;
 };
 
 static struct gdbarch *
@@ -1369,10 +1369,10 @@ ppu2spu_sniffer (const struct frame_unwind *self,
        {
          struct ppu2spu_cache *cache
            = FRAME_OBSTACK_CALLOC (1, struct ppu2spu_cache);
-         std::unique_ptr<struct regcache> regcache
-           (new struct regcache (data.gdbarch));
-
-         regcache->save (ppu2spu_unwind_register, &data);
+         std::unique_ptr<readonly_detached_regcache> regcache
+           (new readonly_detached_regcache (data.gdbarch,
+                                            ppu2spu_unwind_register,
+                                            &data));
 
          cache->frame_id = frame_id_build (base, func);
          cache->regcache = regcache.release ();
index 0df6a88ada6dbd8b0d6ce88bf1b327987cb1e3fe..ebe3c7bac074da9abbe210574406edaa99379410 100644 (file)
@@ -226,6 +226,11 @@ regcache::regcache (readonly_t, const regcache &src)
   save (do_cooked_read, (void *) &src);
 }
 
+readonly_detached_regcache::readonly_detached_regcache (const regcache &src)
+  : readonly_detached_regcache (src.arch (), do_cooked_read, (void *) &src)
+{
+}
+
 gdbarch *
 reg_buffer::arch () const
 {
@@ -282,16 +287,14 @@ reg_buffer::register_buffer (int regnum) const
 }
 
 void
-regcache::save (regcache_cooked_read_ftype *cooked_read,
-               void *src)
+reg_buffer::save (regcache_cooked_read_ftype *cooked_read,
+                 void *src)
 {
   struct gdbarch *gdbarch = m_descr->gdbarch;
   int regnum;
 
-  /* The DST should be `read-only', if it wasn't then the save would
-     end up trying to write the register values back out to the
-     target.  */
-  gdb_assert (m_readonly_p);
+  /* It should have pseudo registers.  */
+  gdb_assert (m_has_pseudo);
   /* Clear the dest.  */
   memset (m_registers, 0, m_descr->sizeof_cooked_registers);
   memset (m_register_status, 0, m_descr->nr_cooked_registers);
@@ -317,16 +320,14 @@ regcache::save (regcache_cooked_read_ftype *cooked_read,
 }
 
 void
-regcache::restore (struct regcache *src)
+regcache::restore (readonly_detached_regcache *src)
 {
   struct gdbarch *gdbarch = m_descr->gdbarch;
   int regnum;
 
   gdb_assert (src != NULL);
-  /* The dst had better not be read-only.  If it is, the `restore'
-     doesn't make much sense.  */
   gdb_assert (!m_readonly_p);
-  gdb_assert (src->m_readonly_p);
+  gdb_assert (src->m_has_pseudo);
 
   gdb_assert (gdbarch == src->arch ());
 
@@ -344,12 +345,6 @@ regcache::restore (struct regcache *src)
     }
 }
 
-struct regcache *
-regcache_dup (struct regcache *src)
-{
-  return new regcache (regcache::readonly, *src);
-}
-
 enum register_status
 regcache_register_status (const struct regcache *regcache, int regnum)
 {
index a4ca2ecf7a3089ff63cfb17a3fccf12a0b6137aa..4ad0060fdd1e376238dba12339bbc441c82ed1be 100644 (file)
@@ -243,6 +243,11 @@ protected:
 
   gdb_byte *register_buffer (int regnum) const;
 
+  /* Save a register cache.  The set of registers saved into the
+     regcache determined by the save_reggroup.  COOKED_READ returns
+     zero iff the register's value can't be returned.  */
+  void save (regcache_cooked_read_ftype *cooked_read, void *src);
+
   struct regcache_descr *m_descr;
 
   bool m_has_pseudo;
@@ -250,6 +255,8 @@ protected:
   gdb_byte *m_registers;
   /* Register cache status.  */
   signed char *m_register_status;
+
+  friend class regcache;
 };
 
 /* An abstract class which only has methods doing read.  */
@@ -284,6 +291,8 @@ protected:
                                  bool is_raw);
 };
 
+class readonly_detached_regcache;
+
 /* The register cache for storing raw register values.  */
 
 class regcache : public readable_regcache
@@ -307,15 +316,11 @@ public:
     return m_aspace;
   }
 
-/* Save/restore 'this' regcache.  The set of registers saved /
-   restored into the regcache determined by the save_reggroup /
-   restore_reggroup respectively.  COOKED_READ returns zero iff the
-   register's value can't be returned.  */
-  void save (regcache_cooked_read_ftype *cooked_read, void *src);
-
-  /* Writes to regcache will go through to the target.  SRC is a
+  /* Restore 'this' regcache.  The set of registers restored into
+     the regcache determined by the restore_reggroup.
+     Writes to regcache will go through to the target.  SRC is a
      read-only register cache.  */
-  void restore (struct regcache *src);
+  void restore (readonly_detached_regcache *src);
 
   void cooked_write (int regnum, const gdb_byte *buf);
 
@@ -413,9 +418,26 @@ private:
   registers_changed_ptid (ptid_t ptid);
 };
 
-/* Duplicate the contents of a register cache to a read-only register
-   cache.  The operation is pass-through.  */
-extern struct regcache *regcache_dup (struct regcache *regcache);
+class readonly_detached_regcache : public readable_regcache
+{
+public:
+  readonly_detached_regcache (const regcache &src);
+
+  /* Create a readonly regcache by getting contents from COOKED_READ.  */
+
+  readonly_detached_regcache (gdbarch *gdbarch,
+                             regcache_cooked_read_ftype *cooked_read,
+                             void *src)
+    : readable_regcache (gdbarch, true)
+  {
+    save (cooked_read, src);
+  }
+
+  DISABLE_COPY_AND_ASSIGN (readonly_detached_regcache);
+
+  void raw_update (int regnum) override
+  {}
+};
 
 extern void registers_changed (void);
 extern void registers_changed_ptid (ptid_t);
index da7b93764d2572a3b03ab58ec05153f881cf3bd8..a632c0656e9cb3c4471e3aa5e39977ad9861a73d 100644 (file)
@@ -1202,7 +1202,7 @@ spu_write_pc (struct regcache *regcache, CORE_ADDR pc)
 struct spu2ppu_cache
 {
   struct frame_id frame_id;
-  struct regcache *regcache;
+  readonly_detached_regcache *regcache;
 };
 
 static struct gdbarch *
@@ -1229,7 +1229,7 @@ spu2ppu_prev_register (struct frame_info *this_frame,
   gdb_byte *buf;
 
   buf = (gdb_byte *) alloca (register_size (gdbarch, regnum));
-  regcache_cooked_read (cache->regcache, regnum, buf);
+  cache->regcache->cooked_read (regnum, buf);
   return frame_unwind_got_bytes (this_frame, regnum, buf);
 }
 
@@ -1274,7 +1274,7 @@ spu2ppu_sniffer (const struct frame_unwind *self,
        {
          struct regcache *regcache;
          regcache = get_thread_arch_regcache (inferior_ptid, target_gdbarch ());
-         cache->regcache = regcache_dup (regcache);
+         cache->regcache = new readonly_detached_regcache (*regcache);
          *this_prologue_cache = cache;
          return 1;
        }