From 9c861883169cb9eec4581ab6db3a1b711e79ee10 Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Mon, 11 Jun 2018 10:09:16 +0100 Subject: [PATCH] Add reg_buffer_common 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 | 16 ++++++++++ gdb/common/common-regcache.h | 15 +++++++++ gdb/gdbserver/ChangeLog | 12 +++++++ gdb/gdbserver/regcache.c | 56 ++++++++++++++++++++++---------- gdb/gdbserver/regcache.h | 21 ++++++++---- gdb/regcache.c | 46 ++++++++++++-------------- gdb/regcache.h | 62 +++++++++++++++++++++--------------- 7 files changed, 155 insertions(+), 73 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 5e4199345c..9fddd6f976 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,19 @@ +2018-06-11 Alan Hayward + + * 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 * remote.c (stop_reply_p): Remove typedef. Don't declare queue. diff --git a/gdb/common/common-regcache.h b/gdb/common/common-regcache.h index 9709ba414e..4e6bdde4fc 100644 --- a/gdb/common/common-regcache.h +++ b/gdb/common/common-regcache.h @@ -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 */ diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 6917e68fa2..d11ce5d81f 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,15 @@ +2018-06-11 Alan Hayward + + * 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 * event-loop.c (gdb_event, gdb_event_p): Remove typedefs. Don't diff --git a/gdb/gdbserver/regcache.c b/gdb/gdbserver/regcache.c index 0718b9f9a0..83837525a1 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,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 +} diff --git a/gdb/gdbserver/regcache.h b/gdb/gdbserver/regcache.h index 2c0df648f6..352c1df3f9 100644 --- a/gdb/gdbserver/regcache.h +++ b/gdb/gdbserver/regcache.h @@ -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, diff --git a/gdb/regcache.c b/gdb/regcache.c index 3eed7b6304..c10c588c30 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -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, diff --git a/gdb/regcache.h b/gdb/regcache.h index 2f460a02fa..3b72986db1 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); @@ -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); -- 2.34.1