]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
New class reg_buffer
authorYao Qi <yao.qi@linaro.org>
Fri, 22 Sep 2017 13:02:38 +0000 (14:02 +0100)
committerYao Qi <yao.qi@linaro.org>
Fri, 13 Oct 2017 10:52:11 +0000 (11:52 +0100)
This patch splits regcache, moves part of it to reg_buffer, which is a
buffer to hold register contents, and also their status.  reg_buffer may
or may not hold pseudo registers.  Class reg_buffer has methods supply and
collect.

gdb:

2017-09-22  Yao Qi  <yao.qi@linaro.org>
:
* regcache.c (regcache_descr):
(regcache_register_size):
(get_regcache_aspace):
(regcache::save):
(regcache::save):
(regcache::restore):
(regcache_register_status):
(regcache::get_register_status):
(regcache::invalidate):
(regcache::raw_update):
(regcache::raw_read):
(regcache::cooked_read):
(regcache::cooked_read_value):
(regcache_raw_set_cached_value):
(regcache_raw_supply):
(regcache::raw_supply):
(regcache::raw_supply_integer):
(regcache_raw_collect):
(regcache::raw_collect):
* regcache.h (typedef struct cached_reg):
(public:):
(public:):
(protected:):
(private:):

gdb/regcache.c
gdb/regcache.h

index eb2f9673987e3253b52ec5074234b3cad831c4da..8978b14f257f3474faab01cb4fc969b0fdcdce2e 100644 (file)
@@ -152,6 +152,50 @@ regcache_descr (struct gdbarch *gdbarch)
                                                 regcache_descr_handle);
 }
 
+reg_buffer::reg_buffer (gdbarch *gdbarch, bool has_pseudo)
+  : m_has_pseudo (has_pseudo)
+{
+  gdb_assert (gdbarch != NULL);
+  m_descr = regcache_descr (gdbarch);
+
+  if (has_pseudo)
+    {
+      m_registers = XCNEWVEC (gdb_byte, m_descr->sizeof_cooked_registers);
+      m_register_status = XCNEWVEC (signed char,
+                                   m_descr->sizeof_cooked_register_status);
+    }
+  else
+    {
+      m_registers = XCNEWVEC (gdb_byte, m_descr->sizeof_raw_registers);
+      m_register_status = XCNEWVEC (signed char,
+                                   m_descr->sizeof_raw_register_status);
+    }
+}
+
+void reg_buffer::validate (int regnum) const
+{
+  gdb_assert (regnum >= 0);
+  if (m_has_pseudo)
+    gdb_assert (regnum < m_descr->nr_cooked_registers);
+  else
+    gdb_assert (regnum < m_descr->nr_raw_registers);
+}
+
+void
+reg_buffer::clear ()
+{
+  if (m_has_pseudo)
+    {
+      memset (m_registers, 0, m_descr->sizeof_cooked_registers);
+      memset (m_register_status, 0, m_descr->sizeof_cooked_register_status);
+    }
+  else
+    {
+      memset (m_registers, 0, m_descr->sizeof_raw_registers);
+      memset (m_register_status, 0, m_descr->sizeof_raw_register_status);
+    }
+}
+
 /* Utility functions returning useful register attributes stored in
    the regcache descr.  */
 
@@ -190,23 +234,12 @@ regcache_register_size (const struct regcache *regcache, int n)
 
 regcache::regcache (gdbarch *gdbarch, address_space *aspace_,
                    bool readonly_p_)
-  : m_aspace (aspace_), m_readonly_p (readonly_p_)
+  /* The register buffers.  A read-only register cache can hold the
+     full [0 .. gdbarch_num_regs + gdbarch_num_pseudo_regs) while a
+     read/write register cache can only hold [0 .. gdbarch_num_regs).  */
+  : reg_buffer (gdbarch, readonly_p_),
+    m_aspace (aspace_), m_readonly_p (readonly_p_)
 {
-  gdb_assert (gdbarch != NULL);
-  m_descr = regcache_descr (gdbarch);
-
-  if (m_readonly_p)
-    {
-      m_registers = XCNEWVEC (gdb_byte, m_descr->sizeof_cooked_registers);
-      m_register_status = XCNEWVEC (signed char,
-                                   m_descr->sizeof_cooked_register_status);
-    }
-  else
-    {
-      m_registers = XCNEWVEC (gdb_byte, m_descr->sizeof_raw_registers);
-      m_register_status = XCNEWVEC (signed char,
-                                   m_descr->sizeof_raw_register_status);
-    }
   m_ptid = minus_one_ptid;
 }
 
