public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Simon Marchi <simark@simark.ca>
To: Alan Hayward <alan.hayward@arm.com>, gdb-patches@sourceware.org
Cc: nd@arm.com
Subject: Re: [PATCH v2 05/10] Ptrace support for Aarch64 SVE
Date: Sun, 10 Jun 2018 22:52:00 -0000	[thread overview]
Message-ID: <87958a98-4764-609f-5873-9968bd49c028@simark.ca> (raw)
In-Reply-To: <20180606151629.36602-6-alan.hayward@arm.com>

Hi Alan,

Mostly some nits, though there is what looks like an off by one error
in some loops.  You can push after you have looked into it.

On 2018-06-06 11:16 AM, Alan Hayward wrote:
> diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
> index 1e4f937dc9..4db7d0d977 100644
> --- a/gdb/aarch64-linux-nat.c
> +++ b/gdb/aarch64-linux-nat.c
> @@ -384,19 +384,62 @@ store_fpregs_to_thread (const struct regcache *regcache)
>      }
>  }
>  
> +/* Fill GDB's register array with the sve register values
> +   from the current thread.  */
> +
> +static void
> +fetch_sveregs_from_thread (struct regcache *regcache)
> +{
> +  std::unique_ptr<gdb_byte> base
> +    = aarch64_sve_get_sveregs (ptid_get_lwp (regcache->ptid ()));
> +  aarch64_sve_regs_copy_to_reg_buf (regcache, base.get ());
> +}
> +
> +/* Store to the current thread the valid sve register
> +   values in the GDB's register array.  */
> +
> +static void
> +store_sveregs_to_thread (struct regcache *regcache)
> +{
> +  int ret;
> +  struct iovec iovec;
> +  int tid = ptid_get_lwp (regcache->ptid ());
> +
> +  /* Obtain a dump of SVE registers from ptrace.  */
> +  std::unique_ptr<gdb_byte> base = aarch64_sve_get_sveregs (tid);

I am not sure if it matters in this case because no destructor is run, but
I think it should be std::unique_ptr<gdb_byte[]>.

> @@ -56,3 +60,268 @@ aarch64_sve_get_vq (int tid)
>  
>    return vq;
>  }
> +
> +/* See nat/aarch64-sve-linux-ptrace.h.  */
> +
> +std::unique_ptr<gdb_byte>
> +aarch64_sve_get_sveregs (int tid)
> +{
> +  struct iovec iovec;
> +  struct user_sve_header header;
> +  uint64_t vq = aarch64_sve_get_vq (tid);
> +
> +  if (vq == 0)
> +    perror_with_name (_("Unable to fetch sve register header"));
> +
> +  /* A ptrace call with NT_ARM_SVE will return a header followed by either a
> +     dump of all the SVE and FP registers, or an fpsimd structure (identical to
> +     the one returned by NT_FPREGSET) if the kernel has not yet executed any
> +     SVE code.  Make sure we allocate enough space for a full SVE dump.  */
> +
> +  iovec.iov_len = SVE_PT_SIZE (vq, SVE_PT_REGS_SVE);
> +  std::unique_ptr<gdb_byte> buf (new gdb_byte[iovec.iov_len]);
> +  iovec.iov_base = buf.get ();
> +
> +  if (ptrace (PTRACE_GETREGSET, tid, NT_ARM_SVE, &iovec) < 0)
> +    perror_with_name (_("Unable to fetch sve registers"));
> +
> +  return buf;
> +}
> +
> +/* See nat/aarch64-sve-linux-ptrace.h.  */
> +
> +void
> +aarch64_sve_regs_copy_to_reg_buf (struct reg_buffer_common *reg_buf,
> +				   const void *buf)

The indentation of the second line has one extra space.

