Add reg_buffer_common
authorAlan Hayward <alan.hayward@arm.com>
Mon, 11 Jun 2018 09:09:16 +0000 (10:09 +0100)
committerAlan Hayward <alan.hayward@arm.com>
Mon, 11 Jun 2018 09:09:16 +0000 (10:09 +0100)
A purely virtual class containing functions from gdb/regcache.h

Both the gdb regcache structures and gdbserver regcache inherit
directly from reg_buffer_common. This will allow for common
functions which require the use of a regcache.

gdb/
* common/common-regcache.h (reg_buffer_common): New structure.
* regcache.c (reg_buffer::invalidate): Move from detached_regcache.
(reg_buffer::raw_supply): Likewise.
(reg_buffer::raw_supply_integer): Likewise.
(reg_buffer::raw_supply_zeroed): Likewise.
(reg_buffer::raw_collect): Likewise.
(reg_buffer::raw_collect_integer): Likewise.
* regcache.h (reg_buffer::invalidate): Move from detached_regcache.
(reg_buffer::raw_supply): Likewise.
(reg_buffer::raw_supply_integer): Likewise.
(reg_buffer::raw_supply_zeroed): Likewise.
(reg_buffer::raw_collect): Likewise.
(reg_buffer::raw_collect_integer): Likewise.

gdbserver/
* regcache.c (new_register_cache): Use new.
(free_register_cache): Use delete.
(register_data): Use const.
(supply_register): Move body inside regcache.
(regcache::raw_supply): New override function.
(collect_register): Move body inside regcache.
(regcache::raw_collect): New override function.
(regcache::get_register_status): New override function.
* regcache.h (struct regcache): Inherit from reg_buffer_common.

gdb/ChangeLog
gdb/common/common-regcache.h
gdb/gdbserver/ChangeLog
gdb/gdbserver/regcache.c
gdb/gdbserver/regcache.h
gdb/regcache.c
gdb/regcache.h

index 5e41993..9fddd6f 100644 (file)
@@ -1,3 +1,19 @@
+2018-06-11  Alan Hayward  <alan.hayward@arm.com>
+
+       * common/common-regcache.h (reg_buffer_common): New structure.
+       * regcache.c (reg_buffer::invalidate): Move from detached_regcache.
+       (reg_buffer::raw_supply): Likewise.
+       (reg_buffer::raw_supply_integer): Likewise.
+       (reg_buffer::raw_supply_zeroed): Likewise.
+       (reg_buffer::raw_collect): Likewise.
+       (reg_buffer::raw_collect_integer): Likewise.
+       * regcache.h (reg_buffer::invalidate): Move from detached_regcache.
+       (reg_buffer::raw_supply): Likewise.
+       (reg_buffer::raw_supply_integer): Likewise.
+       (reg_buffer::raw_supply_zeroed): Likewise.
+       (reg_buffer::raw_collect): Likewise.
+       (reg_buffer::raw_collect_integer): Likewise.
+
 2018-06-10  Tom Tromey  <tom@tromey.com>
 
        * remote.c (stop_reply_p): Remove typedef.  Don't declare queue.
index 9709ba4..4e6bdde 100644 (file)
@@ -62,4 +62,19 @@ extern enum register_status regcache_raw_read_unsigned
 
 ULONGEST regcache_raw_get_unsigned (struct regcache *regcache, int regnum);
 
+struct reg_buffer_common
+{
+  virtual ~reg_buffer_common () = default;
+
+  /* Get the availability status of the value of register REGNUM in this
+     buffer.  */
+  virtual register_status get_register_status (int regnum) const = 0;
+
+  /* Supply register REGNUM, whose contents are stored in BUF, to REGCACHE.  */
+  virtual void raw_supply (int regnum, const void *buf) = 0;
+
+  /* Collect register REGNUM from REGCACHE and store its contents in BUF.  */
+  virtual void raw_collect (int regnum, void *buf) const = 0;
+};
+
 #endif /* COMMON_REGCACHE_H */
