AArch64: gdbserver: read pauth registers
authorAlan Hayward <alan.hayward@arm.com>
Fri, 22 Mar 2019 10:34:09 +0000 (10:34 +0000)
committerAlan Hayward <alan.hayward@arm.com>
Fri, 22 Mar 2019 10:34:09 +0000 (10:34 +0000)
Add the pauth registers to the regset lists.

Add a new regset type OPTIONAL_REGS which allows for the regset read to fail.
Once the read fails, it will not be checked again.  This allows targets with
optional features to keep a single static regset_info structure.

gdb/ChangeLog:

* arch/aarch64.h (AARCH64_PAUTH_REGS_SIZE): New define.

gdb/gdbserver/ChangeLog:

* linux-aarch64-low.c (aarch64_store_pauthregset): New function.
* linux-low.c (regsets_store_inferior_registers): Allow optional reads
to fail.
* linux-low.h (enum regset_type): Add OPTIONAL_REGS.

gdb/ChangeLog
gdb/arch/aarch64.h
gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-aarch64-low.c
gdb/gdbserver/linux-low.c
gdb/gdbserver/linux-low.h

index 78ec7045d338b66afe47003970d7715d3ba1e8ca..8622c9bfa8157929ed0563d8a94740bdb671ceb1 100644 (file)
@@ -1,3 +1,8 @@
+2019-03-22  Alan Hayward  <alan.hayward@arm.com>
+           Jiong Wang  <jiong.wang@arm.com>
+
+       * arch/aarch64.h (AARCH64_PAUTH_REGS_SIZE): New define.
+
 2019-03-22  Alan Hayward  <alan.hayward@arm.com>
            Jiong Wang  <jiong.wang@arm.com>
 
index 8c80b7be62426c1c32cbfef18d3bd98b1d354bf5..309fe75273ef5175f11ebb6b111e260ac5da2aef 100644 (file)
@@ -68,6 +68,7 @@ enum aarch64_regnum
 
 #define AARCH64_PAUTH_DMASK_REGNUM(pauth_reg_base) (pauth_reg_base)
 #define AARCH64_PAUTH_CMASK_REGNUM(pauth_reg_base) (pauth_reg_base + 1)
+#define AARCH64_PAUTH_REGS_SIZE (16)
 
 #define AARCH64_X_REGS_NUM 31
 #define AARCH64_V_REGS_NUM 32
index 3b585ca99239ecbeaa2479e7e303f344b46fc9d6..21c286d5ef3e710f1c5a849dcb82de205974c7f6 100644 (file)
@@ -1,3 +1,11 @@
+2019-03-22  Alan Hayward  <alan.hayward@arm.com>
+           Jiong Wang  <jiong.wang@arm.com>
+
+       * linux-aarch64-low.c (aarch64_store_pauthregset): New function.
+       * linux-low.c (regsets_store_inferior_registers): Allow optional reads
+       to fail.
+       * linux-low.h (enum regset_type): Add OPTIONAL_REGS.
+
 2019-03-22  Alan Hayward  <alan.hayward@arm.com>
            Jiong Wang  <jiong.wang@arm.com>
 
index e2e25f0e27a4143edd81f0378caa322494dbe6c6..20c75493b07c03c044258055219326c05e606128 100644 (file)
@@ -135,6 +135,23 @@ aarch64_store_fpregset (struct regcache *regcache, const void *buf)
   supply_register (regcache, AARCH64_FPCR_REGNUM, &regset->fpcr);
 }
 
+/* Store the pauth registers to regcache.  */
+
+static void
+aarch64_store_pauthregset (struct regcache *regcache, const void *buf)
+{
+  uint64_t *pauth_regset = (uint64_t *) buf;
+  int pauth_base = find_regno (regcache->tdesc, "pauth_dmask");
+
+  if (pauth_base == 0)
+    return;
+
+  supply_register (regcache, AARCH64_PAUTH_DMASK_REGNUM (pauth_base),
+                  &pauth_regset[0]);
+  supply_register (regcache, AARCH64_PAUTH_CMASK_REGNUM (pauth_base),
+                  &pauth_regset[1]);
+}
+
 /* Enable miscellaneous debugging output.  The name is historical - it
    was originally used to debug LinuxThreads support.  */
 extern int debug_threads;
@@ -564,6 +581,9 @@ static struct regset_info aarch64_regsets[] =
     sizeof (struct user_fpsimd_state), FP_REGS,
     aarch64_fill_fpregset, aarch64_store_fpregset
   },
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_PAC_MASK,
+    AARCH64_PAUTH_REGS_SIZE, OPTIONAL_REGS,
+    NULL, aarch64_store_pauthregset },
   NULL_REGSET
 };
 
@@ -590,6 +610,9 @@ static struct regset_info aarch64_sve_regsets[] =
     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
   },
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_PAC_MASK,
+    AARCH64_PAUTH_REGS_SIZE, OPTIONAL_REGS,
+    NULL, aarch64_store_pauthregset },
   NULL_REGSET
 };
 
index b1a9d1289902ed6a88a7d1dbd731da4ec48b5e29..6f703f589fe931c86c27bf750cf6ee144062befd 100644 (file)
@@ -5358,10 +5358,11 @@ regsets_fetch_inferior_registers (struct regsets_info *regsets_info,
 #endif
       if (res < 0)
        {
-         if (errno == EIO)
+         if (errno == EIO
+             || (errno == EINVAL && regset->type == OPTIONAL_REGS))
            {
-             /* If we get EIO on a regset, do not try it again for
-                this process mode.  */
+             /* If we get EIO on a regset, or an EINVAL and the regset is
+                optional, do not try it again for this process mode.  */
              disable_regset (regsets_info, regset);
            }
          else if (errno == ENODATA)
@@ -5456,10 +5457,11 @@ regsets_store_inferior_registers (struct regsets_info *regsets_info,
 
       if (res < 0)
        {
-         if (errno == EIO)
+         if (errno == EIO
+             || (errno == EINVAL && regset->type == OPTIONAL_REGS))
            {
-             /* If we get EIO on a regset, do not try it again for
-                this process mode.  */
+             /* If we get EIO on a regset, or an EINVAL and the regset is
+                optional, do not try it again for this process mode.  */
              disable_regset (regsets_info, regset);
            }
          else if (errno == ESRCH)
index d09390dd99d8df3d62f66ca2459861b15fc43691..1ade35d64850f86168c0a0043165bc681c20721f 100644 (file)
@@ -40,6 +40,7 @@ enum regset_type {
   GENERAL_REGS,
   FP_REGS,
   EXTENDED_REGS,
+  OPTIONAL_REGS, /* Do not error if the regset cannot be accessed.  */
 };
 
 /* The arch's regsets array initializer must be terminated with a NULL