aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Hayward <alan.hayward@arm.com>2017-08-15 16:40:09 +0100
committerAlan Hayward <alan.hayward@arm.com>2017-08-15 16:40:09 +0100
commit4ac8135dd8b7568b6185dc2e4ecd9a5d00b8f10b (patch)
tree53a514dfe9a09ea5b961886fa4f5578ccf41a602
parente9a5485336dfecd40c69a35ab09f37203e2d8918 (diff)
downloadfsf-binutils-gdb-4ac8135dd8b7568b6185dc2e4ecd9a5d00b8f10b.zip
fsf-binutils-gdb-4ac8135dd8b7568b6185dc2e4ecd9a5d00b8f10b.tar.gz
fsf-binutils-gdb-4ac8135dd8b7568b6185dc2e4ecd9a5d00b8f10b.tar.bz2
[PATCH 5/7]: Regcache: Allow writable regcache
-rw-r--r--gdb/regcache.c51
-rw-r--r--gdb/regcache.h13
2 files changed, 34 insertions, 30 deletions
diff --git a/gdb/regcache.c b/gdb/regcache.c
index 5405dba..9d04c7b 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -189,29 +189,32 @@ regcache_register_size (const struct regcache *regcache, int n)
}
regcache::regcache (gdbarch *gdbarch, address_space *aspace_,
- bool readonly_p_)
+ bool readonly_p_, bool allocate_registers)
: m_aspace (aspace_), m_readonly_p (readonly_p_)
{
gdb_assert (gdbarch != NULL);
m_descr = regcache_descr (gdbarch);
- if (m_readonly_p)
+ if (allocate_registers)
{
+ /* Need extra space to store the additional cooked registers for when
+ the detached regcache is used to save a regcache. */
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);
}
+
+ /* All status' are initialised to REG_UNKNOWN. */
+ m_register_status = XCNEWVEC (signed char,
+ m_descr->sizeof_cooked_register_status);
}
target_regcache::target_regcache (gdbarch *gdbarch, address_space *aspace_)
- : regcache (gdbarch, aspace_, false)
+ : regcache (gdbarch, aspace_, false, false)
{
+ /* Only allocate the raw registers - cooked registers are not cached.
+ Note that the register status is still fully allocated, to allow the
+ checking of the state of any register. */
+ m_registers = XCNEWVEC (gdb_byte, m_descr->sizeof_raw_registers);
+
m_ptid = minus_one_ptid;
/* A target_regcache should never be readonly. */
@@ -359,9 +362,9 @@ regcache::restore_to (target_regcache *dst)
/* Duplicate detached regcache to a detached regcache. */
regcache*
-regcache::dup ()
+regcache::dup (bool readonly_p)
{
- regcache *new_regcache = new regcache (arch (), aspace ());
+ regcache *new_regcache = new regcache (arch (), aspace (), readonly_p);
memcpy (new_regcache->m_registers, m_registers,
m_descr->sizeof_cooked_registers);
@@ -373,9 +376,9 @@ regcache::dup ()
/* Duplicate a target_regcache to a detached regcache. */
regcache*
-target_regcache::dup ()
+target_regcache::dup (bool readonly_p)
{
- regcache *new_regcache = new regcache (arch (), aspace ());
+ regcache *new_regcache = new regcache (arch (), aspace (), readonly_p);
new_regcache->save (do_cooked_read, (void *) this);
return new_regcache;
}
@@ -391,14 +394,17 @@ enum register_status
regcache::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);
-
+ gdb_assert (regnum < m_descr->nr_cooked_registers);
return (enum register_status) m_register_status[regnum];
}
+enum register_status
+target_regcache::get_register_status (int regnum) const
+{
+ gdb_assert (regnum < m_descr->nr_raw_registers);
+ return regcache::get_register_status (regnum);
+}
+
void
regcache_invalidate (struct regcache *regcache, int regnum)
{
@@ -707,8 +713,7 @@ regcache::cooked_read (int regnum, gdb_byte *buf)
gdb_assert (regnum < m_descr->nr_cooked_registers);
if (regnum < m_descr->nr_raw_registers)
return raw_read (regnum, buf);
- else if (m_readonly_p
- && m_register_status[regnum] != REG_UNKNOWN)
+ else if (m_register_status[regnum] != REG_UNKNOWN)
{
/* Read-only register cache, perhaps the cooked value was
cached? */
@@ -760,7 +765,7 @@ regcache::cooked_read_value (int regnum)
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_register_status[regnum] != REG_UNKNOWN
|| !gdbarch_pseudo_register_read_value_p (m_descr->gdbarch))
{
struct value *result;
diff --git a/gdb/regcache.h b/gdb/regcache.h
index 1437dac..f4408a5 100644
--- a/gdb/regcache.h
+++ b/gdb/regcache.h
@@ -235,9 +235,8 @@ typedef struct cached_reg
class regcache
{
public:
- regcache (gdbarch *gdbarch, address_space *aspace_)
- : regcache (gdbarch, aspace_, true)
- {}
+ regcache (gdbarch *gdbarch, address_space *aspace_, bool readonly_p_ = true,
+ bool allocate_registers = true);
regcache (const regcache &) = delete;
void operator= (const regcache &) = delete;
@@ -256,7 +255,7 @@ public:
}
/* Duplicate self into a new regcache. */
- virtual regcache* dup ();
+ virtual regcache* dup (bool readonly_p = true);
/* Copy the register contents from a target_regcache to self.
All cooked registers are read and cached. */
@@ -300,7 +299,7 @@ public:
void raw_supply_zeroed (int regnum);
- enum register_status get_register_status (int regnum) const;
+ virtual enum register_status get_register_status (int regnum) const;
void raw_set_cached_value (int regnum, const gdb_byte *buf);
@@ -337,7 +336,6 @@ public:
void debug_print_register (const char *func, int regno);
protected:
- regcache (gdbarch *gdbarch, address_space *aspace_, bool readonly_p_);
gdb_byte *register_buffer (int regnum) const;
@@ -392,13 +390,14 @@ public:
void restore_to (target_regcache *dst) = delete;
/* Duplicate self into a new regcache. Result is not a target_regcache. */
- regcache* dup ();
+ regcache* dup (bool readonly_p = true);
/* Overridden regcache methods. These versions will pass the read/write
through to the target. */
enum register_status raw_read (int regnum, gdb_byte *buf);
virtual void raw_write (int regnum, const gdb_byte *buf);
void raw_update (int regnum);
+ enum register_status get_register_status (int regnum) const;
ptid_t ptid () const
{