index 6917e68..d11ce5d 100644 (file)
@@ -1,3 +1,15 @@
+2018-06-11  Alan Hayward  <alan.hayward@arm.com>
+
+       * regcache.c (new_register_cache): Use new.
+       (free_register_cache): Use delete.
+       (register_data): Use const.
+       (supply_register): Move body inside regcache.
+       (regcache::raw_supply): New override function.
+       (collect_register): Move body inside regcache.
+       (regcache::raw_collect): New override function.
+       (regcache::get_register_status): New override function.
+       * regcache.h (struct regcache): Inherit from reg_buffer_common.
+
 2018-06-09  Tom Tromey  <tom@tromey.com>
 
        * event-loop.c (gdb_event, gdb_event_p): Remove typedefs.  Don't
index 0718b9f..8383752 100644 (file)
@@ -159,7 +159,7 @@ init_register_cache (struct regcache *regcache,
 struct regcache *
 new_register_cache (const struct target_desc *tdesc)
 {
-  struct regcache *regcache = XCNEW (struct regcache);
+  struct regcache *regcache = new struct regcache;
 
   gdb_assert (tdesc->registers_size != 0);
 
@@ -174,7 +174,7 @@ free_register_cache (struct regcache *regcache)
       if (regcache->registers_owned)
        free (regcache->registers);
       free (regcache->register_status);
-      free (regcache);
+      delete regcache;
     }
 }
 
@@ -300,35 +300,37 @@ regcache_register_size (const struct regcache *regcache, int n)
 }
 
 static unsigned char *
-register_data (struct regcache *regcache, int n, int fetch)
+register_data (const struct regcache *regcache, int n, int fetch)
 {
   return (regcache->registers
          + find_register_by_number (regcache->tdesc, n).offset / 8);
 }
 
-/* Supply register N, whose contents are stored in BUF, to REGCACHE.
-   If BUF is NULL, the register's value is recorded as
-   unavailable.  */
-
 void
 supply_register (struct regcache *regcache, int n, const void *buf)
 {
+  return regcache->raw_supply (n, buf);
+}
+
+/* See common/common-regcache.h.  */
+
+void
+regcache::raw_supply (int n, const void *buf)
+{
   if (buf)
     {
-      memcpy (register_data (regcache, n, 0), buf,
-             register_size (regcache->tdesc, n));
+      memcpy (register_data (this, n, 0), buf, register_size (tdesc, n));
 #ifndef IN_PROCESS_AGENT
-      if (regcache->register_status != NULL)
-       regcache->register_status[n] = REG_VALID;
+      if (register_status != NULL)
+       register_status[n] = REG_VALID;
 #endif
     }
   else
     {
-      memset (register_data (regcache, n, 0), 0,
-             register_size (regcache->tdesc, n));
+      memset (register_data (this, n, 0), 0, register_size (tdesc, n));
 #ifndef IN_PROCESS_AGENT
-      if (regcache->register_status != NULL)
-       regcache->register_status[n] = REG_UNAVAILABLE;
+      if (register_status != NULL)
+       register_status[n] = REG_UNAVAILABLE;
 #endif
     }
 }
@@ -410,8 +412,15 @@ supply_register_by_name (struct regcache *regcache,
 void
 collect_register (struct regcache *regcache, int n, void *buf)
 {
-  memcpy (buf, register_data (regcache, n, 1),
-         register_size (regcache->tdesc, n));
+  regcache->raw_collect (n, buf);
+}
+
+/* See common/common-regcache.h.  */
+
+void
+regcache::raw_collect (int n, void *buf) const
+{
+  memcpy (buf, register_data (this, n, 1), register_size (tdesc, n));
 }
 
 enum register_status
@@ -480,3 +489,16 @@ regcache_write_pc (struct regcache *regcache, CORE_ADDR pc)
 }
 
 #endif
+
+/* See common/common-regcache.h.  */
+
+enum register_status
+regcache::get_register_status (int regnum) const
+{
+#ifndef IN_PROCESS_AGENT
+  gdb_assert (regnum >= 0 && regnum < tdesc->reg_defs.size ());
+  return (enum register_status) (register_status[regnum]);
+#else
+  return REG_VALID;
+#endif
+}
index 2c0df64..352c1df 100644 (file)
@@ -28,23 +28,32 @@ struct target_desc;
    inferior; this is primarily for simplicity, as the performance
    benefit is minimal.  */
 
