From patchwork Thu Aug 17 08:47:15 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Hayward X-Patchwork-Id: 22175 Received: (qmail 79579 invoked by alias); 17 Aug 2017 08:47:26 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 76260 invoked by uid 89); 17 Aug 2017 08:47:23 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LOTSOFHASH, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: EUR01-DB5-obe.outbound.protection.outlook.com Received: from mail-db5eur01on0081.outbound.protection.outlook.com (HELO EUR01-DB5-obe.outbound.protection.outlook.com) (104.47.2.81) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 17 Aug 2017 08:47:20 +0000 Received: from AM3PR08MB0101.eurprd08.prod.outlook.com (10.160.211.19) by AM3PR08MB0101.eurprd08.prod.outlook.com (10.160.211.19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.1.1341.17; Thu, 17 Aug 2017 08:47:16 +0000 Received: from AM3PR08MB0101.eurprd08.prod.outlook.com ([fe80::b8e2:8809:e2b2:ae37]) by AM3PR08MB0101.eurprd08.prod.outlook.com ([fe80::b8e2:8809:e2b2:ae37%14]) with mapi id 15.01.1341.024; Thu, 17 Aug 2017 08:47:16 +0000 From: Alan Hayward To: "gdb-patches@sourceware.org" CC: nd Subject: [PATCH 1/7] Regcache: Subclass ptid functionality to target_regcache Date: Thu, 17 Aug 2017 08:47:15 +0000 Message-ID: <6AAAA989-5B31-4E54-963C-57F2B7452BD7@arm.com> authentication-results: spf=none (sender IP is ) smtp.mailfrom=Alan.Hayward@arm.com; x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; AM3PR08MB0101; 6:86BzjB7JupPu+u16px9U8/kNYgllUIyMEKjjodfEcM0dpZe0iUXcJ9sihYlULxC8ttQjnyq1d0gg9LlpqiKCWkL/cvES5YT4+/nZ6aovXOVZUJkHZWSLBayrZm970FrnYx/pXHfjrEUz+ni22Bx5ftC2nEtUCcadhP9mRXIa2BTGG1auA0iutFsxOXbv4yBrFA19cKyLFeK/4oVnEVrIIeQNWTKRnZD+i/tjc7i9/qdboXNVKA/GR3Birqe7sXZCgrvdci6mV/pvka8zIrdqowreS8vRHBBpUN3GUv8up8st/Xnih8T49ln/EQL8B32nMLNCw2qSHTSeW46vHB/QUg==; 5:l0QqpNF8rwQouykPKh2WPTrBgko56elwMk41pzqq5WT1eEcnchb6OMNWKK44Qs3HiBKJV8ZjWQh4+Q5li955NEy5z/LRwdXb1uAlIr524Q87TP0eZsTv0WZYDQn+EITv2VdpzFC6gz1LDuxt/pBSyg==; 24:rtD8azlJwj+TcNIf37e0vWj1k6qb+ZV+t9MV2RiNvk7klhXL0tqQOK74uuS9XkQESm4/Np9Jq1dMbrB3L5swV4cDB8QnnlCADStUjeZiiYI=; 7:35fHpMDAAk2T0v8TQhD7HT8H3eqZ7y8Cmm5AAcOCchyDpPJ5DawWJgldrFkghYeMRTVJ9xSeSTH3wXcEcJpOoUZqNxx21teS4jhy5yxdGpHNRoXoOphoEGiZgBO4LiwpgC6I2p+XleNt/5BzfQSc8R5YZ+RUwTUfv0bKWrFZv/vc9DE/0wqBQh3IxQ2uGDhyFEDLP5Sa1qT6A1go4JjCl+4ewzKXVrZ0zsvDz19T96Y= x-ms-exchange-antispam-srfa-diagnostics: SSOS; x-ms-office365-filtering-correlation-id: 87ede843-168a-47b4-76b9-08d4e54c8fe9 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(300000500095)(300135000095)(300000501095)(300135300095)(300000502095)(300135100095)(22001)(2017030254152)(300000503095)(300135400095)(48565401081)(2017052603031)(201703131423075)(201703031133081)(201702281549075)(300000504095)(300135200095)(300000505095)(300135600095)(300000506095)(300135500095); SRVR:AM3PR08MB0101; x-ms-traffictypediagnostic: AM3PR08MB0101: nodisclaimer: True x-exchange-antispam-report-test: UriScan:(180628864354917); x-microsoft-antispam-prvs: x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(601004)(2401047)(5005006)(8121501046)(93006095)(93001095)(100000703101)(100105400095)(10201501046)(3002001)(6055026)(6041248)(20161123562025)(20161123558100)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123564025)(20161123555025)(20161123560025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:AM3PR08MB0101; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:AM3PR08MB0101; x-forefront-prvs: 0402872DA1 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(6009001)(39860400002)(199003)(377424004)(189002)(81166006)(68736007)(86362001)(3280700002)(478600001)(189998001)(2501003)(5640700003)(99286003)(5660300001)(2906002)(6436002)(25786009)(7736002)(53936002)(3660700001)(33656002)(3846002)(305945005)(6512007)(36756003)(102836003)(101416001)(97736004)(8936002)(6116002)(66066001)(14454004)(50986999)(6916009)(2900100001)(8676002)(54356999)(6486002)(106356001)(105586002)(72206003)(6506006)(81156014)(2351001)(82746002)(83716003)(4326008)(110136004)(5890100001)(5250100002); DIR:OUT; SFP:1101; SCL:1; SRVR:AM3PR08MB0101; H:AM3PR08MB0101.eurprd08.prod.outlook.com; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-ID: <08F8E171D7BF86468EB7603CAF7D44EB@eurprd08.prod.outlook.com> MIME-Version: 1.0 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-originalarrivaltime: 17 Aug 2017 08:47:15.9237 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM3PR08MB0101 X-IsSubscribed: yes This patch creates the target_regcache, subclassed from regcache. All ptid related functions are moved to target_regcache. A regcache retains the ptid () method, which always returns -1. This ensures users can always test if a regcache is attached to a target, without needing to know if it is a target_regcache. The get_current_regcache and get_thread_* functions now all return a target_regcache. It is perfectly safe for the existing code to treat the result as a regcache. A target_regcache cannot be read only, because it does not make sense that a regcache connected to a target would be read only. Tested on a --enable-targets=all build with board files unix, native-gdbserver and unittest.exp. 2017-08-16 Alan Hayward * gdbarch-selftests.c: Use target_regcache. * regcache.c (target_regcache::target_regcache): New constructor. (get_thread_arch_aspace_regcache): Use target_regcache. (get_thread_regcache_for_ptid): Likewise. (target_regcache::regcache_thread_ptid_changed): Likewise. (registers_changed_ptid): Likewise. (current_regcache_test): Likewise. (_initialize_regcache): Likewise. * regcache.h: New class target_regcache. diff --git a/gdb/gdbarch-selftests.c b/gdb/gdbarch-selftests.c index 096ba975f75edf6e2de81a767f2b645ff2405fd7..a6251d2a9f87ccff310f90eb5c27bc4199844f22 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.h b/gdb/regcache.h index aa64a000acf06b90dc7f2f519b07f8ff7e3903b4..bc3f24cffe1413d521998ab3c8081833a2735754 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); diff --git a/gdb/regcache.c b/gdb/regcache.c index e8f92d684dd80a197e055aa1b1bbe2caaab2392a..3d6ca86006fa59463069808f6e5b355028c4d3cc 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)"));