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. */
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;
}
/* 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];
}
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
if (status != REG_VALID)
memset (dst_buf, 0, register_size (gdbarch, regnum));
- m_register_status[regnum] = status;
+ set_register_status (regnum, status);
}
}
}
{
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));
}
}
}
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)
{
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. */
/* 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);
}
}
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
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))
{
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;
}
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;
}
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];
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];
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];
}
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];
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];
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_)
DISABLE_COPY_AND_ASSIGN (regcache);
- ~regcache ()
- {
- xfree (m_registers);
- xfree (m_register_status);
- }
-
gdbarch *arch () const;
address_space *aspace () const
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,
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,
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