-struct regcache
+struct regcache : public reg_buffer_common
 {
   /* The regcache's target description.  */
-  const struct target_desc *tdesc;
+  const struct target_desc *tdesc = nullptr;
 
   /* Whether the REGISTERS buffer's contents are valid.  If false, we
      haven't fetched the registers from the target yet.  Not that this
      register cache is _not_ pass-through, unlike GDB's.  Note that
      "valid" here is unrelated to whether the registers are available
      in a traceframe.  For that, check REGISTER_STATUS below.  */
-  int registers_valid;
-  int registers_owned;
-  unsigned char *registers;
+  int registers_valid = 0;
+  int registers_owned = 0;
+  unsigned char *registers = nullptr;
 #ifndef IN_PROCESS_AGENT
   /* One of REG_UNAVAILBLE or REG_VALID.  */
-  unsigned char *register_status;
+  unsigned char *register_status = nullptr;
 #endif
+
+  /* See common/common-regcache.h.  */
+  enum register_status get_register_status (int regnum) const override;
+
+  /* See common/common-regcache.h.  */
+  void raw_supply (int regnum, const void *buf) override;
+
+  /* See common/common-regcache.h.  */
+  void raw_collect (int regnum, void *buf) const override;
 };
 
 struct regcache *init_register_cache (struct regcache *regcache,
index 3eed7b6..c10c588 100644 (file)
@@ -321,6 +321,8 @@ regcache::restore (readonly_detached_regcache *src)
     }
 }
 
+/* See common/common-regcache.h.  */
+
 enum register_status
 reg_buffer::get_register_status (int regnum) const
 {
@@ -330,7 +332,7 @@ reg_buffer::get_register_status (int regnum) const
 }
 
 void
-detached_regcache::invalidate (int regnum)
+reg_buffer::invalidate (int regnum)
 {
   assert_regnum (regnum);
   m_register_status[regnum] = REG_UNKNOWN;
@@ -880,8 +882,10 @@ regcache::cooked_write_part (int regnum, int offset, int len,
   write_part (regnum, offset, len, buf, false);
 }
 
+/* See common/common-regcache.h.  */
+
 void
-detached_regcache::raw_supply (int regnum, const void *buf)
+reg_buffer::raw_supply (int regnum, const void *buf)
 {
   void *regbuf;
   size_t size;
@@ -906,15 +910,11 @@ detached_regcache::raw_supply (int regnum, const void *buf)
     }
 }
 
-/* Supply register REGNUM to REGCACHE.  Value to supply is an integer stored at
-   address ADDR, in target endian, with length ADDR_LEN and sign IS_SIGNED.  If
-   the register size is greater than ADDR_LEN, then the integer will be sign or
-   zero extended.  If the register size is smaller than the integer, then the
-   most significant bytes of the integer will be truncated.  */
+/* See regcache.h.  */
 
 void
-detached_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;
@@ -930,12 +930,10 @@ detached_regcache::raw_supply_integer (int regnum, const gdb_byte *addr,
   m_register_status[regnum] = REG_VALID;
 }
 
-/* Supply register REGNUM with zeroed value to REGCACHE.  This is not the same
-   as calling raw_supply with NULL (which will set the state to
-   unavailable).  */
+/* See regcache.h.  */
 
 void
-detached_regcache::raw_supply_zeroed (int regnum)
+reg_buffer::raw_supply_zeroed (int regnum)
 {
   void *regbuf;
   size_t size;
@@ -949,8 +947,10 @@ detached_regcache::raw_supply_zeroed (int regnum)
   m_register_status[regnum] = REG_VALID;
 }
 
+/* See common/common-regcache.h.  */
+
 void
-regcache::raw_collect (int regnum, void *buf) const
+reg_buffer::raw_collect (int regnum, void *buf) const
 {
   const void *regbuf;
   size_t size;
@@ -963,19 +963,11 @@ regcache::raw_collect (int regnum, void *buf) const
   memcpy (buf, regbuf, size);
 }
 
-/* Transfer a single or all registers belonging to a certain register
-   set to or from a buffer.  This is the main worker function for
-   regcache_supply_regset and regcache_collect_regset.  */
-
-/* Collect register REGNUM from REGCACHE.  Store collected value as an integer
-   at address ADDR, in target endian, with length ADDR_LEN and sign IS_SIGNED.
-   If ADDR_LEN is greater than the register size, then the integer will be sign
-   or zero extended.  If ADDR_LEN is smaller than the register size, then the
-   most significant bytes of the integer will be truncated.  */
+/* See regcache.h.  */
 
 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;