> +{
> +  char *base = (char*) buf;

Space after "char".

> +  int i;
> +  struct user_sve_header *header = (struct user_sve_header *) buf;
> +  uint64_t vq, vg_reg_buf = 0;
> +
> +  vq = sve_vq_from_vl (header->vl);
> +
> +  /* Sanity check the data in the header.  */
> +  if (!sve_vl_valid (header->vl)
> +      || SVE_PT_SIZE (vq, header->flags) != header->size)
> +    error (_("Invalid SVE header from kernel."));
> +
> +  if (REG_VALID == reg_buf->get_register_status (AARCH64_SVE_VG_REGNUM))
> +    reg_buf->raw_collect (AARCH64_SVE_VG_REGNUM, &vg_reg_buf);
> +
> +  if (vg_reg_buf == 0)
> +    {
> +      /* VG has not been set.  */
> +      vg_reg_buf = sve_vg_from_vl (header->vl);
> +      reg_buf->raw_supply (AARCH64_SVE_VG_REGNUM, &vg_reg_buf);
> +    }
> +  else if (vg_reg_buf != sve_vg_from_vl (header->vl) && !vq_change_warned)
> +    {
> +      /* Vector length on the running process has changed.  GDB currently does
> +	 not support this and will result in GDB showing incorrect partially
> +	 incorrect data for the vector registers.  Warn once and continue.  We
> +	 do not expect many programs to exhibit this behaviour.  To fix this
> +	 we need to spot the change earlier and generate a new target
> +	 descriptor.  */
> +      warning (_("SVE Vector length has changed (%ld to %d). "
> +		 "Vector registers may show incorrect data."),
> +	       vg_reg_buf, sve_vg_from_vl (header->vl));
> +      vq_change_warned = true;
> +    }
> +
> +  if (HAS_SVE_STATE (*header))
> +    {
> +      /* The register dump contains a set of SVE registers.  */
> +
> +      for (i = 0; i < AARCH64_SVE_Z_REGS_NUM; i++)

Declare the loop variables in the for (), when possible.

> +	reg_buf->raw_supply (AARCH64_SVE_Z0_REGNUM + i,
> +			     base + SVE_PT_SVE_ZREG_OFFSET (vq, i));
> +
> +      for (i = 0; i < AARCH64_SVE_P_REGS_NUM; i++)
> +	reg_buf->raw_supply (AARCH64_SVE_P0_REGNUM + i,
> +			     base + SVE_PT_SVE_PREG_OFFSET (vq, i));
> +
> +      reg_buf->raw_supply (AARCH64_SVE_FFR_REGNUM,
> +			   base + SVE_PT_SVE_FFR_OFFSET (vq));
> +      reg_buf->raw_supply (AARCH64_FPSR_REGNUM,
> +			   base + SVE_PT_SVE_FPSR_OFFSET (vq));
> +      reg_buf->raw_supply (AARCH64_FPCR_REGNUM,
> +			   base + SVE_PT_SVE_FPCR_OFFSET (vq));
> +    }
> +  else
> +    {
> +      /* There is no SVE state yet - the register dump contains a fpsimd
> +	 structure instead.  These registers still exist in the hardware, but
> +	 the kernel has not yet initialised them, and so they will be null.  */
> +
> +      char *zero_reg = (char *) alloca (SVE_PT_SVE_ZREG_SIZE (vq));
> +      struct user_fpsimd_state *fpsimd
> +	= (struct user_fpsimd_state *)(base + SVE_PT_FPSIMD_OFFSET);
> +
> +      /* Copy across the V registers from fpsimd structure to the Z registers,
> +	 ensuring the non overlapping state is set to null.  */
> +
> +      memset (zero_reg, 0, SVE_PT_SVE_ZREG_SIZE (vq));
> +
> +      for (i = 0; i <= AARCH64_SVE_Z_REGS_NUM; i++)
> +	{
> +	  memcpy (zero_reg, &fpsimd->vregs[i], sizeof (__int128_t));
> +	  reg_buf->raw_supply (AARCH64_SVE_Z0_REGNUM + i, zero_reg);
> +	}

I'm getting this.  Is the "i <= ..." on purpose?

  CXX    aarch64-sve-linux-ptrace.o
/home/simark/src/binutils-gdb/gdb/nat/aarch64-sve-linux-ptrace.c: In function 'void aarch64_sve_regs_copy_to_reg_buf(reg_buffer_common*, const void*)':
/home/simark/src/binutils-gdb/gdb/nat/aarch64-sve-linux-ptrace.c:168:61: error: iteration 32 invokes undefined behavior [-Werror=aggressive-loop-optimizations]
    memcpy (zero_reg, &fpsimd->vregs[i], sizeof (__int128_t));
                                                             ^
/home/simark/src/binutils-gdb/gdb/nat/aarch64-sve-linux-ptrace.c:166:21: note: within this loop
       for (i = 0; i <= AARCH64_SVE_Z_REGS_NUM; i++)



> +
> +      reg_buf->raw_supply (AARCH64_FPSR_REGNUM, &fpsimd->fpsr);
> +      reg_buf->raw_supply (AARCH64_FPCR_REGNUM, &fpsimd->fpcr);
> +
> +      /* Clear the SVE only registers.  */
> +
> +      for (i = 0; i <= AARCH64_SVE_P_REGS_NUM; i++)

Here too, "<="?

> +	reg_buf->raw_supply (AARCH64_SVE_P0_REGNUM + i, zero_reg);
> +
> +      reg_buf->raw_supply (AARCH64_SVE_FFR_REGNUM, zero_reg);
> +    }
> +}
> +
> +/* See nat/aarch64-sve-linux-ptrace.h.  */
> +
> +void
> +aarch64_sve_regs_copy_from_reg_buf (struct reg_buffer_common *reg_buf,
> +				     void *buf)

