From: Alan Hayward Date: Tue, 15 Aug 2017 15:38:22 +0000 (+0100) Subject: [PATCH 1/7] Regcache: Subclass ptid functionality to target_regcache X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=15587be5bd4f8e1db324aa4f8950369a628ccc21;p=thirdparty%2Fbinutils-gdb.git [PATCH 1/7] Regcache: Subclass ptid functionality to target_regcache --- diff --git a/gdb/gdbarch-selftests.c b/gdb/gdbarch-selftests.c index 096ba975f75..a6251d2a9f8 100644 --- a/gdb/gdbarch-selftests.c +++ b/gdb/gdbarch-selftests.c @@ -27,11 +27,11 @@ namespace selftests { /* A read-write regcache which doesn't write the target. */ -class regcache_test : public regcache +class regcache_test : public target_regcache { public: explicit regcache_test (struct gdbarch *gdbarch) - : regcache (gdbarch, NULL, false) + : target_regcache (gdbarch, NULL) { set_ptid (inferior_ptid); diff --git a/gdb/regcache.c b/gdb/regcache.c index e8f92d684dd..3d6ca86006f 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -207,7 +207,15 @@ regcache::regcache (gdbarch *gdbarch, address_space *aspace_, m_register_status = XCNEWVEC (signed char, m_descr->sizeof_raw_register_status); } +} + +target_regcache::target_regcache (gdbarch *gdbarch, address_space *aspace_) + : regcache (gdbarch, aspace_, false) +{ m_ptid = minus_one_ptid; + + /* A target_regcache should never be readonly. */ + gdb_assert (!m_readonly_p); } static enum register_status @@ -440,25 +448,25 @@ regcache::invalidate (int regnum) recording if the register values have been changed (eg. by the user). Therefore all registers must be written back to the target when appropriate. */ -std::forward_list regcache::current_regcache; +std::forward_list target_regcache::current_regcache; -struct regcache * +target_regcache * get_thread_arch_aspace_regcache (ptid_t ptid, struct gdbarch *gdbarch, struct address_space *aspace) { - for (const auto ®cache : regcache::current_regcache) + for (const auto ®cache : target_regcache::current_regcache) if (ptid_equal (regcache->ptid (), ptid) && regcache->arch () == gdbarch) return regcache; - regcache *new_regcache = new regcache (gdbarch, aspace, false); + target_regcache *new_regcache = new target_regcache (gdbarch, aspace); - regcache::current_regcache.push_front (new_regcache); + target_regcache::current_regcache.push_front (new_regcache); new_regcache->set_ptid (ptid); return new_regcache; } -struct regcache * +target_regcache * get_thread_arch_regcache (ptid_t ptid, struct gdbarch *gdbarch) { struct address_space *aspace; @@ -479,7 +487,7 @@ get_thread_arch_regcache (ptid_t ptid, struct gdbarch *gdbarch) static ptid_t current_thread_ptid; static struct gdbarch *current_thread_arch; -struct regcache * +target_regcache * get_thread_regcache (ptid_t ptid) { if (!current_thread_arch || !ptid_equal (current_thread_ptid, ptid)) @@ -491,7 +499,7 @@ get_thread_regcache (ptid_t ptid) return get_thread_arch_regcache (ptid, current_thread_arch); } -struct regcache * +target_regcache * get_current_regcache (void) { return get_thread_regcache (inferior_ptid); @@ -502,7 +510,7 @@ get_current_regcache (void) struct regcache * get_thread_regcache_for_ptid (ptid_t ptid) { - return get_thread_regcache (ptid); + return (struct regcache*) get_thread_regcache (ptid); } /* Observer for the target_changed event. */ @@ -516,9 +524,9 @@ regcache_observer_target_changed (struct target_ops *target) /* Update global variables old ptids to hold NEW_PTID if they were holding OLD_PTID. */ void -regcache::regcache_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid) +target_regcache::regcache_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid) { - for (auto ®cache : regcache::current_regcache) + for (auto ®cache : target_regcache::current_regcache) { if (ptid_equal (regcache->ptid (), old_ptid)) regcache->set_ptid (new_ptid); @@ -539,15 +547,15 @@ regcache::regcache_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid) void registers_changed_ptid (ptid_t ptid) { - for (auto oit = regcache::current_regcache.before_begin (), + for (auto oit = target_regcache::current_regcache.before_begin (), it = std::next (oit); - it != regcache::current_regcache.end (); + it != target_regcache::current_regcache.end (); ) { if (ptid_match ((*it)->ptid (), ptid)) { delete *it; - it = regcache::current_regcache.erase_after (oit); + it = target_regcache::current_regcache.erase_after (oit); } else oit = it++; @@ -1668,7 +1676,7 @@ maintenance_print_remote_registers (char *args, int from_tty) namespace selftests { -class regcache_access : public regcache +class regcache_access : public target_regcache { public: @@ -1677,8 +1685,8 @@ public: static size_t current_regcache_size () { - return std::distance (regcache::current_regcache.begin (), - regcache::current_regcache.end ()); + return std::distance (target_regcache::current_regcache.begin (), + target_regcache::current_regcache.end ()); } }; @@ -1692,7 +1700,7 @@ current_regcache_test (void) /* Get regcache from ptid1, a new regcache is added to current_regcache. */ - regcache *regcache = get_thread_arch_aspace_regcache (ptid1, + target_regcache *regcache = get_thread_arch_aspace_regcache (ptid1, target_gdbarch (), NULL); @@ -1745,7 +1753,8 @@ _initialize_regcache (void) = gdbarch_data_register_post_init (init_regcache_descr); observer_attach_target_changed (regcache_observer_target_changed); - observer_attach_thread_ptid_changed (regcache::regcache_thread_ptid_changed); + observer_attach_thread_ptid_changed + (target_regcache::regcache_thread_ptid_changed); add_com ("flushregs", class_maintenance, reg_flush_command, _("Force gdb to flush its register cache (maintainer command)")); diff --git a/gdb/regcache.h b/gdb/regcache.h index aa64a000acf..bc3f24cffe1 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -24,14 +24,15 @@ #include struct regcache; +class target_regcache; struct regset; struct gdbarch; struct address_space; -extern struct regcache *get_current_regcache (void); -extern struct regcache *get_thread_regcache (ptid_t ptid); -extern struct regcache *get_thread_arch_regcache (ptid_t, struct gdbarch *); -extern struct regcache *get_thread_arch_aspace_regcache (ptid_t, +extern target_regcache *get_current_regcache (void); +extern target_regcache *get_thread_regcache (ptid_t ptid); +extern target_regcache *get_thread_arch_regcache (ptid_t, struct gdbarch *); +extern target_regcache *get_thread_arch_aspace_regcache (ptid_t, struct gdbarch *, struct address_space *); @@ -240,7 +241,8 @@ typedef struct cached_reg gdb_byte *data; } cached_reg_t; -/* The register cache for storing raw register values. */ + +/* A register cache. This is not connected to a target and ptid is unset. */ class regcache { @@ -344,41 +346,23 @@ public: void dump (ui_file *file, enum regcache_dump_what what_to_dump); - ptid_t ptid () const - { - return m_ptid; - } - - void set_ptid (const ptid_t ptid) + virtual ptid_t ptid () const { - this->m_ptid = ptid; + /* Ptid of a non-target regcache is always -1. */ + return (ptid_t) -1; } /* Dump the contents of a register from the register cache to the target debug. */ void debug_print_register (const char *func, int regno); - static void regcache_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid); protected: regcache (gdbarch *gdbarch, address_space *aspace_, bool readonly_p_); - 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, - const void *out, - decltype (regcache_raw_read) read, - decltype (regcache_raw_write) write); - - void transfer_regset (const struct regset *regset, - struct regcache *out_regcache, - 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 @@ -389,6 +373,7 @@ private: 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 @@ -398,21 +383,63 @@ private: regcache_cpy(). The actual contents are determined by the reggroup_save and reggroup_restore methods. */ bool m_readonly_p; - /* If this is a read-write cache, which thread's registers is - it connected to? */ - ptid_t m_ptid; - friend struct regcache * - get_thread_arch_aspace_regcache (ptid_t ptid, struct gdbarch *gdbarch, - struct address_space *aspace); +private: - friend void - registers_changed_ptid (ptid_t ptid); + enum register_status xfer_part (int regnum, int offset, int len, void *in, + const void *out, + decltype (regcache_raw_read) read, + decltype (regcache_raw_write) write); + + void transfer_regset (const struct regset *regset, + struct regcache *out_regcache, + int regnum, const void *in_buf, + void *out_buf, size_t size) const; + +private: friend void regcache_cpy (struct regcache *dst, struct regcache *src); }; + +/* A register cache that can be attached to a target. ptid can be set. */ + +class target_regcache : public regcache +{ +public: + + ptid_t ptid () const + { + return m_ptid; + } + + static void regcache_thread_ptid_changed (ptid_t old_ptid, + ptid_t new_ptid); + +protected: + + /* Constructor is only called via get_thread_arch_aspace_regcache. */ + target_regcache (gdbarch *gdbarch, address_space *aspace_); + + void set_ptid (const ptid_t ptid) + { + this->m_ptid = ptid; + } + + static std::forward_list current_regcache; + +private: + + /* The thread the cache is connected to, or -1 if not attached. */ + ptid_t m_ptid; + + friend struct target_regcache * get_thread_arch_aspace_regcache + (ptid_t ptid, struct gdbarch *gdbarch, struct address_space *aspace); + + friend void registers_changed_ptid (ptid_t ptid); +}; + /* Duplicate the contents of a register cache to a read-only register cache. The operation is pass-through. */ extern struct regcache *regcache_dup (struct regcache *regcache);