Patchwork [AArch64,2/6] "pauth" feature gdbserver support

login
register
mail settings
Submitter Jiong Wang
Date Aug. 9, 2017, 12:22 p.m.
Message ID <22fbb2eb-c65b-692c-86d7-65a340b0d889@foss.arm.com>
Download mbox | patch
Permalink /patch/22039/
State New
Headers show

Comments

Jiong Wang - Aug. 9, 2017, 12:22 p.m.
This patch adds the new ARMv8.3-A pointer authentication feature support for
gdbserver on linux configuration.

The support is straightforward.  "pauth" ptrace regset are added, and store
function (read from ptrace and store into regcache) is implemented.

gdb/gdbserver/
2017-08-09  Jiong Wang<jiong.wang@arm.com>

	* configure.srv (srv_regobj): Add aarch64-pauth.o.
	(srv_xmlfiles): Add aarch64-pauth.xml and aarch64-pauth-core.xml.
	(ipa_obj): Add aarch64-pauth.o.
	* linux-aarch64-low.c (init_registers_aarch64_pauth): New
	declaration.
	(tdesc_aarch64_pauth): Likewise.
	(aarch64_store_pauthregset): Likewise.
	(aarch64_cannot_store_register): Add some comments.
	(aarch64_linux_read_description): Support pauth feature.
	(aarch64_pauth_regsets): New regset_info.
	(aarch64_pauth_regsets_info): New regsets_info.
	(regs_info_aarch64_pauth): New regs_info.
	(aarch64_regs_info): Support pauth feature.
	(initialize_low_arch): Call init_registers_aarch64_pauth and also
	initialize regsets info from aarch64_pauth_regsets_info.

Patch

diff --git a/gdb/gdbserver/configure.srv b/gdb/gdbserver/configure.srv
index 808af0d..fa328f0 100644
--- a/gdb/gdbserver/configure.srv
+++ b/gdb/gdbserver/configure.srv
@@ -51,6 +51,7 @@  srv_linux_obj="linux-low.o linux-osdata.o linux-procfs.o linux-ptrace.o linux-wa
 case "${target}" in
   aarch64*-*-linux*)
 			srv_regobj="aarch64.o"
+			srv_regobj="${srv_regobj} aarch64-pauth.o"
 			srv_regobj="${srv_regobj} arm-with-neon.o"
 			srv_tgtobj="linux-aarch64-low.o aarch64-linux-hw-point.o"
 			srv_tgtobj="$srv_tgtobj linux-aarch32-low.o"
@@ -59,13 +60,16 @@  case "${target}" in
 			srv_tgtobj="$srv_tgtobj aarch64-insn.o"
 			srv_tgtobj="${srv_tgtobj} $srv_linux_obj"
 			srv_xmlfiles="aarch64.xml"
+			srv_xmlfiles="${srv_xmlfiles} aarch64-pauth.xml"
 			srv_xmlfiles="${srv_xmlfiles} aarch64-core.xml"
+			srv_xmlfiles="${srv_xmlfiles} aarch64-pauth-core.xml"
 			srv_xmlfiles="${srv_xmlfiles} aarch64-fpu.xml"
 			srv_xmlfiles="${srv_xmlfiles} arm/arm-core.xml arm/arm-vfpv3.xml"
 			srv_xmlfiles="${srv_xmlfiles} arm/arm-with-neon.xml"
 			srv_linux_regsets=yes
 			srv_linux_thread_db=yes
 			ipa_obj="linux-aarch64-ipa.o aarch64-ipa.o"
+			ipa_obj="linux-aarch64-ipa.o aarch64-ipa.o aarch64-pauth.o"
 			;;
   arm*-*-linux*)	srv_regobj="reg-arm.o arm-with-iwmmxt.o"
 			srv_regobj="${srv_regobj} arm-with-vfpv2.o"
diff --git a/gdb/gdbserver/linux-aarch64-low.c b/gdb/gdbserver/linux-aarch64-low.c
index 334310b..0f45b03 100644
--- a/gdb/gdbserver/linux-aarch64-low.c
+++ b/gdb/gdbserver/linux-aarch64-low.c
@@ -41,7 +41,9 @@ 
 
 /* Defined in auto-generated files.  */
 void init_registers_aarch64 (void);
+void init_registers_aarch64_pauth (void);
 extern const struct target_desc *tdesc_aarch64;
+extern const struct target_desc *tdesc_aarch64_pauth;
 
 #ifdef HAVE_SYS_REG_H
 #include <sys/reg.h>
@@ -91,6 +93,7 @@  is_64bit_tdesc (void)
 static int
 aarch64_cannot_store_register (int regno)
 {
+  /* FPSR, FPCR, PAUTH_DMASK, PAUTH_CMASK are read-only. */
   return regno >= AARCH64_NUM_REGS;
 }
 
@@ -153,6 +156,18 @@  aarch64_store_fpregset (struct regcache *regcache, const void *buf)
   supply_register (regcache, AARCH64_FPCR_REGNO, &regset->fpcr);
 }
 
+/* regset_store_func for NT_ARM_PAC_MASK.  */
+
+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");
+
+  supply_register (regcache, pauth_base, &pauth_regset[0]);
+  supply_register (regcache, pauth_base + 1, &pauth_regset[1]);
+}
+
 /* Enable miscellaneous debugging output.  The name is historical - it
    was originally used to debug LinuxThreads support.  */
 extern int debug_threads;
@@ -485,7 +500,13 @@  aarch64_linux_read_description (void)
   is_elf64 = linux_pid_exe_is_elf_64_file (tid, &machine);
 
   if (is_elf64)
-    return tdesc_aarch64;
+    {
+      CORE_ADDR hwcap = 0;
+
+      aarch64_host_hwcap (&hwcap);
+
+      return (hwcap & HWCAP_APIA) ? tdesc_aarch64_pauth : tdesc_aarch64;
+    }
   else
     return tdesc_arm_with_neon;
 }
@@ -526,13 +547,49 @@  static struct regs_info regs_info_aarch64 =
     &aarch64_regsets_info,
   };
 
+static struct regset_info aarch64_pauth_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_FPREGSET,
+    sizeof (struct user_fpsimd_state), FP_REGS,
+    aarch64_fill_fpregset, aarch64_store_fpregset },
+#define AARCH64_PAUTH_REGS_SIZE (16)
+  { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_ARM_PAC_MASK,
+    AARCH64_PAUTH_REGS_SIZE, EXTENDED_REGS,
+    NULL, aarch64_store_pauthregset },
+  NULL_REGSET
+};
+
+static struct regsets_info aarch64_pauth_regsets_info =
+  {
+    aarch64_pauth_regsets, /* regsets */
+    0, /* num_regsets */
+    NULL, /* disabled_regsets */
+  };
+
+static struct regs_info regs_info_aarch64_pauth =
+  {
+    NULL, /* regset_bitmap */
+    NULL, /* usrregs */
+    &aarch64_pauth_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;
+    {
+      CORE_ADDR hwcap = 0;
+
+      aarch64_host_hwcap (&hwcap);
+
+      return (hwcap & HWCAP_APIA
+	      ? &regs_info_aarch64_pauth : &regs_info_aarch64);
+    }
   else
     return &regs_info_aarch32;
 }
@@ -3009,8 +3066,10 @@  void
 initialize_low_arch (void)
 {
   init_registers_aarch64 ();
+  init_registers_aarch64_pauth ();
 
   initialize_low_arch_aarch32 ();
 
   initialize_regsets_info (&aarch64_regsets_info);
+  initialize_regsets_info (&aarch64_pauth_regsets_info);
 }