public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Simon Marchi <simon.marchi@efficios.com>
To: gdb-patches@sourceware.org
Cc: Luis Machado <luis.machado@arm.com>,
	John Baldwin <jhb@freebsd.org>,
	"Aktemur, Tankut Baris" <tankut.baris.aktemur@intel.com>,
	Simon Marchi <simon.marchi@efficios.com>,
	John Baldwin <jhb@FreeBSD.org>
Subject: [PATCH 21/24] gdb: migrate aarch64 to new gdbarch_pseudo_register_write
Date: Fri,  1 Dec 2023 11:27:34 -0500	[thread overview]
Message-ID: <20231201162751.741751-22-simon.marchi@efficios.com> (raw)
In-Reply-To: <20231201162751.741751-1-simon.marchi@efficios.com>

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 <jhb@FreeBSD.org>
---
 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 e3658c2c8e10..a1eab01abb8c 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<const gdb_byte> 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];
   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<gdb_byte> 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<const gdb_byte> data)
 {
   aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_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<gdb_byte> 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<const gdb_byte> src
+	  = data.slice (chunks * offsets.chunk_size, offsets.chunk_size);
+	gdb::array_view<gdb_byte> 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<const gdb_byte> buf)
 {
   aarch64_gdbarch_tdep *tdep = gdbarch_tdep<aarch64_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<gdb_byte> 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,
-- 
2.43.0


  parent reply	other threads:[~2023-12-01 16:32 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-01 16:27 [PATCH 00/24] Fix reading and writing pseudo registers in non-current frames Simon Marchi
2023-12-01 16:27 ` [PATCH 01/24] gdb: don't handle i386 k registers as pseudo registers Simon Marchi
2023-12-01 16:27 ` [PATCH 02/24] gdb: use reg_buffer_common throughout gdbsupport/common-regcache.h Simon Marchi
2023-12-01 16:27 ` [PATCH 03/24] gdb: make store_integer take an array_view Simon Marchi
2023-12-01 16:27 ` [PATCH 04/24] gdb: simplify conditions in regcache::{read,write,raw_collect,raw_supply}_part Simon Marchi
2023-12-01 16:27 ` [PATCH 05/24] gdb: change regcache interface to use array_view Simon Marchi
2023-12-01 16:27 ` [PATCH 06/24] gdb: fix bugs in {get,put}_frame_register_bytes Simon Marchi
2023-12-01 16:27 ` [PATCH 07/24] gdb: make put_frame_register take an array_view Simon Marchi
2023-12-01 16:27 ` [PATCH 08/24] gdb: change value_of_register and value_of_register_lazy to take the next frame Simon Marchi
2023-12-01 16:27 ` [PATCH 09/24] gdb: remove frame_register Simon Marchi
2023-12-01 16:27 ` [PATCH 10/24] gdb: make put_frame_register take the next frame Simon Marchi
2023-12-01 16:27 ` [PATCH 11/24] gdb: make put_frame_register_bytes " Simon Marchi
2023-12-01 16:27 ` [PATCH 12/24] gdb: make get_frame_register_bytes " Simon Marchi
2023-12-22 13:33   ` Kévin Le Gouguec
2023-12-22 15:31     ` Simon Marchi
2023-12-22 16:22       ` Kévin Le Gouguec
2023-12-01 16:27 ` [PATCH 13/24] gdb: add value::allocate_register Simon Marchi
2023-12-01 16:27 ` [PATCH 14/24] gdb: read pseudo register through frame Simon Marchi
2023-12-01 16:27 ` [PATCH 15/24] gdb: change parameter name in frame_unwind_register_unsigned declaration Simon Marchi
2023-12-01 16:27 ` [PATCH 16/24] gdb: rename gdbarch_pseudo_register_write to gdbarch_deprecated_pseudo_register_write Simon Marchi
2023-12-01 16:27 ` [PATCH 17/24] gdb: add gdbarch_pseudo_register_write that takes a frame Simon Marchi
2023-12-01 16:27 ` [PATCH 18/24] gdb: migrate i386 and amd64 to the new gdbarch_pseudo_register_write Simon Marchi
2023-12-01 16:27 ` [PATCH 19/24] gdb: make aarch64_za_offsets_from_regnum return za_offsets Simon Marchi
2023-12-01 16:27 ` [PATCH 20/24] gdb: add missing raw register read in aarch64_sme_pseudo_register_write Simon Marchi
2023-12-01 16:27 ` Simon Marchi [this message]
2023-12-14 14:53   ` [PATCH 21/24] gdb: migrate aarch64 to new gdbarch_pseudo_register_write Luis Machado
2023-12-01 16:27 ` [PATCH 22/24] gdb: migrate arm to gdbarch_pseudo_register_read_value Simon Marchi
2023-12-01 16:27 ` [PATCH 23/24] gdb: migrate arm to new gdbarch_pseudo_register_write Simon Marchi
2023-12-01 16:27 ` [PATCH 24/24] gdb/testsuite: add tests for unwinding of pseudo registers Simon Marchi
2023-12-14 14:54   ` Luis Machado
2023-12-01 16:56 ` [PATCH 00/24] Fix reading and writing pseudo registers in non-current frames Simon Marchi
2023-12-14 14:51 ` Luis Machado
2023-12-14 16:20   ` Simon Marchi
  -- strict thread matches above, loose matches on Subject: below --
2023-11-08  5:00 Simon Marchi
2023-11-08  5:01 ` [PATCH 21/24] gdb: migrate aarch64 to new gdbarch_pseudo_register_write Simon Marchi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231201162751.741751-22-simon.marchi@efficios.com \
    --to=simon.marchi@efficios.com \
    --cc=gdb-patches@sourceware.org \
    --cc=jhb@freebsd.org \
    --cc=luis.machado@arm.com \
    --cc=tankut.baris.aktemur@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).