From patchwork Wed Jun 14 14:02:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Hayward X-Patchwork-Id: 21006 Received: (qmail 54755 invoked by alias); 14 Jun 2017 14:02:06 -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 54740 invoked by uid 89); 14 Jun 2017 14:02:05 -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=backing X-HELO: EUR01-DB5-obe.outbound.protection.outlook.com Received: from mail-db5eur01on0059.outbound.protection.outlook.com (HELO EUR01-DB5-obe.outbound.protection.outlook.com) (104.47.2.59) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 14 Jun 2017 14:02:03 +0000 Received: from DB3PR08MB0106.eurprd08.prod.outlook.com (10.161.56.20) by DB3PR08MB0108.eurprd08.prod.outlook.com (10.161.56.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1157.12; Wed, 14 Jun 2017 14:02:04 +0000 Received: from DB3PR08MB0106.eurprd08.prod.outlook.com ([fe80::b409:2748:dd27:79e6]) by DB3PR08MB0106.eurprd08.prod.outlook.com ([fe80::b409:2748:dd27:79e6%14]) with mapi id 15.01.1157.017; Wed, 14 Jun 2017 14:02:04 +0000 From: Alan Hayward To: "gdb-patches@sourceware.org" CC: nd Subject: [PATCH] Replace regbuf with regcache in record-full.c Date: Wed, 14 Jun 2017 14:02:04 +0000 Message-ID: authentication-results: sourceware.org; dkim=none (message not signed) header.d=none; sourceware.org; dmarc=none action=none header.from=arm.com; x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1; DB3PR08MB0108; 7:QMvJQF/7MQSPXSZZVxdY4tNJY/WP+qgnZrhmFzm3wPlYWAl3pAHE5vn5o0FC6Z0JsKMim70FQ/9s2J9tnpSbwv0rq5M11N8qusURx2Bba0/AF+OLAS2HtG6AjN5Ae5g7nv0ufQuN4Mh6MtwPkNoAOI6pAQToOu3QsFganZefTrl+COh3iXphZHVq7MXEvw2/Ne7xz6zRI18Ktzsja3og4YtZDcEt5gYAMuTtq1D992dQHeeDjXZd0F3aMWZvddoAkX2ovdEYRwk1tv1IgxLddS2y1mjjQz2iy7xCQcaRbFWgBVHCdlkQFHJaP7Y5pGrmPA9Udx7NplkmgjWO9Dkj2A== x-ms-traffictypediagnostic: DB3PR08MB0108: x-ms-office365-filtering-correlation-id: b06fd0af-4e56-4094-08f1-08d4b32defe3 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(2017030254075)(48565401081)(201703131423075)(201703031133081); SRVR:DB3PR08MB0108; nodisclaimer: True x-microsoft-antispam-prvs: x-exchange-antispam-report-test: UriScan:(180628864354917)(788757137089); x-exchange-antispam-report-cfa-test: BCL:0; PCL:0; RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(601004)(2401047)(8121501046)(5005006)(93006095)(93001095)(3002001)(10201501046)(100000703101)(100105400095)(6055026)(6041248)(20161123555025)(20161123558100)(20161123560025)(20161123562025)(20161123564025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(6072148)(100000704101)(100105200095)(100000705101)(100105500095); SRVR:DB3PR08MB0108; BCL:0; PCL:0; RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095); SRVR:DB3PR08MB0108; x-forefront-prvs: 033857D0BD x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(6009001)(39450400003)(39840400002)(39400400002)(39850400002)(39410400002)(377424004)(575784001)(50986999)(189998001)(2900100001)(6116002)(3660700001)(3846002)(4326008)(54356999)(2351001)(14454004)(3280700002)(2906002)(36756003)(478600001)(102836003)(82746002)(5640700003)(6486002)(66066001)(8936002)(83716003)(53936002)(72206003)(6506006)(6436002)(8676002)(305945005)(5250100002)(2501003)(6512007)(7736002)(25786009)(33656002)(110136004)(5660300001)(86362001)(99286003)(6916009)(38730400002)(81166006); DIR:OUT; SFP:1101; SCL:1; SRVR:DB3PR08MB0108; H:DB3PR08MB0106.eurprd08.prod.outlook.com; FPR:; SPF:None; MLV:sfv; LANG:en; spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM Content-ID: MIME-Version: 1.0 X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-originalarrivaltime: 14 Jun 2017 14:02:04.4053 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB3PR08MB0108 X-IsSubscribed: yes In record-full.c, instead of backing up all the registers into a large buffer, duplicate the regcache. This enables the removal of an instance of MAX_REGISTER_SIZE. Note that regcache_dup() create a read-only copy of a register cache, which ensures the new regcache cannot write back to the target. Once created, we need to be able to copy registers between the two caches, which we want to do without creating a temporary buffer. I've added regcache::raw_copy() to allow the copying of raw registers between two regcaches - either of which might be set as read-only. Alternatively, I could make the new regcache as writable (by enabling a regcache copy constructor). But, I think this would be dangerous as it it then has the potential to write back to the target if the wrong function is called. Tested on a --enable-targets=all build with board files unix and native-gdbserver. Alan. 2017-06-14 Alan Hayward * gdb/record-full.c (record_full_core_regbuf): Remove. (record_full_core_regcache): New. (record_full_core_open_1): Duplicate regcache (record_full_close): Delete duplicated regcache. (record_full_core_fetch_registers): Use duplicated regcache. (record_full_core_store_registers): Likewise. * gdb/regcache.c (regcache::raw_copy): New function. * gdb/regcache.h (regcache::raw_copy): New declaration. diff --git a/gdb/record-full.c b/gdb/record-full.c index 4f73e2a5ad0d4a2407b31a1d391e813147e15798..00bbda213605110324a6529b9d4d538cd292c62f 100644 --- a/gdb/record-full.c +++ b/gdb/record-full.c @@ -167,7 +167,7 @@ struct record_full_core_buf_entry }; /* Record buf with core target. */ -static gdb_byte *record_full_core_regbuf = NULL; +static struct regcache *record_full_core_regcache = NULL; static struct target_section *record_full_core_start; static struct target_section *record_full_core_end; static struct record_full_core_buf_entry *record_full_core_buf_list = NULL; @@ -793,22 +793,17 @@ static void record_full_core_open_1 (const char *name, int from_tty) { struct regcache *regcache = get_current_regcache (); - int regnum = gdbarch_num_regs (get_regcache_arch (regcache)); - int i; - /* Get record_full_core_regbuf. */ + /* Get record_full_core_regcache. */ target_fetch_registers (regcache, -1); - record_full_core_regbuf = (gdb_byte *) xmalloc (MAX_REGISTER_SIZE * regnum); - for (i = 0; i < regnum; i ++) - regcache_raw_collect (regcache, i, - record_full_core_regbuf + MAX_REGISTER_SIZE * i); + record_full_core_regcache = regcache_dup (regcache); /* Get record_full_core_start and record_full_core_end. */ if (build_section_table (core_bfd, &record_full_core_start, &record_full_core_end)) { - xfree (record_full_core_regbuf); - record_full_core_regbuf = NULL; + regcache_xfree (record_full_core_regcache); + record_full_core_regcache = NULL; error (_("\"%s\": Can't find sections: %s"), bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ())); } @@ -886,11 +881,11 @@ record_full_close (struct target_ops *self) record_full_list_release (record_full_list); - /* Release record_full_core_regbuf. */ - if (record_full_core_regbuf) + /* Release record_full_core_regcache. */ + if (record_full_core_regcache) { - xfree (record_full_core_regbuf); - record_full_core_regbuf = NULL; + regcache_xfree (record_full_core_regcache); + record_full_core_regcache = NULL; } /* Release record_full_core_buf_list. */ @@ -2051,15 +2046,12 @@ record_full_core_fetch_registers (struct target_ops *ops, if (regno < 0) { int num = gdbarch_num_regs (get_regcache_arch (regcache)); - int i; - for (i = 0; i < num; i ++) - regcache_raw_supply (regcache, i, - record_full_core_regbuf + MAX_REGISTER_SIZE * i); + for (int i = 0; i < num; i ++) + regcache->raw_copy (i, record_full_core_regcache); } else - regcache_raw_supply (regcache, regno, - record_full_core_regbuf + MAX_REGISTER_SIZE * regno); + regcache->raw_copy (regno, record_full_core_regcache); } /* "to_prepare_to_store" method for prec over corefile. */ @@ -2078,8 +2070,7 @@ record_full_core_store_registers (struct target_ops *ops, int regno) { if (record_full_gdb_operation_disable) - regcache_raw_collect (regcache, regno, - record_full_core_regbuf + MAX_REGISTER_SIZE * regno); + record_full_core_regcache->raw_copy (regno, regcache); else error (_("You can't do that without a process to debug.")); } diff --git a/gdb/regcache.h b/gdb/regcache.h index 00b729d9af1b9d9823fc84fb424047c2b918ec8d..24257d8eafd4f7168b622a48ec1e646b9027153e 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -324,6 +324,8 @@ public: void raw_supply_zeroed (int regnum); + void raw_copy (int regnum, const struct regcache *src_regcache); + enum register_status get_register_status (int regnum) const; void raw_set_cached_value (int regnum, const gdb_byte *buf); @@ -402,8 +404,8 @@ private: /* 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 - cache can only be updated via the methods regcache_dup() and - regcache_cpy(). The actual contents are determined by the + cache can only be updated via the methods regcache_dup (), regcache_cpy () + and regcache::raw_copy (). 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 diff --git a/gdb/regcache.c b/gdb/regcache.c index 4e8c1ee0e648fd17ce2a120c61ecd495ff2e2467..54454e3f039ff5d6ab436cd9e0f1da607476ce32 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -1256,6 +1256,20 @@ regcache::raw_collect (int regnum, void *buf) const memcpy (buf, regbuf, size); } +/* Collect register REGNUM from SRC_REGCACHE and store its contents in + REGCACHE. Regcaches must have matching gdbarches. */ + +void +regcache::raw_copy (int regnum, const struct regcache *src_regcache) +{ + gdb_assert (src_regcache != NULL); + gdb_assert (regnum >= 0 && regnum < m_descr->nr_raw_registers); + gdb_assert (m_descr->gdbarch == src_regcache->m_descr->gdbarch); + + src_regcache->raw_collect (regnum, register_buffer (regnum)); + m_register_status[regnum] = src_regcache->m_register_status[regnum]; +} + /* Transfer a single or all registers belonging to a certain register set to or from a buffer. This is the main worker function for regcache_supply_regset and regcache_collect_regset. */