@@ -289,8 +322,9 @@ get_regcache_aspace (const struct regcache *regcache)
 /* Return  a pointer to register REGNUM's buffer cache.  */
 
 gdb_byte *
-regcache::register_buffer (int regnum) const
+reg_buffer::register_buffer (int regnum) const
 {
+  validate (regnum);
   return m_registers + m_descr->register_offset[regnum];
 }
 
@@ -313,8 +347,7 @@ regcache::save (regcache_cooked_read_ftype *cooked_read,
      target.  */
   gdb_assert (m_readonly_p);
   /* Clear the dest.  */
-  memset (m_registers, 0, m_descr->sizeof_cooked_registers);
-  memset (m_register_status, 0, m_descr->sizeof_cooked_register_status);
+  clear ();
   /* Copy over any registers (identified by their membership in the
      save_reggroup) and mark them as valid.  The full [0 .. gdbarch_num_regs +
      gdbarch_num_pseudo_regs) range is checked since some architectures need
@@ -331,7 +364,7 @@ regcache::save (regcache_cooked_read_ftype *cooked_read,
          if (status != REG_VALID)
            memset (dst_buf, 0, register_size (gdbarch, regnum));
 
-         m_register_status[regnum] = status;
+         set_register_status (regnum, status);
        }
     }
 }
@@ -354,7 +387,7 @@ regcache::restore (struct regcache *src)
     {
       if (gdbarch_register_reggroup_p (gdbarch, regnum, restore_reggroup))
        {
-         if (src->m_register_status[regnum] == REG_VALID)
+         if (src->get_register_status (regnum) == REG_VALID)
            cooked_write (regnum, src->register_buffer (regnum));
        }
     }
@@ -385,17 +418,19 @@ regcache_register_status (const struct regcache *regcache, int regnum)
 }
 
 enum register_status
-regcache::get_register_status (int regnum) const
+reg_buffer::get_register_status (int regnum) const
 {
-  gdb_assert (regnum >= 0);
-  if (m_readonly_p)
-    gdb_assert (regnum < m_descr->nr_cooked_registers);
-  else
-    gdb_assert (regnum < m_descr->nr_raw_registers);
-
+  validate (regnum);
   return (enum register_status) m_register_status[regnum];
 }
 
+void
+reg_buffer::set_register_status (int regnum, enum register_status status)
+{
+  validate (regnum);
+  m_register_status[regnum] = status;
+}
+
 void
 regcache_invalidate (struct regcache *regcache, int regnum)
 {
@@ -409,7 +444,7 @@ regcache::invalidate (int regnum)
   gdb_assert (regnum >= 0);
   gdb_assert (!m_readonly_p);
   gdb_assert (regnum < m_descr->nr_raw_registers);
-  m_register_status[regnum] = REG_UNKNOWN;
+  set_register_status (regnum, REG_UNKNOWN);
 }
 
 /* Global structure containing the current regcache.  */
@@ -573,8 +608,8 @@ regcache::raw_update (int regnum)
       /* A number of targets can't access the whole set of raw
         registers (because the debug API provides no means to get at
         them).  */
-      if (m_register_status[regnum] == REG_UNKNOWN)
-       m_register_status[regnum] = REG_UNAVAILABLE;
+      if (get_register_status (regnum) == REG_UNKNOWN)
+       set_register_status (regnum, REG_UNAVAILABLE);
     }
 }
 
@@ -590,13 +625,13 @@ regcache::raw_read (int regnum, gdb_byte *buf)
   gdb_assert (buf != NULL);
   raw_update (regnum);
 
-  if (m_register_status[regnum] != REG_VALID)
+  if (get_register_status(regnum) != REG_VALID)
     memset (buf, 0, m_descr->sizeof_register[regnum]);
   else
     memcpy (buf, register_buffer (regnum),
            m_descr->sizeof_register[regnum]);
 
-  return (enum register_status) m_register_status[regnum];
+  return get_register_status (regnum);
 }
 
 enum register_status
