From patchwork Fri Nov 24 21:26:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Marchi X-Patchwork-Id: 80765 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B34DF3858296 for ; Fri, 24 Nov 2023 21:31:58 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from simark.ca (simark.ca [158.69.221.121]) by sourceware.org (Postfix) with ESMTPS id 5952A3858C35 for ; Fri, 24 Nov 2023 21:31:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5952A3858C35 Authentication-Results: sourceware.org; dmarc=fail (p=none dis=none) header.from=efficios.com Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=efficios.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 5952A3858C35 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=158.69.221.121 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700861470; cv=none; b=xUGAb7XMsB+F4lKYb4LVJKwIyAOIeJeZWR/PP5odXt3XH9cHpNj36a/p1luBFKl5H4SXNL81gw31AiHZd+8PpPlRXcMJcpjjwg+txqT3dy2q1a78wmJyjTQXg3NRXBgr0gdr1/PRzmL1w5JGczXrghUWZzelF1xLoERWGqOxLoY= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700861470; c=relaxed/simple; bh=DI95mlL20iGUWPSGOwg8bq58LfNUCeJ5iLmwLLSmILc=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=ICILQEDIu3BkS3ByNvVPdkIsFUlmxArRNT790NpXiM3Fe9gQHi2whpTvZTCPuvAb72SVi2YUe06rryc/a+p4svUEdnEYW+01PI/cytx7hMst0GE4yAVoutfND7Dkt2GFM2O9dw1uBk7xYdxvr2n9DMBHAOrUMzW0wf/3AoMEo/o= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from smarchi-efficios.internal.efficios.com (192-222-143-198.qc.cable.ebox.net [192.222.143.198]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPSA id A1D1B1E1A7; Fri, 24 Nov 2023 16:31:06 -0500 (EST) From: Simon Marchi To: gdb-patches@sourceware.org Cc: Luis Machado , John Baldwin , Andrew Burgess , Simon Marchi , John Baldwin Subject: [PATCH v2 21/24] gdb: migrate aarch64 to new gdbarch_pseudo_register_write Date: Fri, 24 Nov 2023 16:26:38 -0500 Message-ID: <20231124212656.96801-22-simon.marchi@efficios.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20231124212656.96801-1-simon.marchi@efficios.com> References: <20231124212656.96801-1-simon.marchi@efficios.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3496.7 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_NONE, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_SOFTFAIL, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org New in v2: - Allocate enough space for an SVE register in aarch64_pseudo_write_1 (i.e. keep the logic that's there before the patch for the local buffer size) Make aarch64 use the new gdbarch_pseudo_register_write. This fixes writing pseudo registers to non-current frames on this architecture. Change-Id: Ic012a0b95ae728d45a7121f77a79d604c23a849e Reviewed-By: John Baldwin --- gdb/aarch64-tdep.c | 128 +++++++++++++++++++++++++-------------------- 1 file changed, 70 insertions(+), 58 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index e31e4bea41fc..4d670853bb6b 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -3296,32 +3296,35 @@ aarch64_pseudo_read_value (gdbarch *gdbarch, frame_info_ptr next_frame, /* Helper for aarch64_pseudo_write. */ static void -aarch64_pseudo_write_1 (struct gdbarch *gdbarch, struct regcache *regcache, - int regnum_offset, int regsize, const gdb_byte *buf) +aarch64_pseudo_write_1 (gdbarch *gdbarch, frame_info_ptr next_frame, + int regnum_offset, + gdb::array_view buf) { - unsigned v_regnum = AARCH64_V0_REGNUM + regnum_offset; + unsigned raw_regnum = AARCH64_V0_REGNUM + regnum_offset; /* Enough space for a full vector register. */ - gdb_byte reg_buf[register_size (gdbarch, AARCH64_V0_REGNUM)]; + int raw_reg_size = register_size (gdbarch, raw_regnum); + gdb_byte raw_buf[raw_reg_size]; gdb_static_assert (AARCH64_V0_REGNUM == AARCH64_SVE_Z0_REGNUM); /* Ensure the register buffer is zero, we want gdb writes of the various 'scalar' pseudo registers to behavior like architectural writes, register width bytes are written the remainder are set to zero. */ - memset (reg_buf, 0, register_size (gdbarch, AARCH64_V0_REGNUM)); + memset (raw_buf, 0, register_size (gdbarch, AARCH64_V0_REGNUM)); - memcpy (reg_buf, buf, regsize); - regcache->raw_write (v_regnum, reg_buf); + gdb::array_view raw_view (raw_buf, raw_reg_size); + copy (buf, raw_view.slice (0, buf.size ())); + put_frame_register (next_frame, raw_regnum, raw_view); } /* Given REGNUM, a SME pseudo-register number, store the bytes from DATA to the pseudo-register. */ static void -aarch64_sme_pseudo_register_write (struct gdbarch *gdbarch, - struct regcache *regcache, - int regnum, const gdb_byte *data) +aarch64_sme_pseudo_register_write (gdbarch *gdbarch, frame_info_ptr next_frame, + const int regnum, + gdb::array_view data) { aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); @@ -3335,33 +3338,39 @@ aarch64_sme_pseudo_register_write (struct gdbarch *gdbarch, za_offsets offsets = aarch64_za_offsets_from_regnum (gdbarch, regnum); /* Fetch the contents of ZA. */ - size_t svl = sve_vl_from_vq (tdep->sme_svq); - gdb::byte_vector za (std::pow (svl, 2)); - regcache->raw_read (tdep->sme_za_regnum, za); + value *za_value = value_of_register (tdep->sme_za_regnum, next_frame); - /* Copy the requested data. */ - for (int chunks = 0; chunks < offsets.chunks; chunks++) - { - const gdb_byte *source = data + chunks * offsets.chunk_size; - gdb_byte *destination - = za.data () + offsets.starting_offset + chunks * offsets.stride_size; + { + /* Create a view only on the portion of za we want to write. */ + gdb::array_view za_view + = za_value->contents_writeable ().slice (offsets.starting_offset); - memcpy (destination, source, offsets.chunk_size); - } + /* Copy the requested data. */ + for (int chunks = 0; chunks < offsets.chunks; chunks++) + { + gdb::array_view src + = data.slice (chunks * offsets.chunk_size, offsets.chunk_size); + gdb::array_view dst + = za_view.slice (chunks * offsets.stride_size, offsets.chunk_size); + copy (src, dst); + } + } /* Write back to ZA. */ - regcache->raw_write (tdep->sme_za_regnum, za.data ()); + put_frame_register (next_frame, tdep->sme_za_regnum, + za_value->contents_raw ()); } /* Implement the "pseudo_register_write" gdbarch method. */ static void -aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache, - int regnum, const gdb_byte *buf) +aarch64_pseudo_write (gdbarch *gdbarch, frame_info_ptr next_frame, + const int pseudo_reg_num, + gdb::array_view buf) { aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - if (is_w_pseudo_register (gdbarch, regnum)) + if (is_w_pseudo_register (gdbarch, pseudo_reg_num)) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* Default offset for little endian. */ @@ -3371,53 +3380,56 @@ aarch64_pseudo_write (struct gdbarch *gdbarch, struct regcache *regcache, offset = 4; /* Find the correct X register to extract the data from. */ - int x_regnum = AARCH64_X0_REGNUM + (regnum - tdep->w_pseudo_base); + int x_regnum = AARCH64_X0_REGNUM + (pseudo_reg_num - tdep->w_pseudo_base); /* First zero-out the contents of X. */ - ULONGEST zero = 0; - regcache->raw_write (x_regnum, zero); + gdb_byte bytes[8] {}; + gdb::array_view bytes_view (bytes); + copy (buf, bytes_view.slice (offset, 4)); + /* Write to the bottom 4 bytes of X. */ - regcache->raw_write_part (x_regnum, offset, 4, buf); + put_frame_register (next_frame, x_regnum, bytes_view); return; } - else if (is_sme_pseudo_register (gdbarch, regnum)) + else if (is_sme_pseudo_register (gdbarch, pseudo_reg_num)) { - aarch64_sme_pseudo_register_write (gdbarch, regcache, regnum, buf); + aarch64_sme_pseudo_register_write (gdbarch, next_frame, pseudo_reg_num, + buf); return; } - regnum -= gdbarch_num_regs (gdbarch); + /* Offset in the "pseudo-register space". */ + int pseudo_offset = pseudo_reg_num - gdbarch_num_regs (gdbarch); - if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32) - return aarch64_pseudo_write_1 (gdbarch, regcache, - regnum - AARCH64_Q0_REGNUM, Q_REGISTER_SIZE, - buf); + if (pseudo_offset >= AARCH64_Q0_REGNUM + && pseudo_offset < AARCH64_Q0_REGNUM + 32) + return aarch64_pseudo_write_1 (gdbarch, next_frame, + pseudo_offset - AARCH64_Q0_REGNUM, buf); - if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32) - return aarch64_pseudo_write_1 (gdbarch, regcache, - regnum - AARCH64_D0_REGNUM, D_REGISTER_SIZE, - buf); + if (pseudo_offset >= AARCH64_D0_REGNUM + && pseudo_offset < AARCH64_D0_REGNUM + 32) + return aarch64_pseudo_write_1 (gdbarch, next_frame, + pseudo_offset - AARCH64_D0_REGNUM, buf); - if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32) - return aarch64_pseudo_write_1 (gdbarch, regcache, - regnum - AARCH64_S0_REGNUM, S_REGISTER_SIZE, - buf); + if (pseudo_offset >= AARCH64_S0_REGNUM + && pseudo_offset < AARCH64_S0_REGNUM + 32) + return aarch64_pseudo_write_1 (gdbarch, next_frame, + pseudo_offset - AARCH64_S0_REGNUM, buf); - if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32) - return aarch64_pseudo_write_1 (gdbarch, regcache, - regnum - AARCH64_H0_REGNUM, H_REGISTER_SIZE, - buf); + if (pseudo_offset >= AARCH64_H0_REGNUM + && pseudo_offset < AARCH64_H0_REGNUM + 32) + return aarch64_pseudo_write_1 (gdbarch, next_frame, + pseudo_offset - AARCH64_H0_REGNUM, buf); - if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32) - return aarch64_pseudo_write_1 (gdbarch, regcache, - regnum - AARCH64_B0_REGNUM, B_REGISTER_SIZE, - buf); + if (pseudo_offset >= AARCH64_B0_REGNUM + && pseudo_offset < AARCH64_B0_REGNUM + 32) + return aarch64_pseudo_write_1 (gdbarch, next_frame, + pseudo_offset - AARCH64_B0_REGNUM, buf); - if (tdep->has_sve () && regnum >= AARCH64_SVE_V0_REGNUM - && regnum < AARCH64_SVE_V0_REGNUM + 32) - return aarch64_pseudo_write_1 (gdbarch, regcache, - regnum - AARCH64_SVE_V0_REGNUM, - V_REGISTER_SIZE, buf); + if (tdep->has_sve () && pseudo_offset >= AARCH64_SVE_V0_REGNUM + && pseudo_offset < AARCH64_SVE_V0_REGNUM + 32) + return aarch64_pseudo_write_1 (gdbarch, next_frame, + pseudo_offset - AARCH64_SVE_V0_REGNUM, buf); gdb_assert_not_reached ("regnum out of bound"); } @@ -4483,7 +4495,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_num_pseudo_regs (gdbarch, num_pseudo_regs); set_gdbarch_pseudo_register_read_value (gdbarch, aarch64_pseudo_read_value); - set_gdbarch_deprecated_pseudo_register_write (gdbarch, aarch64_pseudo_write); + set_gdbarch_pseudo_register_write (gdbarch, aarch64_pseudo_write); set_tdesc_pseudo_register_name (gdbarch, aarch64_pseudo_register_name); set_tdesc_pseudo_register_type (gdbarch, aarch64_pseudo_register_type); set_tdesc_pseudo_register_reggroup_p (gdbarch,