diff options
author | Alan Hayward <alan.hayward@arm.com> | 2017-08-15 16:40:09 +0100 |
---|---|---|
committer | Alan Hayward <alan.hayward@arm.com> | 2017-08-15 16:40:09 +0100 |
commit | 4ac8135dd8b7568b6185dc2e4ecd9a5d00b8f10b (patch) | |
tree | 53a514dfe9a09ea5b961886fa4f5578ccf41a602 | |
parent | e9a5485336dfecd40c69a35ab09f37203e2d8918 (diff) | |
download | fsf-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.c | 51 | ||||
-rw-r--r-- | gdb/regcache.h | 13 |
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 { |