public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v3 0/3] Enable ptrace support for aarch64 sve
@ 2018-06-15 16:18 Alan Hayward
  2018-06-15 16:18 ` [PATCH v3 3/3] Ptrace support for AArch64 SVE gdbsever Alan Hayward
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Alan Hayward @ 2018-06-15 16:18 UTC (permalink / raw)
  To: gdb-patches; +Cc: nd, Alan Hayward

This set of patches adds the ptrace support for SVE.

Patch 1 includes macros/defines copied from the Linux kernel headers.
Previously, there was reservation about the copyright/ownership issues
about putting this into gdb. These header contents were all fully written
by Arm, who own the copyright and released it to Linux under GPL3 license.
This patch simply repackages the same code and releases it with the
same license and "provided by Arm" comment. There is precedence for
Arm doing the same in other FSF projects, and it falls within GPLs
copyleft policy.

I've also kept all the defines in a single file as it only contains
the relevant sections from two headers.

Apologies for the delay on submitting this, as I was seeking
clarification to the above. I'm hoping this alleviates any concerns.
It's also a more robust solution than selectively compiling support.

Patches 2 and 3 fix up all the review comments from v2.
In particular, patch 3 changes is_sve_tdesc to the only method I
could find - checking the number of registers.

Ran make check on x86 and aarch64.
Tested SVE and non-SVE built gdb on Aarch64 SVE emulator.

In addition, I've still got the following awaiting review:
[PATCH] Support large registers in regcache transfer_regset
https://sourceware.org/ml/gdb-patches/2018-06/msg00303.html

Alan Hayward (3):
  Add Aarch64 SVE compatibility macros
  Ptrace support for Aarch64 SVE
  Ptrace support for AArch64 SVE gdbsever

 gdb/aarch64-linux-nat.c                |  54 ++++++-
 gdb/gdbserver/Makefile.in              |   1 +
 gdb/gdbserver/linux-aarch64-low.c      |  63 +++++++-
 gdb/nat/aarch64-sve-linux-ptrace.c     | 269 ++++++++++++++++++++++++++++++++-
 gdb/nat/aarch64-sve-linux-ptrace.h     |  51 +++----
 gdb/nat/aarch64-sve-linux-sigcontext.h | 268 ++++++++++++++++++++++++++++++++
 6 files changed, 667 insertions(+), 39 deletions(-)
 create mode 100644 gdb/nat/aarch64-sve-linux-sigcontext.h

-- 
2.15.1 (Apple Git-101)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3 2/3] Ptrace support for Aarch64 SVE
  2018-06-15 16:18 [PATCH v3 0/3] Enable ptrace support for aarch64 sve Alan Hayward
  2018-06-15 16:18 ` [PATCH v3 3/3] Ptrace support for AArch64 SVE gdbsever Alan Hayward