The indent is off by one here too.

reg_buf could be const.

> +{
> +  struct user_sve_header *header = (struct user_sve_header *) buf;
> +  char *base = (char*) buf;

Space after "char".

> +  uint64_t vq, vg_reg_buf = 0;
> +  int i;
> +
> +  vq = sve_vq_from_vl (header->vl);
> +
> +  /* Sanity check the data in the header.  */
> +  if (!sve_vl_valid (header->vl)
> +      || SVE_PT_SIZE (vq, header->flags) != header->size)
> +    error (_("Invalid SVE header from kernel."));
> +
> +  if (REG_VALID == reg_buf->get_register_status (AARCH64_SVE_VG_REGNUM))
> +    reg_buf->raw_collect (AARCH64_SVE_VG_REGNUM, &vg_reg_buf);
> +
> +  if (vg_reg_buf != 0 && vg_reg_buf != sve_vg_from_vl (header->vl))
> +    {
> +      /* Vector length on the running process has changed.  GDB currently does
> +	 not support this and will result in GDB writing invalid data back to
> +	 the vector registers.  Error and exit.  We do not expect many programs
> +	 to exhibit this behaviour.  To fix this we need to spot the change
> +	 earlier and generate a new target descriptor.  */
> +      error (_("SVE Vector length has changed (%ld to %d). "
> +	       "Cannot write back registers."),
> +	     vg_reg_buf, sve_vg_from_vl (header->vl));
> +    }
> +
> +  if (!HAS_SVE_STATE (*header))
> +    {
> +      /* There is no SVE state yet - the register dump contains a fpsimd
> +	 structure instead.  Where possible we want to write the reg_buf data
> +	 back to the kernel using the fpsimd structure.  However, if we cannot
> +	 then we'll need to reformat the fpsimd into a full SVE structure,
> +	 resulting in the initialization of SVE state written back to the
> +	 kernel, which is why we try to avoid it.  */
> +
> +      int has_sve_state = 0;

This should become a bool, and tests should become:

  if (has_sve_state)

  if (!has_sve_state)

Thanks,

Simon

  reply	other threads:[~2018-06-10 22:52 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-06 15:16 [PATCH v2 00/10] gdb/gdbserver support for aarch64 SVE Alan Hayward
2018-06-06 15:17 ` [PATCH v2 09/10] Ptrace support for AArch64 SVE gdbsever Alan Hayward
2018-06-11  2:43   ` Simon Marchi
2018-06-11  2:44   ` Simon Marchi
2018-06-06 15:17 ` [PATCH v2 02/10] Add Aarch64 SVE Linux headers Alan Hayward
2018-06-08 14:13   ` Alan Hayward
2018-06-08 14:37     ` Simon Marchi
2018-06-08 15:23       ` Simon Marchi
2018-06-12 14:37         ` Alan Hayward
2018-06-12 14:43           ` Pedro Alves
2018-06-12 15:06             ` Simon Marchi
2018-06-12 15:11               ` Pedro Alves
2018-06-12 15:21                 ` Simon Marchi
2018-06-12 15:09             ` Alan Hayward
2018-06-12 14:51           ` Simon Marchi
2018-06-12 16:34             ` Sergio Durigan Junior
2018-06-12 17:51               ` Alan Hayward
2018-06-12 20:29                 ` Sergio Durigan Junior
2018-06-15  9:45                   ` Ramana Radhakrishnan
2018-06-15 17:14                     ` Alan Hayward
2018-09-20 21:16                       ` Status of the AArch* builders (was: Re: [PATCH v2 02/10] Add Aarch64 SVE Linux headers) Sergio Durigan Junior
2018-09-24 14:16                         ` Alan Hayward
2018-09-24 14:42                           ` Status of the AArch* builders Sergio Durigan Junior
2018-10-11  9:23                             ` Alan Hayward
2018-10-12 19:06                               ` Sergio Durigan Junior
2018-10-15 10:16                                 ` Alan Hayward
2018-10-15 12:42                                   ` Sergio Durigan Junior
2018-10-15 14:02                                     ` Alan Hayward
2018-10-15 15:32                                       ` Sergio Durigan Junior
2018-10-17 18:46                                         ` Sergio Durigan Junior
2018-10-24  9:56                                           ` Alan Hayward
2018-10-25 16:26                                             ` Sergio Durigan Junior
2018-06-08 15:27       ` [PATCH v2 02/10] Add Aarch64 SVE Linux headers Alan Hayward
2018-06-06 15:17 ` [PATCH v2 01/10] Aarch64 SVE pseudo register support Alan Hayward
2018-06-06 22:17   ` Simon Marchi
2018-06-07  9:34     ` Alan Hayward
2018-06-06 15:17 ` [PATCH v2 07/10] Increase gdbsever PBUFSIZ Alan Hayward
2018-06-11  0:46   ` Simon Marchi
2018-06-06 15:17 ` [PATCH v2 08/10] Enable Aarch64 SVE for gdbserver Alan Hayward
2018-06-11  0:49   ` Simon Marchi
2018-06-06 15:17 ` [PATCH v2 05/10] Ptrace support for Aarch64 SVE Alan Hayward
2018-06-10 22:52   ` Simon Marchi [this message]
2018-06-06 15:17 ` [PATCH v2 10/10] Remove reg2 section from Aarch64 SVE cores Alan Hayward
2018-06-11  2:47   ` Simon Marchi
2018-06-11 16:37     ` Alan Hayward
2018-06-06 15:17 ` [PATCH v2 06/10] Add Aarch64 SVE dwarf regnums Alan Hayward
2018-06-11  0:43   ` Simon Marchi
2018-06-06 15:17 ` [PATCH v2 03/10] Add reg_buffer_common Alan Hayward
2018-06-07 20:19   ` Simon Marchi
2018-06-07 20:42     ` Simon Marchi
2018-06-08 14:14     ` Alan Hayward
2018-06-10 22:21       ` Simon Marchi
2018-06-06 15:17 ` [PATCH v2 04/10] Add regcache raw_compare method Alan Hayward
2018-06-07 20:56   ` Simon Marchi
2018-06-08 15:16     ` Alan Hayward
2018-06-10 22:26       ` 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=87958a98-4764-609f-5873-9968bd49c028@simark.ca \
    --to=simark@simark.ca \
    --cc=alan.hayward@arm.com \
    --cc=gdb-patches@sourceware.org \
    --cc=nd@arm.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).