diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9f78ed33cc3..50524abd51c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2018-02-21 Yao Qi + + * regcache.c (regcache::regcache): Call reg_buffer ctor. + (regcache::arch): Move it to reg_buffer::arch. + (regcache::register_buffer): Likewise. + (regcache::assert_regnum): Likewise. + (regcache::num_raw_registers): Likewise. + * regcache.h (reg_buffer): New class. + (regcache): Inherit reg_buffer. + 2018-02-20 Simon Marchi * remote-sim.c (gdb_os_printf_filtered, gdb_os_vprintf_filtered, diff --git a/gdb/regcache.c b/gdb/regcache.c index ab750c61707..8addc82c68c 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -181,14 +181,13 @@ regcache_register_size (const struct regcache *regcache, int n) return register_size (regcache->arch (), n); } -regcache::regcache (gdbarch *gdbarch, const address_space *aspace_, - bool readonly_p_) - : m_aspace (aspace_), m_readonly_p (readonly_p_) +reg_buffer::reg_buffer (gdbarch *gdbarch, bool has_pseudo) + : m_has_pseudo (has_pseudo) { gdb_assert (gdbarch != NULL); m_descr = regcache_descr (gdbarch); - if (m_readonly_p) + if (has_pseudo) { m_registers = XCNEWVEC (gdb_byte, m_descr->sizeof_cooked_registers); m_register_status = XCNEWVEC (signed char, @@ -199,6 +198,16 @@ regcache::regcache (gdbarch *gdbarch, const address_space *aspace_, m_registers = XCNEWVEC (gdb_byte, m_descr->sizeof_raw_registers); m_register_status = XCNEWVEC (signed char, gdbarch_num_regs (gdbarch)); } +} + +regcache::regcache (gdbarch *gdbarch, const address_space *aspace_, + bool 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_) +{ m_ptid = minus_one_ptid; } @@ -218,7 +227,7 @@ regcache::regcache (readonly_t, const regcache &src) } gdbarch * -regcache::arch () const +reg_buffer::arch () const { return m_descr->gdbarch; } @@ -267,7 +276,7 @@ private: /* Return a pointer to register REGNUM's buffer cache. */ gdb_byte * -regcache::register_buffer (int regnum) const +reg_buffer::register_buffer (int regnum) const { return m_registers + m_descr->register_offset[regnum]; } @@ -390,9 +399,13 @@ regcache::invalidate (int regnum) } void -regcache::assert_regnum (int regnum) const +reg_buffer::assert_regnum (int regnum) const { - gdb_assert (regnum >= 0 && regnum < gdbarch_num_regs (arch ())); + gdb_assert (regnum >= 0); + if (m_has_pseudo) + gdb_assert (regnum < m_descr->nr_cooked_registers); + else + gdb_assert (regnum < gdbarch_num_regs (arch ())); } /* Global structure containing the current regcache. */ @@ -1272,7 +1285,7 @@ regcache_write_pc (struct regcache *regcache, CORE_ADDR pc) } int -regcache::num_raw_registers () const +reg_buffer::num_raw_registers () const { return gdbarch_num_regs (arch ()); } diff --git a/gdb/regcache.h b/gdb/regcache.h index 9e3da8c3fc5..e2c762119d3 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -227,9 +227,44 @@ 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); + + /* Return regcache's architecture. */ + gdbarch *arch () const; + + virtual ~reg_buffer () + { + xfree (m_registers); + xfree (m_register_status); + } + +protected: + /* Assert on the range of REGNUM. */ + void assert_regnum (int regnum) const; + + int num_raw_registers () const; + + gdb_byte *register_buffer (int regnum) const; + + struct regcache_descr *m_descr; + + 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) @@ -244,15 +279,6 @@ public: DISABLE_COPY_AND_ASSIGN (regcache); - ~regcache () - { - xfree (m_registers); - xfree (m_register_status); - } - - /* Return regcache's architecture. */ - gdbarch *arch () const; - /* Return REGCACHE's address space. */ const address_space *aspace () const { @@ -339,14 +365,9 @@ public: static void regcache_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid); protected: regcache (gdbarch *gdbarch, const address_space *aspace_, bool readonly_p_); - - int num_raw_registers () const; - static std::forward_list 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, @@ -357,21 +378,10 @@ private: int regnum, const void *in_buf, void *out_buf, size_t size) const; - /* Assert on the range of REGNUM. */ - void assert_regnum (int regnum) const; - - struct regcache_descr *m_descr; - /* The address space of this register cache (for registers where it makes sense, like PC or SP). */ const address_space * const 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