@ 2018-06-15 16:18 ` Alan Hayward
  2018-06-15 16:18 ` [PATCH v3 1/3] Add Aarch64 SVE compatibility macros Alan Hayward
  2018-06-17  2:26 ` [PATCH v3 0/3] Enable ptrace support for aarch64 sve Simon Marchi
  3 siblings, 0 replies; 5+ messages in thread
From: Alan Hayward @ 2018-06-15 16:18 UTC (permalink / raw)
  To: gdb-patches; +Cc: nd, Alan Hayward

Add support for reading and writing registers for Aarch64 SVE.
I've made this functionality common as it will be required for
gdbserver when gdbsever sve support is added.

We need to support the cases where the kernel only gives us a
fpsimd structure. This occurs when there is no active SVE state
in the kernel (for example, after starting a new process).

Added checks to make sure the vector length has not changed whilst
the process is running.

2018-06-15  Alan Hayward  <alan.hayward@arm.com>

gdb/
	* aarch64-linux-nat.c (fetch_sveregs_from_thread): New function.
	(store_sveregs_to_thread): Likewise.
	(aarch64_linux_fetch_inferior_registers): Check for SVE.
	(aarch64_linux_store_inferior_registers): Likewise.
	* nat/aarch64-sve-linux-ptrace.c (aarch64_sve_get_sveregs): New
	function.
	(aarch64_sve_regs_copy_to_regcache): Likewise.
	(aarch64_sve_regs_copy_from_regcache): Likewise.
	* nat/aarch64-sve-linux-ptrace.h (aarch64_sve_get_sveregs): New
	declaration.
	(aarch64_sve_regs_copy_to_regcache): Likewise.
	(aarch64_sve_regs_copy_from_regcache): Likewise.
	(sve_context): Structure from Linux headers.
	(SVE_SIG_ZREGS_SIZE): Define from Linux headers.
	(SVE_SIG_ZREG_SIZE): Likewise.
	(SVE_SIG_PREG_SIZE): Likewise.
	(SVE_SIG_FFR_SIZE): Likewise.
	(SVE_SIG_REGS_OFFSET): Likewise.
	(SVE_SIG_ZREGS_OFFSET): Likewise.
	(SVE_SIG_ZREG_OFFSET): Likewise.
	(SVE_SIG_ZREGS_SIZE): Likewise.
	(SVE_SIG_PREGS_OFFSET): Likewise.
	(SVE_SIG_PREG_OFFSET): Likewise.
	(SVE_SIG_PREGS_SIZE): Likewise.
	(SVE_SIG_FFR_OFFSET): Likewise.
	(SVE_SIG_REGS_SIZE): Likewise.
	(SVE_SIG_CONTEXT_SIZE): Likewise.
	(SVE_PT_REGS_MASK): Likewise.
	(SVE_PT_REGS_FPSIMD): Likewise.
	(SVE_PT_REGS_SVE): Likewise.
	(SVE_PT_VL_INHERIT): Likewise.
	(SVE_PT_VL_ONEXEC): Likewise.
	(SVE_PT_REGS_OFFSET): Likewise.
	(SVE_PT_FPSIMD_OFFSET): Likewise.
	(SVE_PT_FPSIMD_SIZE): Likewise.
	(SVE_PT_SVE_ZREG_SIZE): Likewise.
	(SVE_PT_SVE_PREG_SIZE): Likewise.
	(SVE_PT_SVE_FFR_SIZE): Likewise.
	(SVE_PT_SVE_FPSR_SIZE): Likewise.
	(SVE_PT_SVE_FPCR_SIZE): Likewise.
	(__SVE_SIG_TO_PT): Likewise.
	(SVE_PT_SVE_OFFSET): Likewise.
	(SVE_PT_SVE_ZREGS_OFFSET): Likewise.
	(SVE_PT_SVE_ZREG_OFFSET): Likewise.
	(SVE_PT_SVE_ZREGS_SIZE): Likewise.
	(SVE_PT_SVE_PREGS_OFFSET): Likewise.
	(SVE_PT_SVE_PREG_OFFSET): Likewise.
	(SVE_PT_SVE_PREGS_SIZE): Likewise.
	(SVE_PT_SVE_FFR_OFFSET): Likewise.
	(SVE_PT_SVE_FPSR_OFFSET): Likewise.
	(SVE_PT_SVE_FPCR_OFFSET): Likewise.
	(SVE_PT_SVE_SIZE): Likewise.
	(SVE_PT_SIZE): Likewise.
	(HAS_SVE_STATE): New define.

gdbserver
	* Makefile.in: Add aarch64-sve-linux-ptrace.c.
---
 gdb/aarch64-linux-nat.c            |  54 +++++++-
 gdb/gdbserver/Makefile.in          |   1 +
 gdb/nat/aarch64-sve-linux-ptrace.c | 269 ++++++++++++++++++++++++++++++++++++-
 gdb/nat/aarch64-sve-linux-ptrace.h |  21 +++
 4 files changed, 342 insertions(+), 3 deletions(-)

diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c
index 1e4f937dc9..1e7db2920b 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);
+
+  /* Overwrite with regcache state.  */
+  aarch64_sve_regs_copy_from_reg_buf (regcache, base.get ());
+
+  /* Write back to the kernel.  */
+  iovec.iov_base = base.get ();
+  iovec.iov_len = ((struct user_sve_header *) base.get ())->size;
+  ret = ptrace (PTRACE_SETREGSET, tid, NT_ARM_SVE, &iovec);
+
+  if (ret < 0)
+    perror_with_name (_("Unable to store sve registers"));
+}
+
 /* Implement the "fetch_registers" target_ops method.  */
 
 void
 aarch64_linux_nat_target::fetch_registers (struct regcache *regcache,
 					   int regno)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
+
   if (regno == -1)
     {
       fetch_gregs_from_thread (regcache);
-      fetch_fpregs_from_thread (regcache);
+      if (tdep->has_sve ())
+	fetch_sveregs_from_thread (regcache);
+      else
+	fetch_fpregs_from_thread (regcache);
     }
   else if (regno < AARCH64_V0_REGNUM)
     fetch_gregs_from_thread (regcache);
+  else if (tdep->has_sve ())
+    fetch_sveregs_from_thread (regcache);
   else
     fetch_fpregs_from_thread (regcache);
 }
@@ -407,13 +450,20 @@ void
 aarch64_linux_nat_target::store_registers (struct regcache *regcache,
 					   int regno)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (regcache->arch ());
+
   if (regno == -1)
     {
       store_gregs_to_thread (regcache);
-      store_fpregs_to_thread (regcache);
+      if (tdep->has_sve ())
+	store_sveregs_to_thread (regcache);
+      else
+	store_fpregs_to_thread (regcache);
     }
   else if (regno < AARCH64_V0_REGNUM)
     store_gregs_to_thread (regcache);
+  else if (tdep->has_sve ())
+    store_sveregs_to_thread (regcache);
   else
     store_fpregs_to_thread (regcache);
 }
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index cf04b7d7b5..513f286289 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -219,6 +219,7 @@ SFILES = \
 	$(srcdir)/common/tdesc.c \
 	$(srcdir)/common/vec.c \
 	$(srcdir)/common/xml-utils.c \
+	$(srcdir)/nat/aarch64-sve-linux-ptrace.c \
 	$(srcdir)/nat/linux-btrace.c \
 	$(srcdir)/nat/linux-namespaces.c \
 	$(srcdir)/nat/linux-osdata.c \
diff --git a/gdb/nat/aarch64-sve-linux-ptrace.c b/gdb/nat/aarch64-sve-linux-ptrace.c
index 119656b886..a2f9261ba6 100644
--- a/gdb/nat/aarch64-sve-linux-ptrace.c
+++ b/gdb/nat/aarch64-sve-linux-ptrace.c
@@ -24,6 +24,10 @@
 #include "elf/common.h"
 #include "aarch64-sve-linux-ptrace.h"
 #include "arch/aarch64.h"
+#include "common-regcache.h"
+#include "common/byte-vector.h"
+
+static bool vq_change_warned = false;
 
 /* See nat/aarch64-sve-linux-ptrace.h.  */
 
@@ -46,7 +50,7 @@ aarch64_sve_get_vq (int tid)
       return 0;
     }
 
-  long vq = sve_vq_from_vl (header.vl);
+  uint64_t vq = sve_vq_from_vl (header.vl);
 
   if (!sve_vl_valid (header.vl))
     {
@@ -56,3 +60,266 @@ 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)
+{
+  char *base = (char *) buf;
+  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 (int i = 0; i < AARCH64_SVE_Z_REGS_NUM; i++)
+	reg_buf->raw_supply (AARCH64_SVE_Z0_REGNUM + i,
+			     base + SVE_PT_SVE_ZREG_OFFSET (vq, i));
+
+      for (int 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 (int 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);
+	}
+
+      reg_buf->raw_supply (AARCH64_FPSR_REGNUM, &fpsimd->fpsr);
+      reg_buf->raw_supply (AARCH64_FPCR_REGNUM, &fpsimd->fpcr);
+
+      /* Clear the SVE only registers.  */
+
+      for (int i = 0; i < AARCH64_SVE_P_REGS_NUM; i++)
+	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 (const struct reg_buffer_common *reg_buf,
+				    void *buf)
+{
+  struct user_sve_header *header = (struct user_sve_header *) buf;
+  char *base = (char *) 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_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.  */
+
+      bool has_sve_state = false;
+      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);
+
+      memset (zero_reg, 0, SVE_PT_SVE_ZREG_SIZE (vq));
+
+      /* Check in the reg_buf if any of the Z registers are set after the
+	 first 128 bits, or if any of the other SVE registers are set.  */
+
+      for (int i = 0; i < AARCH64_SVE_Z_REGS_NUM; i++)
+	{
+	  has_sve_state |= reg_buf->raw_compare (AARCH64_SVE_Z0_REGNUM + i,
+						 zero_reg, sizeof (__int128_t));
+	  if (has_sve_state)
+	    break;
+	}
+
+      if (!has_sve_state)
+	for (int i = 0; i < AARCH64_SVE_P_REGS_NUM; i++)
+	  {
+	    has_sve_state |= reg_buf->raw_compare (AARCH64_SVE_P0_REGNUM + i,
+						   zero_reg, 0);
+	    if (has_sve_state)
+	      break;
+	  }
+
+      if (!has_sve_state)
+	  has_sve_state |= reg_buf->raw_compare (AARCH64_SVE_FFR_REGNUM,
+						 zero_reg, 0);
+
+      /* If no SVE state exists, then use the existing fpsimd structure to
+	 write out state and return.  */
+      if (!has_sve_state)
+	{
+	  /* The collects of the Z registers will overflow the size of a vreg.
+	     There is enough space in the structure to allow for this, but we
+	     cannot overflow into the next register as we might not be
+	     collecting every register.  */
+
+	  for (int i = 0; i < AARCH64_SVE_Z_REGS_NUM; i++)
+	    {
+	      if (REG_VALID
+		  == reg_buf->get_register_status (AARCH64_SVE_Z0_REGNUM + i))
+		{
+		  reg_buf->raw_collect (AARCH64_SVE_Z0_REGNUM + i, zero_reg);
+		  memcpy (&fpsimd->vregs[i], zero_reg, sizeof (__int128_t));
+		}
+	    }
+
+	  if (REG_VALID == reg_buf->get_register_status (AARCH64_FPSR_REGNUM))
+	    reg_buf->raw_collect (AARCH64_FPSR_REGNUM, &fpsimd->fpsr);
+	  if (REG_VALID == reg_buf->get_register_status (AARCH64_FPCR_REGNUM))
+	    reg_buf->raw_collect (AARCH64_FPCR_REGNUM, &fpsimd->fpcr);
+
+	  return;
+	}
+
+      /* Otherwise, reformat the fpsimd structure into a full SVE set, by
+	 expanding the V registers (working backwards so we don't splat
+	 registers before they are copied) and using null for everything else.
+	 Note that enough space for a full SVE dump was originally allocated
+	 for base.  */
+
+      header->flags |= SVE_PT_REGS_SVE;
+      header->size = SVE_PT_SIZE (vq, SVE_PT_REGS_SVE);
+
+      memcpy (base + SVE_PT_SVE_FPSR_OFFSET (vq), &fpsimd->fpsr,
+	      sizeof (uint32_t));
+      memcpy (base + SVE_PT_SVE_FPCR_OFFSET (vq), &fpsimd->fpcr,
+	      sizeof (uint32_t));
+
+      for (int i = AARCH64_SVE_Z_REGS_NUM; i >= 0 ; i--)
+	{
+	  memcpy (base + SVE_PT_SVE_ZREG_OFFSET (vq, i), &fpsimd->vregs[i],
+		  sizeof (__int128_t));
+	}
+    }
+
+  /* Replace the kernel values with those from reg_buf.  */
+
+  for (int i = 0; i < AARCH64_SVE_Z_REGS_NUM; i++)
+    if (REG_VALID == reg_buf->get_register_status (AARCH64_SVE_Z0_REGNUM + i))
+      reg_buf->raw_collect (AARCH64_SVE_Z0_REGNUM + i,
+			    base + SVE_PT_SVE_ZREG_OFFSET (vq, i));
+
+  for (int i = 0; i < AARCH64_SVE_P_REGS_NUM; i++)
+    if (REG_VALID == reg_buf->get_register_status (AARCH64_SVE_P0_REGNUM + i))
+      reg_buf->raw_collect (AARCH64_SVE_P0_REGNUM + i,
+			    base + SVE_PT_SVE_PREG_OFFSET (vq, i));
+
+  if (REG_VALID == reg_buf->get_register_status (AARCH64_SVE_FFR_REGNUM))
+    reg_buf->raw_collect (AARCH64_SVE_FFR_REGNUM,
+			  base + SVE_PT_SVE_FFR_OFFSET (vq));
+  if (REG_VALID == reg_buf->get_register_status (AARCH64_FPSR_REGNUM))
+    reg_buf->raw_collect (AARCH64_FPSR_REGNUM,
+			  base + SVE_PT_SVE_FPSR_OFFSET (vq));
+  if (REG_VALID == reg_buf->get_register_status (AARCH64_FPCR_REGNUM))
+    reg_buf->raw_collect (AARCH64_FPCR_REGNUM,
+			  base + SVE_PT_SVE_FPCR_OFFSET (vq));
+
+}
diff --git a/gdb/nat/aarch64-sve-linux-ptrace.h b/gdb/nat/aarch64-sve-linux-ptrace.h
index 7f5a81f325..5a7186b7aa 100644
--- a/gdb/nat/aarch64-sve-linux-ptrace.h
+++ b/gdb/nat/aarch64-sve-linux-ptrace.h
@@ -29,9 +29,30 @@
 #include "aarch64-sve-linux-sigcontext.h"
 #endif
 
+/* Indicates whether a SVE ptrace header is followed by SVE registers or a
+   fpsimd structure.  */
+
+#define HAS_SVE_STATE(header) ((header).flags && SVE_PT_REGS_SVE)
+
 /* Read VQ for the given tid using ptrace.  If SVE is not supported then zero
    is returned (on a system that supports SVE, then VQ cannot be zero).  */
 
 uint64_t aarch64_sve_get_vq (int tid);
 
+/* Read the current SVE register set using ptrace, allocating space as
+   required.  */
+
+extern std::unique_ptr<gdb_byte[]> aarch64_sve_get_sveregs (int tid);
+
+/* Put the registers from linux structure buf into register buffer.  */
+
+extern void aarch64_sve_regs_copy_to_reg_buf (struct reg_buffer_common *reg_buf,
+					      const void *buf);
+
+/* Put the registers from register buffer into linux structure buf.  */
+
+extern void
+aarch64_sve_regs_copy_from_reg_buf (const struct reg_buffer_common *reg_buf,
+				    void *buf);
+
 #endif /* aarch64-sve-linux-ptrace.h */
-- 
2.15.1 (Apple Git-101)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3 3/3] Ptrace support for AArch64 SVE gdbsever
  2018-06-15 16:18 [PATCH v3 0/3] Enable ptrace support for aarch64 sve Alan Hayward
@ 2018-06-15 16:18 ` Alan Hayward
  2018-06-15 16:18 ` [PATCH v3 2/3] Ptrace support for Aarch64 SVE Alan Hayward
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Alan Hayward @ 2018-06-15 16:18 UTC (permalink / raw)
  To: gdb-patches; +Cc: nd, Alan Hayward

Add checks to detect SVE tdesc. Easiest way to do this is by checking the
size of the vector registers.

Use the common aarch64 ptrace copy functions for reading/writing registers.
A wrapper is required due to the common functions using reg_buffer_common.

2018-06-15  Alan Hayward  <alan.hayward@arm.com>

gdbserver/
	* linux-aarch64-low.c (is_sve_tdesc): New function.
	(aarch64_sve_regs_copy_to_regcache): Likewise.
	(aarch64_sve_regs_copy_from_regcache):  Likewise.
	(aarch64_regs_info): Add SVE checks.
	(initialize_low_arch): Initialize SVE.
---
 gdb/gdbserver/linux-aarch64-low.c | 63 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 60 insertions(+), 3 deletions(-)

diff --git a/gdb/gdbserver/linux-aarch64-low.c b/gdb/gdbserver/linux-aarch64-low.c
index 9db9a7c1c3..1d34e319df 100644
--- a/gdb/gdbserver/linux-aarch64-low.c
+++ b/gdb/gdbserver/linux-aarch64-low.c
@@ -41,6 +41,7 @@
 #include "arch/aarch64.h"
 #include "linux-aarch64-tdesc.h"
 #include "nat/aarch64-sve-linux-ptrace.h"
+#include "tdesc.h"
 
 #ifdef HAVE_SYS_REG_H
 #include <sys/reg.h>
@@ -73,6 +74,16 @@ is_64bit_tdesc (void)
   return register_size (regcache->tdesc, 0) == 8;
 }
 
+/* Return true if the regcache contains the number of SVE registers.  */
+
+static bool
+is_sve_tdesc (void)
+{
+  struct regcache *regcache = get_thread_regcache (current_thread, 0);
+
+  return regcache->tdesc->reg_defs.size () == AARCH64_SVE_NUM_REGS;
+}
+
 /* Implementation of linux_target_ops method "cannot_store_register".  */
 
 static int
@@ -514,6 +525,22 @@ aarch64_arch_setup (void)
   aarch64_linux_get_debug_reg_capacity (lwpid_of (current_thread));
 }
 
+/* Wrapper for aarch64_sve_regs_copy_to_reg_buf.  */
+
+static void
+aarch64_sve_regs_copy_to_regcache (struct regcache *regcache, const void *buf)
+{
+  return aarch64_sve_regs_copy_to_reg_buf (regcache, buf);
+}
+
+/* Wrapper for aarch64_sve_regs_copy_from_reg_buf.  */
+
+static void
+aarch64_sve_regs_copy_from_regcache (struct regcache *regcache, void *buf)
+{
+  return aarch64_sve_regs_copy_from_reg_buf (regcache, buf);
+}
+
 static struct regset_info aarch64_regsets[] =
 {
   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS,
@@ -540,15 +567,44 @@ static struct regs_info regs_info_aarch64 =
     &aarch64_regsets_info,
   };
 
+static struct regset_info aarch64_sve_regsets[] =
+{
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS,
+    sizeof (struct user_pt_regs), GENERAL_REGS,
+    aarch64_fill_gregset, aarch64_store_gregset },
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_SVE,
+    SVE_PT_SIZE (AARCH64_MAX_SVE_VQ, SVE_PT_REGS_SVE), EXTENDED_REGS,
+    aarch64_sve_regs_copy_from_regcache, aarch64_sve_regs_copy_to_regcache
+  },
+  NULL_REGSET
+};
+
+static struct regsets_info aarch64_sve_regsets_info =
+  {
+    aarch64_sve_regsets, /* regsets.  */
+    0, /* num_regsets.  */
+    NULL, /* disabled_regsets.  */
+  };
+
+static struct regs_info regs_info_aarch64_sve =
+  {
+    NULL, /* regset_bitmap.  */
+    NULL, /* usrregs.  */
+    &aarch64_sve_regsets_info,
+  };
+
 /* Implementation of linux_target_ops method "regs_info".  */
 
 static const struct regs_info *
 aarch64_regs_info (void)
 {
-  if (is_64bit_tdesc ())
-    return &regs_info_aarch64;
-  else
+  if (!is_64bit_tdesc ())
     return &regs_info_aarch32;
+
+  if (is_sve_tdesc ())
+    return &regs_info_aarch64_sve;
+
+  return &regs_info_aarch64;
 }
 
 /* Implementation of linux_target_ops method "supports_tracepoints".  */
@@ -3027,6 +3083,7 @@ initialize_low_arch (void)
   initialize_low_arch_aarch32 ();
 
   initialize_regsets_info (&aarch64_regsets_info);
+  initialize_regsets_info (&aarch64_sve_regsets_info);
 
 #if GDB_SELF_TEST
   initialize_low_tdesc ();
-- 
2.15.1 (Apple Git-101)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v3 1/3] Add Aarch64 SVE compatibility macros
  2018-06-15 16:18 [PATCH v3 0/3] Enable ptrace support for aarch64 sve Alan Hayward
  2018-06-15 16:18 ` [PATCH v3 3/3] Ptrace support for AArch64 SVE gdbsever Alan Hayward
  2018-06-15 16:18 ` [PATCH v3 2/3] Ptrace support for Aarch64 SVE Alan Hayward
@ 2018-06-15 16:18 ` Alan Hayward
  2018-06-17  2:26 ` [PATCH v3 0/3] Enable ptrace support for aarch64 sve Simon Marchi
  3 siblings, 0 replies; 5+ messages in thread
From: Alan Hayward @ 2018-06-15 16:18 UTC (permalink / raw)
  To: gdb-patches; +Cc: nd, Alan Hayward

This header provides compatibility support for SVE allow building
even when the underlying host system lacks support for SVE.
If the binary is then run on an SVE-enabled kernel then support
will automatically be available.

2018-06-15  Alan Hayward  <alan.hayward@arm.com>

	* nat/aarch64-sve-linux-sigcontext.h: New file.
	* nat/aarch64-sve-linux-ptrace.h (SVE_VQ_BYTES): Move to
	new file.
	(SVE_VQ_MIN): Likewise.
	(SVE_VQ_MAX): Likewise.
	(SVE_VL_MIN): Likewise.
	(SVE_VL_MAX): Likewise.
	(SVE_NUM_ZREGS): Likewise.
	(SVE_NUM_PREGS): Likewise.
	(sve_vl_valid): Likewise.
	(struct user_sve_header): Likewise.
---
 gdb/nat/aarch64-sve-linux-ptrace.h     |  44 +-----
 gdb/nat/aarch64-sve-linux-sigcontext.h | 268 +++++++++++++++++++++++++++++++++
 2 files changed, 272 insertions(+), 40 deletions(-)
 create mode 100644 gdb/nat/aarch64-sve-linux-sigcontext.h

diff --git a/gdb/nat/aarch64-sve-linux-ptrace.h b/gdb/nat/aarch64-sve-linux-ptrace.h
index 61f841466c..7f5a81f325 100644
--- a/gdb/nat/aarch64-sve-linux-ptrace.h
+++ b/gdb/nat/aarch64-sve-linux-ptrace.h
@@ -20,54 +20,18 @@
 #ifndef AARCH64_SVE_LINUX_PTRACE_H
 #define AARCH64_SVE_LINUX_PTRACE_H
 
-/* Where indicated, this file contains defines and macros lifted directly from
-   the Linux kernel headers, with no modification.
-   Refer to Linux kernel documentation for details.  */
-
 #include <asm/sigcontext.h>
 #include <sys/utsname.h>
 #include <sys/ptrace.h>
 #include <asm/ptrace.h>
 
+#ifndef SVE_SIG_ZREGS_SIZE
+#include "aarch64-sve-linux-sigcontext.h"
+#endif
+
 /* Read VQ for the given tid using ptrace.  If SVE is not supported then zero
    is returned (on a system that supports SVE, then VQ cannot be zero).  */
 
 uint64_t aarch64_sve_get_vq (int tid);
 
-/* Structures and defines taken from sigcontext.h.  */
-
-#ifndef SVE_SIG_ZREGS_SIZE
-
-#define SVE_VQ_BYTES		16	/* number of bytes per quadword */
-
-#define SVE_VQ_MIN		1
-#define SVE_VQ_MAX		512
-
-#define SVE_VL_MIN		(SVE_VQ_MIN * SVE_VQ_BYTES)
-#define SVE_VL_MAX		(SVE_VQ_MAX * SVE_VQ_BYTES)
-
-#define SVE_NUM_ZREGS		32
-#define SVE_NUM_PREGS		16
-
-#define sve_vl_valid(vl) \
-	((vl) % SVE_VQ_BYTES == 0 && (vl) >= SVE_VL_MIN && (vl) <= SVE_VL_MAX)
-
-#endif /* SVE_SIG_ZREGS_SIZE.  */
-
-
-/* Structures and defines taken from ptrace.h.  */
-
-#ifndef SVE_PT_SVE_ZREG_SIZE
-
-struct user_sve_header {
-	__u32 size; /* total meaningful regset content in bytes */
-	__u32 max_size; /* maxmium possible size for this thread */
-	__u16 vl; /* current vector length */
-	__u16 max_vl; /* maximum possible vector length */
-	__u16 flags;
-	__u16 __reserved;
-};
-
-#endif /* SVE_PT_SVE_ZREG_SIZE.  */
-
 #endif /* aarch64-sve-linux-ptrace.h */
diff --git a/gdb/nat/aarch64-sve-linux-sigcontext.h b/gdb/nat/aarch64-sve-linux-sigcontext.h
new file mode 100644
index 0000000000..bdece8e17d
--- /dev/null
+++ b/gdb/nat/aarch64-sve-linux-sigcontext.h
@@ -0,0 +1,268 @@
+/* Copyright (C) 2018 Free Software Foundation, Inc.
+   Contributed by Arm Ltd.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef AARCH64_SVE_LINUX_SIGCONTEXT_H
+#define AARCH64_SVE_LINUX_SIGCONTEXT_H
+
+#define SVE_MAGIC	0x53564501
+
+struct sve_context {
+	struct _aarch64_ctx head;
+	__u16 vl;
+	__u16 __reserved[3];
+};
+
+/*
+ * The SVE architecture leaves space for future expansion of the
+ * vector length beyond its initial architectural limit of 2048 bits
+ * (16 quadwords).
+ *
+ * See linux/Documentation/arm64/sve.txt for a description of the VL/VQ
+ * terminology.
+ */
+#define SVE_VQ_BYTES		16	/* number of bytes per quadword */
+
+#define SVE_VQ_MIN		1
+#define SVE_VQ_MAX		512
+
+#define SVE_VL_MIN		(SVE_VQ_MIN * SVE_VQ_BYTES)
+#define SVE_VL_MAX		(SVE_VQ_MAX * SVE_VQ_BYTES)
+
+#define SVE_NUM_ZREGS		32
+#define SVE_NUM_PREGS		16
+
+#define sve_vl_valid(vl) \
+	((vl) % SVE_VQ_BYTES == 0 && (vl) >= SVE_VL_MIN && (vl) <= SVE_VL_MAX)
+
+/*
+ * If the SVE registers are currently live for the thread at signal delivery,
+ * sve_context.head.size >=
+ *	SVE_SIG_CONTEXT_SIZE(sve_vq_from_vl(sve_context.vl))
+ * and the register data may be accessed using the SVE_SIG_*() macros.
+ *
+ * If sve_context.head.size <
+ *	SVE_SIG_CONTEXT_SIZE(sve_vq_from_vl(sve_context.vl)),
+ * the SVE registers were not live for the thread and no register data
+ * is included: in this case, the SVE_SIG_*() macros should not be
+ * used except for this check.
+ *
+ * The same convention applies when returning from a signal: a caller
+ * will need to remove or resize the sve_context block if it wants to
+ * make the SVE registers live when they were previously non-live or
+ * vice-versa.  This may require the the caller to allocate fresh
+ * memory and/or move other context blocks in the signal frame.
+ *
+ * Changing the vector length during signal return is not permitted:
+ * sve_context.vl must equal the thread's current vector length when
+ * doing a sigreturn.
+ *
+ *
+ * Note: for all these macros, the "vq" argument denotes the SVE
+ * vector length in quadwords (i.e., units of 128 bits).
+ *
+ * The correct way to obtain vq is to use sve_vq_from_vl(vl).  The
+ * result is valid if and only if sve_vl_valid(vl) is true.  This is
+ * guaranteed for a struct sve_context written by the kernel.
+ *
+ *
+ * Additional macros describe the contents and layout of the payload.
+ * For each, SVE_SIG_x_OFFSET(args) is the start offset relative to
+ * the start of struct sve_context, and SVE_SIG_x_SIZE(args) is the
+ * size in bytes:
+ *
+ *	x	type				description
+ *	-	----				-----------
+ *	REGS					the entire SVE context
+ *
+ *	ZREGS	__uint128_t[SVE_NUM_ZREGS][vq]	all Z-registers
+ *	ZREG	__uint128_t[vq]			individual Z-register Zn
+ *
+ *	PREGS	uint16_t[SVE_NUM_PREGS][vq]	all P-registers
+ *	PREG	uint16_t[vq]			individual P-register Pn
+ *
+ *	FFR	uint16_t[vq]			first-fault status register
+ *
+ * Additional data might be appended in the future.
+ */
+
+#define SVE_SIG_ZREG_SIZE(vq)	((__u32)(vq) * SVE_VQ_BYTES)
+#define SVE_SIG_PREG_SIZE(vq)	((__u32)(vq) * (SVE_VQ_BYTES / 8))
+#define SVE_SIG_FFR_SIZE(vq)	SVE_SIG_PREG_SIZE(vq)
+
+#define SVE_SIG_REGS_OFFSET					\
+	((sizeof(struct sve_context) + (SVE_VQ_BYTES - 1))	\
+		/ SVE_VQ_BYTES * SVE_VQ_BYTES)
+
+#define SVE_SIG_ZREGS_OFFSET	SVE_SIG_REGS_OFFSET
+#define SVE_SIG_ZREG_OFFSET(vq, n) \
+	(SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREG_SIZE(vq) * (n))
+#define SVE_SIG_ZREGS_SIZE(vq) \
+	(SVE_SIG_ZREG_OFFSET(vq, SVE_NUM_ZREGS) - SVE_SIG_ZREGS_OFFSET)
+
+#define SVE_SIG_PREGS_OFFSET(vq) \
+	(SVE_SIG_ZREGS_OFFSET + SVE_SIG_ZREGS_SIZE(vq))
+#define SVE_SIG_PREG_OFFSET(vq, n) \
+	(SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREG_SIZE(vq) * (n))
+#define SVE_SIG_PREGS_SIZE(vq) \
+	(SVE_SIG_PREG_OFFSET(vq, SVE_NUM_PREGS) - SVE_SIG_PREGS_OFFSET(vq))
+
+#define SVE_SIG_FFR_OFFSET(vq) \
+	(SVE_SIG_PREGS_OFFSET(vq) + SVE_SIG_PREGS_SIZE(vq))
+
+#define SVE_SIG_REGS_SIZE(vq) \
+	(SVE_SIG_FFR_OFFSET(vq) + SVE_SIG_FFR_SIZE(vq) - SVE_SIG_REGS_OFFSET)
+
+#define SVE_SIG_CONTEXT_SIZE(vq) (SVE_SIG_REGS_OFFSET + SVE_SIG_REGS_SIZE(vq))
+
+/* SVE/FP/SIMD state (NT_ARM_SVE) */
+
+struct user_sve_header {
+	__u32 size; /* total meaningful regset content in bytes */
+	__u32 max_size; /* maxmium possible size for this thread */
+	__u16 vl; /* current vector length */
+	__u16 max_vl; /* maximum possible vector length */
+	__u16 flags;
+	__u16 __reserved;
+};
+
+/* Definitions for user_sve_header.flags: */
+#define SVE_PT_REGS_MASK		(1 << 0)
+
+#define SVE_PT_REGS_FPSIMD		0
+#define SVE_PT_REGS_SVE			SVE_PT_REGS_MASK
+
+/*
+ * Common SVE_PT_* flags:
+ * These must be kept in sync with prctl interface in <linux/ptrace.h>
+ */
+#define SVE_PT_VL_INHERIT		(PR_SVE_VL_INHERIT >> 16)
+#define SVE_PT_VL_ONEXEC		(PR_SVE_SET_VL_ONEXEC >> 16)
+
+
+/*
+ * The remainder of the SVE state follows struct user_sve_header.  The
+ * total size of the SVE state (including header) depends on the
+ * metadata in the header:  SVE_PT_SIZE(vq, flags) gives the total size
+ * of the state in bytes, including the header.
+ *
+ * Refer to <asm/sigcontext.h> for details of how to pass the correct
+ * "vq" argument to these macros.
+ */
+
+/* Offset from the start of struct user_sve_header to the register data */
+#define SVE_PT_REGS_OFFSET					\
+	((sizeof(struct sve_context) + (SVE_VQ_BYTES - 1))	\
+		/ SVE_VQ_BYTES * SVE_VQ_BYTES)
+
+/*
+ * The register data content and layout depends on the value of the
+ * flags field.
+ */
+
+/*
+ * (flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_FPSIMD case:
+ *
+ * The payload starts at offset SVE_PT_FPSIMD_OFFSET, and is of type
+ * struct user_fpsimd_state.  Additional data might be appended in the
+ * future: use SVE_PT_FPSIMD_SIZE(vq, flags) to compute the total size.
+ * SVE_PT_FPSIMD_SIZE(vq, flags) will never be less than
+ * sizeof(struct user_fpsimd_state).
+ */
+
+#define SVE_PT_FPSIMD_OFFSET		SVE_PT_REGS_OFFSET
+
+#define SVE_PT_FPSIMD_SIZE(vq, flags)	(sizeof(struct user_fpsimd_state))
+
+/*
+ * (flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE case:
+ *
+ * The payload starts at offset SVE_PT_SVE_OFFSET, and is of size
+ * SVE_PT_SVE_SIZE(vq, flags).
+ *
+ * Additional macros describe the contents and layout of the payload.
+ * For each, SVE_PT_SVE_x_OFFSET(args) is the start offset relative to
+ * the start of struct user_sve_header, and SVE_PT_SVE_x_SIZE(args) is
+ * the size in bytes:
+ *
+ *	x	type				description
+ *	-	----				-----------
+ *	ZREGS		\
+ *	ZREG		|
+ *	PREGS		| refer to <asm/sigcontext.h>
+ *	PREG		|
+ *	FFR		/
+ *
+ *	FPSR	uint32_t			FPSR
+ *	FPCR	uint32_t			FPCR
+ *
+ * Additional data might be appended in the future.
+ */
+
+#define SVE_PT_SVE_ZREG_SIZE(vq)	SVE_SIG_ZREG_SIZE(vq)
+#define SVE_PT_SVE_PREG_SIZE(vq)	SVE_SIG_PREG_SIZE(vq)
+#define SVE_PT_SVE_FFR_SIZE(vq)		SVE_SIG_FFR_SIZE(vq)
+#define SVE_PT_SVE_FPSR_SIZE		sizeof(__u32)
+#define SVE_PT_SVE_FPCR_SIZE		sizeof(__u32)
+
+#define __SVE_SIG_TO_PT(offset) \
+	((offset) - SVE_SIG_REGS_OFFSET + SVE_PT_REGS_OFFSET)
+
+#define SVE_PT_SVE_OFFSET		SVE_PT_REGS_OFFSET
+
+#define SVE_PT_SVE_ZREGS_OFFSET \
+	__SVE_SIG_TO_PT(SVE_SIG_ZREGS_OFFSET)
+#define SVE_PT_SVE_ZREG_OFFSET(vq, n) \
+	__SVE_SIG_TO_PT(SVE_SIG_ZREG_OFFSET(vq, n))
+#define SVE_PT_SVE_ZREGS_SIZE(vq) \
+	(SVE_PT_SVE_ZREG_OFFSET(vq, SVE_NUM_ZREGS) - SVE_PT_SVE_ZREGS_OFFSET)
+
+#define SVE_PT_SVE_PREGS_OFFSET(vq) \
+	__SVE_SIG_TO_PT(SVE_SIG_PREGS_OFFSET(vq))
+#define SVE_PT_SVE_PREG_OFFSET(vq, n) \
+	__SVE_SIG_TO_PT(SVE_SIG_PREG_OFFSET(vq, n))
+#define SVE_PT_SVE_PREGS_SIZE(vq) \
+	(SVE_PT_SVE_PREG_OFFSET(vq, SVE_NUM_PREGS) - \
+		SVE_PT_SVE_PREGS_OFFSET(vq))
+
+#define SVE_PT_SVE_FFR_OFFSET(vq) \
+	__SVE_SIG_TO_PT(SVE_SIG_FFR_OFFSET(vq))
+
+#define SVE_PT_SVE_FPSR_OFFSET(vq)				\
+	((SVE_PT_SVE_FFR_OFFSET(vq) + SVE_PT_SVE_FFR_SIZE(vq) +	\
+			(SVE_VQ_BYTES - 1))			\
+		/ SVE_VQ_BYTES * SVE_VQ_BYTES)
+#define SVE_PT_SVE_FPCR_OFFSET(vq) \
+	(SVE_PT_SVE_FPSR_OFFSET(vq) + SVE_PT_SVE_FPSR_SIZE)
+
+/*
+ * Any future extension appended after FPCR must be aligned to the next
+ * 128-bit boundary.
+ */
+
+#define SVE_PT_SVE_SIZE(vq, flags)					\
+	((SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE		\
+			- SVE_PT_SVE_OFFSET + (SVE_VQ_BYTES - 1))	\
+		/ SVE_VQ_BYTES * SVE_VQ_BYTES)
+
+#define SVE_PT_SIZE(vq, flags)						\
+	 (((flags) & SVE_PT_REGS_MASK) == SVE_PT_REGS_SVE ?		\
+		  SVE_PT_SVE_OFFSET + SVE_PT_SVE_SIZE(vq, flags)	\
+		: SVE_PT_FPSIMD_OFFSET + SVE_PT_FPSIMD_SIZE(vq, flags))
+
+
+#endif /* AARCH64_SVE_LINUX_SIGCONTEXT_H */
-- 
2.15.1 (Apple Git-101)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v3 0/3] Enable ptrace support for aarch64 sve
  2018-06-15 16:18 [PATCH v3 0/3] Enable ptrace support for aarch64 sve Alan Hayward
                   ` (2 preceding siblings ...)
  2018-06-15 16:18 ` [PATCH v3 1/3] Add Aarch64 SVE compatibility macros Alan Hayward
@ 2018-06-17  2:26 ` Simon Marchi
  3 siblings, 0 replies; 5+ messages in thread