@@ -990,6 +982,10 @@ regcache::raw_collect_integer (int regnum, gdb_byte *addr, int addr_len,
                        byte_order);
 }
 
+/* Transfer a single or all registers belonging to a certain register
+   set to or from a buffer.  This is the main worker function for
+   regcache_supply_regset and regcache_collect_regset.  */
+
 void
 regcache::transfer_regset (const struct regset *regset,
                           struct regcache *out_regcache,
index 2f460a0..3b72986 100644 (file)
@@ -139,7 +139,7 @@ typedef struct cached_reg
 
 /* Buffer of registers.  */
 
-class reg_buffer
+class reg_buffer : public reg_buffer_common
 {
 public:
   reg_buffer (gdbarch *gdbarch, bool has_pseudo);
@@ -149,9 +149,42 @@ public:
   /* Return regcache's architecture.  */
   gdbarch *arch () const;
 
-  /* Get the availability status of the value of register REGNUM in this
-     buffer.  */
-  enum register_status get_register_status (int regnum) const;
+  /* See common/common-regcache.h.  */
+  enum register_status get_register_status (int regnum) const override;
+
+  /* See common/common-regcache.h.  */
+  void raw_collect (int regnum, void *buf) const override;
+
+  /* Collect register REGNUM from REGCACHE.  Store collected value as an integer
+     at address ADDR, in target endian, with length ADDR_LEN and sign IS_SIGNED.
+     If ADDR_LEN is greater than the register size, then the integer will be
+     sign or zero extended.  If ADDR_LEN is smaller than the register size, then
+     the most significant bytes of the integer will be truncated.  */
+  void raw_collect_integer (int regnum, gdb_byte *addr, int addr_len,
+                           bool is_signed) const;
+
+  /* See common/common-regcache.h.  */
+  void raw_supply (int regnum, const void *buf) override;
+
+  void raw_supply (int regnum, const reg_buffer &src)
+  {
+    raw_supply (regnum, src.register_buffer (regnum));
+  }
+
+  /* Supply register REGNUM to REGCACHE.  Value to supply is an integer stored
+     at address ADDR, in target endian, with length ADDR_LEN and sign IS_SIGNED.
+     If the register size is greater than ADDR_LEN, then the integer will be
+     sign or zero extended.  If the register size is smaller than the integer,
+     then the most significant bytes of the integer will be truncated.  */
+  void raw_supply_integer (int regnum, const gdb_byte *addr, int addr_len,
+                          bool is_signed);
+
+  /* Supply register REGNUM with zeroed value to REGCACHE.  This is not the same
+     as calling raw_supply with NULL (which will set the state to
+     unavailable).  */
+  void raw_supply_zeroed (int regnum);
+
+  void invalidate (int regnum);
 
   virtual ~reg_buffer () = default;
 
@@ -231,24 +264,9 @@ public:
     : readable_regcache (gdbarch, has_pseudo)
   {}
 
-  /* Supply register REGNUM, whose contents are stored in BUF, to REGCACHE.  */
-  void raw_supply (int regnum, const void *buf);
-
-  void raw_supply (int regnum, const reg_buffer &src)
-  {
-    raw_supply (regnum, src.register_buffer (regnum));
-  }
-
   void raw_update (int regnum) override
   {}
 
-  void raw_supply_integer (int regnum, const gdb_byte *addr, int addr_len,
-                          bool is_signed);
-
-  void raw_supply_zeroed (int regnum);
-
-  void invalidate (int regnum);
-
   DISABLE_COPY_AND_ASSIGN (detached_regcache);
 };
 
@@ -289,12 +307,6 @@ public:
 
   void raw_update (int regnum) override;
 
-  /* Collect register REGNUM from REGCACHE and store its contents in BUF.  */
-  void raw_collect (int regnum, void *buf) const;
-
-  void raw_collect_integer (int regnum, gdb_byte *addr, int addr_len,
-                           bool is_signed) const;
-
   /* Partial transfer of raw registers.  Perform read, modify, write style
      operations.  */
   void raw_write_part (int regnum, int offset, int len, const gdb_byte *buf);