[PATCH v2 03/10] Add reg_buffer_common

Alan Hayward
2018-06-06T15:17:11Z

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.

2018-06-06 Alan Hayward <alan.hayward@arm.com>

gdb/
* common/common-regcache.h (reg_buffer_common): New structure.
* regcache.h (reg_buffer_common:get_register_status) Add override.
(reg_buffer_common:raw_supply): Add dummy function.
reg_buffer_common:raw_collect): Likewise
(readable_regcache:raw_supply) Add override.
(detached_regcache:raw_collect) Likewise.

gdbserver/
* regcache.c (new_register_cache): Use new.
(free_register_cache): Use delete.
register_data): Use const.
(supply_register): Call member function.
(regcache::raw_supply): Replacement for supply_register.
(collect_register): Call member function.
(regcache::raw_collect): Replacement for collect_register.
(regcache::get_register_status): New function.
* regcache.h (regcache:raw_supply): Add dummy function.
(regcache:raw_collect): Likewise
(regcache:get_register_status) Likewise.
---
gdb/common/common-regcache.h | 8 ++++++++
gdb/gdbserver/regcache.c | 47 ++++++++++++++++++++++++++++++++------------
gdb/gdbserver/regcache.h | 18 +++++++++++------
gdb/regcache.h | 19 ++++++++++++++----
4 files changed, 69 insertions(+), 23 deletions(-)

diff --git a/gdb/common/common-regcache.h b/gdb/common/common-regcache.h
index 696ba00955..487da0a7fb 100644
--- a/gdb/common/common-regcache.h
+++ b/gdb/common/common-regcache.h
@@ -62,4 +62,12 @@ 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;
+ virtual void raw_supply (int regnum, const void *buf) = 0;
+ virtual void raw_collect (int regnum, void *buf) const = 0;
+ virtual register_status get_register_status (int regnum) const = 0;
+};
+
#endif /* COMMON_REGCACHE_H */
diff --git a/gdb/gdbserver/regcache.c b/gdb/gdbserver/regcache.c
index 0718b9f9a0..857721ee3d 100644
--- a/gdb/gdbserver/regcache.c
+++ b/gdb/gdbserver/regcache.c
@@ -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,7 +300,7 @@ 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);
@@ -312,23 +312,27 @@ register_data (struct regcache *regcache, int n, int fetch)

void
supply_register (struct regcache *regcache, int n, const void *buf)
+{
+ return regcache->raw_supply (n, buf);
+}
+
+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,10 +414,16 @@ 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);
+}
+
+void
+regcache::raw_collect (int n, void *buf) const
+{
+ memcpy (buf, register_data (this, n, 1), register_size (tdesc, n));
}

+
enum register_status
regcache_raw_read_unsigned (struct regcache *regcache, int regnum,
ULONGEST *val)
@@ -480,3 +490,14 @@ regcache_write_pc (struct regcache *regcache, CORE_ADDR pc)
}

#endif
+
+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
+}
diff --git a/gdb/gdbserver/regcache.h b/gdb/gdbserver/regcache.h
index 2c0df648f6..1842f1d9cf 100644
--- a/gdb/gdbserver/regcache.h
+++ b/gdb/gdbserver/regcache.h
@@ -28,23 +28,29 @@ 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
+
+ void raw_supply (int regnum, const void *buf) override;
+
+ void raw_collect (int regnum, void *buf) const override;
+
+ enum register_status get_register_status (int regnum) const override;
};

struct regcache *init_register_cache (struct regcache *regcache,
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 3edddf47e1..b559a10752 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -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);
@@ -151,13 +151,24 @@ public:

/* Get the availability status of the value of register REGNUM in this
buffer. */
- enum register_status get_register_status (int regnum) const;
+ enum register_status get_register_status (int regnum) const override;

virtual ~reg_buffer ()
{
xfree (m_registers);
xfree (m_register_status);
}
+
+ virtual void raw_supply (int regnum, const void *buf) override
+ {
+ gdb_assert (false);
+ }
+
+ virtual void raw_collect (int regnum, void *buf) const override
+ {
+ gdb_assert (false);
+ }
+
protected:
/* Assert on the range of REGNUM. */
void assert_regnum (int regnum) const;
@@ -235,7 +246,7 @@ public:
{}

/* 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 void *buf) override;

void raw_supply (int regnum, const reg_buffer &src)
{
@@ -293,7 +304,7 @@ 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 (int regnum, void *buf) const override;

void raw_collect_integer (int regnum, gdb_byte *addr, int addr_len,
bool is_signed) const;
--
2.15.1 (Apple Git-101)