From: Simon Marchi @ 2018-06-17  2:26 UTC (permalink / raw)
  To: Alan Hayward, gdb-patches; +Cc: nd

On 2018-06-15 12:18 PM, Alan Hayward wrote:
> This set of patches adds the ptrace support for SVE.
> 
> Patch 1 includes macros/defines copied from the Linux kernel headers.
> Previously, there was reservation about the copyright/ownership issues
> about putting this into gdb. These header contents were all fully written
> by Arm, who own the copyright and released it to Linux under GPL3 license.
> This patch simply repackages the same code and releases it with the
> same license and "provided by Arm" comment. There is precedence for
> Arm doing the same in other FSF projects, and it falls within GPLs
> copyleft policy.
> 
> I've also kept all the defines in a single file as it only contains
> the relevant sections from two headers.
> 
> Apologies for the delay on submitting this, as I was seeking
> clarification to the above. I'm hoping this alleviates any concerns.
> It's also a more robust solution than selectively compiling support.
> 
> Patches 2 and 3 fix up all the review comments from v2.
> In particular, patch 3 changes is_sve_tdesc to the only method I
> could find - checking the number of registers.
> 
> Ran make check on x86 and aarch64.
> Tested SVE and non-SVE built gdb on Aarch64 SVE emulator.
> 
> In addition, I've still got the following awaiting review:
> [PATCH] Support large registers in regcache transfer_regset
> https://sourceware.org/ml/gdb-patches/2018-06/msg00303.html

Thanks, the patchset LGTM.

Note the typo in the third patch's title, "gdbsever".

Simon

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-06-17  2:26 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-15 16:18 [PATCH v3 0/3] Enable ptrace support for aarch64 sve Alan Hayward
2018-06-15 16:18 ` [PATCH v3 3/3] Ptrace support for AArch64 SVE gdbsever Alan Hayward
2018-06-15 16:18 ` [PATCH v3 2/3] Ptrace support for Aarch64 SVE Alan Hayward
2018-06-15 16:18 ` [PATCH v3 1/3] Add Aarch64 SVE compatibility macros Alan Hayward
2018-06-17  2:26 ` [PATCH v3 0/3] Enable ptrace support for aarch64 sve Simon Marchi

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).