@@ -688,17 +723,17 @@ regcache::cooked_read (int regnum, gdb_byte *buf)
   if (regnum < m_descr->nr_raw_registers)
     return raw_read (regnum, buf);
   else if (m_readonly_p
-          && m_register_status[regnum] != REG_UNKNOWN)
+          && get_register_status(regnum) != REG_UNKNOWN)
     {
       /* Read-only register cache, perhaps the cooked value was
         cached?  */
-      if (m_register_status[regnum] == REG_VALID)
+      if (get_register_status (regnum) == REG_VALID)
        memcpy (buf, register_buffer (regnum),
                m_descr->sizeof_register[regnum]);
       else
        memset (buf, 0, m_descr->sizeof_register[regnum]);
 
-      return (enum register_status) m_register_status[regnum];
+      return get_register_status(regnum);
     }
   else if (gdbarch_pseudo_register_read_value_p (m_descr->gdbarch))
     {
@@ -740,7 +775,7 @@ regcache::cooked_read_value (int regnum)
   gdb_assert (regnum < m_descr->nr_cooked_registers);
 
   if (regnum < m_descr->nr_raw_registers
-      || (m_readonly_p && m_register_status[regnum] != REG_UNKNOWN)
+      || (m_readonly_p && get_register_status (regnum) != REG_UNKNOWN)
       || !gdbarch_pseudo_register_read_value_p (m_descr->gdbarch))
     {
       struct value *result;
@@ -837,8 +872,10 @@ regcache_raw_set_cached_value (struct regcache *regcache, int regnum,
 }
 
 void
-regcache::raw_set_cached_value (int regnum, const gdb_byte *buf)
+reg_buffer::raw_set_cached_value (int regnum, const gdb_byte *buf)
 {
+  validate (regnum);
+
   memcpy (register_buffer (regnum), buf,
          m_descr->sizeof_register[regnum]);
   m_register_status[regnum] = REG_VALID;
@@ -1026,13 +1063,12 @@ regcache_raw_supply (struct regcache *regcache, int regnum, const void *buf)
 }
 
 void
-regcache::raw_supply (int regnum, const void *buf)
+reg_buffer::raw_supply (int regnum, const void *buf)
 {
   void *regbuf;
   size_t size;
 
-  gdb_assert (regnum >= 0 && regnum < m_descr->nr_raw_registers);
-  gdb_assert (!m_readonly_p);
+  validate (regnum);
 
   regbuf = register_buffer (regnum);
   size = m_descr->sizeof_register[regnum];
@@ -1059,15 +1095,14 @@ regcache::raw_supply (int regnum, const void *buf)
    most significant bytes of the integer will be truncated.  */
 
 void
-regcache::raw_supply_integer (int regnum, const gdb_byte *addr, int addr_len,
-                             bool is_signed)
+reg_buffer::raw_supply_integer (int regnum, const gdb_byte *addr, int addr_len,
+                               bool is_signed)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (m_descr->gdbarch);
   gdb_byte *regbuf;
   size_t regsize;
 
-  gdb_assert (regnum >= 0 && regnum < m_descr->nr_raw_registers);
-  gdb_assert (!m_readonly_p);
+  validate (regnum);
 
   regbuf = register_buffer (regnum);
   regsize = m_descr->sizeof_register[regnum];
@@ -1082,14 +1117,13 @@ regcache::raw_supply_integer (int regnum, const gdb_byte *addr, int addr_len,
    unavailable).  */
 
 void
-regcache::raw_supply_zeroed (int regnum)
+reg_buffer::raw_supply_zeroed (int regnum)
 {
   void *regbuf;
   size_t size;
 
-  gdb_assert (regnum >= 0 && regnum < m_descr->nr_raw_registers);
-  gdb_assert (!m_readonly_p);
-
+  validate (regnum);
   regbuf = register_buffer (regnum);
   size = m_descr->sizeof_register[regnum];
 
@@ -1107,13 +1141,13 @@ regcache_raw_collect (const struct regcache *regcache, int regnum, void *buf)
 }
 
 void
-regcache::raw_collect (int regnum, void *buf) const
+reg_buffer::raw_collect (int regnum, void *buf) const
 {
   const void *regbuf;
   size_t size;
 
   gdb_assert (buf != NULL);
-  gdb_assert (regnum >= 0 && regnum < m_descr->nr_raw_registers);
+  validate (regnum);
 
   regbuf = register_buffer (regnum);
   size = m_descr->sizeof_register[regnum];
@@ -1131,14 +1165,14 @@ regcache::raw_collect (int regnum, void *buf) const
    most significant bytes of the integer will be truncated.  */
 
 void
-regcache::raw_collect_integer (int regnum, gdb_byte *addr, int addr_len,
-                              bool is_signed) const
+reg_buffer::raw_collect_integer (int regnum, gdb_byte *addr, int addr_len,
+                                bool is_signed) const
 {
   enum bfd_endian byte_order = gdbarch_byte_order (m_descr->gdbarch);
   const gdb_byte *regbuf;
   size_t regsize;
 
-  gdb_assert (regnum >= 0 && regnum < m_descr->nr_raw_registers);
+  validate (regnum);
 
   regbuf = register_buffer (regnum);
   regsize = m_descr->sizeof_register[regnum];
index 460d83facdc1dd74b5075fa7df7f40a19b34c1f3..d06c410bfbfa46bc167025060ed47c6b843830ff 100644 (file)
@@ -235,9 +235,59 @@ typedef struct cached_reg
   gdb_byte *data;
 } cached_reg_t;
 
+/* Buffer of registers.  */
+
+class reg_buffer
+{
+public:
+  reg_buffer (gdbarch *gdbarch, bool has_pseudo);
+
+  DISABLE_COPY_AND_ASSIGN (reg_buffer);
+
+  gdbarch *arch () const;
+
+  virtual ~reg_buffer ()
+  {
+    xfree (m_registers);
+    xfree (m_register_status);
+  }
+
+  void clear ();
+
+  enum register_status get_register_status (int regnum) const;
+  void set_register_status (int regnum, enum register_status status);
+
+  void raw_collect (int regnum, void *buf) const;
+
+  void raw_collect_integer (int regnum, gdb_byte *addr, int addr_len,
+                           bool is_signed) const;
+
+  void raw_supply (int regnum, const void *buf);
+
+  void raw_supply_integer (int regnum, const gdb_byte *addr, int addr_len,
+                          bool is_signed);
+
+  void raw_supply_zeroed (int regnum);
+
+  void raw_set_cached_value (int regnum, const gdb_byte *buf);
+
+protected:
+  gdb_byte *register_buffer (int regnum) const;
+  struct regcache_descr *m_descr;
+
+private:
+  void validate (int regnum) const;
+
+  bool m_has_pseudo;
+  /* The register buffers.  */
+  gdb_byte *m_registers;
+  /* Register cache status.  */
+  signed char *m_register_status;
+};
+
 /* The register cache for storing raw register values.  */
 
-class regcache
+class regcache : public reg_buffer
 {
 public:
   regcache (gdbarch *gdbarch, address_space *aspace_)
@@ -252,12 +302,6 @@ public:
 
   DISABLE_COPY_AND_ASSIGN (regcache);
 
-  ~regcache ()
-  {
-    xfree (m_registers);
-    xfree (m_register_status);
-  }
-
   gdbarch *arch () const;
 
   address_space *aspace () const
@@ -290,22 +334,6 @@ public:
 
   void raw_update (int regnum);
 
-  void raw_collect (int regnum, void *buf) const;
-
-  void raw_collect_integer (int regnum, gdb_byte *addr, int addr_len,
-                           bool is_signed) const;
-
-  void raw_supply (int regnum, const void *buf);
-
-  void raw_supply_integer (int regnum, const gdb_byte *addr, int addr_len,
-                          bool is_signed);
-
-  void raw_supply_zeroed (int regnum);
-
-  enum register_status get_register_status (int regnum) const;
-
-  void raw_set_cached_value (int regnum, const gdb_byte *buf);
-
   void invalidate (int regnum);
 
   enum register_status raw_read_part (int regnum, int offset, int len,
@@ -349,8 +377,6 @@ protected:
   static std::forward_list<regcache *> current_regcache;
 
 private:
-  gdb_byte *register_buffer (int regnum) const;
-
   void restore (struct regcache *src);
 
   enum register_status xfer_part (int regnum, int offset, int len, void *in,
@@ -361,18 +387,10 @@ private:
                        int regnum, const void *in_buf,
                        void *out_buf, size_t size) const;
 
-  struct regcache_descr *m_descr;
-
   /* The address space of this register cache (for registers where it
      makes sense, like PC or SP).  */
   struct address_space *m_aspace;
 
-  /* The register buffers.  A read-only register cache can hold the
-     full [0 .. gdbarch_num_regs + gdbarch_num_pseudo_regs) while a read/write
-     register cache can only hold [0 .. gdbarch_num_regs).  */
-  gdb_byte *m_registers;
-  /* Register cache status.  */
-  signed char *m_register_status;
   /* Is this a read-only cache?  A read-only cache is used for saving
      the target's register state (e.g, across an inferior function
      call or just before forcing a function return).  A read-only