AArch64: Add target description/feature for MTE registers
authorLuis Machado <luis.machado@linaro.org>
Mon, 15 Jun 2020 16:52:27 +0000 (13:52 -0300)
committerLuis Machado <luis.machado@linaro.org>
Wed, 24 Mar 2021 17:52:08 +0000 (14:52 -0300)
This patch adds a target description and feature "mte" for aarch64.

It includes one new register, tag_ctl, that can be used to configure the
tag generation rules and sync/async modes.  It is 64-bit in size.

The patch also adjusts the code that creates the target descriptions at
runtime based on CPU feature checks.

gdb/ChangeLog:

2021-03-24  Luis Machado  <luis.machado@linaro.org>

* aarch64-linux-nat.c
(aarch64_linux_nat_target::read_description): Take MTE flag into
account.
Slight refactor to hwcap flag checking.
* aarch64-linux-tdep.c
(aarch64_linux_core_read_description): Likewise.
* aarch64-tdep.c (tdesc_aarch64_list): Add one more dimension for
MTE.
(aarch64_read_description): Add mte_p parameter and update to use it.
Update the documentation.
(aarch64_gdbarch_init): Update call to aarch64_read_description.
* aarch64-tdep.h (aarch64_read_description): Add mte_p parameter.
* arch/aarch64.c: Include ../features/aarch64-mte.c.
(aarch64_create_target_description): Add mte_p parameter and update
the code to use it.
* arch/aarch64.h (aarch64_create_target_description): Add mte_p
parameter.
* features/Makefile (FEATURE_XMLFILES): Add aarch64-mte.xml.
* features/aarch64-mte.c: New file, generated.
* features/aarch64-mte.xml: New file.

gdbserver/ChangeLog:

2021-03-24  Luis Machado  <luis.machado@linaro.org>

* linux-aarch64-ipa.cc (get_ipa_tdesc): Update call to
aarch64_linux_read_description.
(initialize_low_tracepoint): Likewise.
* linux-aarch64-low.cc (aarch64_target::low_arch_setup): Take MTE flag
into account.
* linux-aarch64-tdesc.cc (tdesc_aarch64_list): Add one more dimension
for MTE.
(aarch64_linux_read_description): Add mte_p parameter and update to
use it.
* linux-aarch64-tdesc.h (aarch64_linux_read_description): Add mte_p
parameter.

15 files changed:
gdb/ChangeLog
gdb/aarch64-linux-nat.c
gdb/aarch64-linux-tdep.c
gdb/aarch64-tdep.c
gdb/aarch64-tdep.h
gdb/arch/aarch64.c
gdb/arch/aarch64.h
gdb/features/Makefile
gdb/features/aarch64-mte.c [new file with mode: 0644]
gdb/features/aarch64-mte.xml [new file with mode: 0644]
gdbserver/ChangeLog
gdbserver/linux-aarch64-ipa.cc
gdbserver/linux-aarch64-low.cc
gdbserver/linux-aarch64-tdesc.cc
gdbserver/linux-aarch64-tdesc.h

index a7d89022010e52179b54b5c704478f9cc8664ee5..33a58cb06d9e400805b66579afeddaa0bc2b39ea 100644 (file)
@@ -1,3 +1,26 @@
+2021-03-24  Luis Machado  <luis.machado@linaro.org>
+
+       * aarch64-linux-nat.c
+       (aarch64_linux_nat_target::read_description): Take MTE flag into
+       account.
+       Slight refactor to hwcap flag checking.
+       * aarch64-linux-tdep.c
+       (aarch64_linux_core_read_description): Likewise.
+       * aarch64-tdep.c (tdesc_aarch64_list): Add one more dimension for
+       MTE.
+       (aarch64_read_description): Add mte_p parameter and update to use it.
+       Update the documentation.
+       (aarch64_gdbarch_init): Update call to aarch64_read_description.
+       * aarch64-tdep.h (aarch64_read_description): Add mte_p parameter.
+       * arch/aarch64.c: Include ../features/aarch64-mte.c.
+       (aarch64_create_target_description): Add mte_p parameter and update
+       the code to use it.
+       * arch/aarch64.h (aarch64_create_target_description): Add mte_p
+       parameter.
+       * features/Makefile (FEATURE_XMLFILES): Add aarch64-mte.xml.
+       * features/aarch64-mte.c: New file, generated.
+       * features/aarch64-mte.xml: New file.
+
 2021-03-24  Luis Machado  <luis.machado@linaro.org>
 
        * Makefile.in (HFILES_NO_SRCDIR): Add arch/aarch64-mte-linux.h.
index 424e616b042339823e57ed317ab9b9820ae7efd2..c56880e33d707a3df847628a91fe9994d73b7b2e 100644 (file)
@@ -653,9 +653,12 @@ aarch64_linux_nat_target::read_description ()
     return aarch32_read_description ();
 
   CORE_ADDR hwcap = linux_get_hwcap (this);
+  CORE_ADDR hwcap2 = linux_get_hwcap2 (this);
 
-  return aarch64_read_description (aarch64_sve_get_vq (tid),
-                                  hwcap & AARCH64_HWCAP_PACA);
+  bool pauth_p = hwcap & AARCH64_HWCAP_PACA;
+  bool mte_p = hwcap2 & HWCAP2_MTE;
+
+  return aarch64_read_description (aarch64_sve_get_vq (tid), pauth_p, mte_p);
 }
 
 /* Convert a native/host siginfo object, into/from the siginfo in the
index a6044ead49f32457cbad7c4fd72504fb69edfe8c..1c45770a287169e9ed817ebac604e9d0cdb54bba 100644 (file)
@@ -731,9 +731,12 @@ aarch64_linux_core_read_description (struct gdbarch *gdbarch,
                                     struct target_ops *target, bfd *abfd)
 {
   CORE_ADDR hwcap = linux_get_hwcap (target);
+  CORE_ADDR hwcap2 = linux_get_hwcap2 (target);
 
+  bool pauth_p = hwcap & AARCH64_HWCAP_PACA;
+  bool mte_p = hwcap2 & HWCAP2_MTE;
   return aarch64_read_description (aarch64_linux_core_read_vq (gdbarch, abfd),
-                                  hwcap & AARCH64_HWCAP_PACA);
+                                  pauth_p, mte_p);
 }
 
 /* Implementation of `gdbarch_stap_is_single_operand', as defined in
index 3ac0564dd9a1bf01a7df60059b3a7b353e3b042f..685c50b84dabb27a537d482e3125635789eb8578 100644 (file)
@@ -58,7 +58,7 @@
 #define HA_MAX_NUM_FLDS                4
 
 /* All possible aarch64 target descriptors.  */
-static target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1][2/*pauth*/];
+static target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1][2/*pauth*/][2 /* mte */];
 
 /* The standard register names, and all the valid aliases for them.  */
 static const struct
@@ -3260,21 +3260,23 @@ aarch64_displaced_step_hw_singlestep (struct gdbarch *gdbarch)
 
 /* Get the correct target description for the given VQ value.
    If VQ is zero then it is assumed SVE is not supported.
-   (It is not possible to set VQ to zero on an SVE system).  */
+   (It is not possible to set VQ to zero on an SVE system).
+
+   MTE_P indicates the presence of the Memory Tagging Extension feature. */
 
 const target_desc *
-aarch64_read_description (uint64_t vq, bool pauth_p)
+aarch64_read_description (uint64_t vq, bool pauth_p, bool mte_p)
 {
   if (vq > AARCH64_MAX_SVE_VQ)
     error (_("VQ is %" PRIu64 ", maximum supported value is %d"), vq,
           AARCH64_MAX_SVE_VQ);
 
-  struct target_desc *tdesc = tdesc_aarch64_list[vq][pauth_p];
+  struct target_desc *tdesc = tdesc_aarch64_list[vq][pauth_p][mte_p];
 
   if (tdesc == NULL)
     {
-      tdesc = aarch64_create_target_description (vq, pauth_p);
-      tdesc_aarch64_list[vq][pauth_p] = tdesc;
+      tdesc = aarch64_create_target_description (vq, pauth_p, mte_p);
+      tdesc_aarch64_list[vq][pauth_p][mte_p] = tdesc;
     }
 
   return tdesc;
@@ -3374,7 +3376,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
      value.  */
   const struct target_desc *tdesc = info.target_desc;
   if (!tdesc_has_registers (tdesc) || vq != aarch64_get_tdesc_vq (tdesc))
-    tdesc = aarch64_read_description (vq, false);
+    tdesc = aarch64_read_description (vq, false, false);
   gdb_assert (tdesc);
 
   feature_core = tdesc_find_feature (tdesc,"org.gnu.gdb.aarch64.core");
index 3783f5cd5e12b0f37a237ad72ae891c51a16db0f..f6d24292f845f6c5a134fe3aa3c3ed9a2864087d 100644 (file)
@@ -102,7 +102,8 @@ struct gdbarch_tdep
   }
 };
 
-const target_desc *aarch64_read_description (uint64_t vq, bool pauth_p);
+const target_desc *aarch64_read_description (uint64_t vq, bool pauth_p,
+                                            bool mte_p);
 
 extern int aarch64_process_record (struct gdbarch *gdbarch,
                               struct regcache *regcache, CORE_ADDR addr);
index d243116be463479401b2db428a2345cca14b17a3..c38f8312c9033b2b14de9c725ff4070d77166d1b 100644 (file)
 #include "../features/aarch64-fpu.c"
 #include "../features/aarch64-sve.c"
 #include "../features/aarch64-pauth.c"
+#include "../features/aarch64-mte.c"
 
 /* See arch/aarch64.h.  */
 
 target_desc *
-aarch64_create_target_description (uint64_t vq, bool pauth_p)
+aarch64_create_target_description (uint64_t vq, bool pauth_p, bool mte_p)
 {
   target_desc_up tdesc = allocate_target_description ();
 
@@ -47,5 +48,9 @@ aarch64_create_target_description (uint64_t vq, bool pauth_p)
   if (pauth_p)
     regnum = create_feature_aarch64_pauth (tdesc.get (), regnum);
 
+  /* Memory tagging extension registers.  */
+  if (mte_p)
+    regnum = create_feature_aarch64_mte (tdesc.get (), regnum);
+
   return tdesc.release ();
 }
index 6c98d5fa379f03ec01bbc2ed35219868b99ff3cf..0eb702c5b5eff3ed960871b7d1751840e187a34b 100644 (file)
 /* Create the aarch64 target description.  A non zero VQ value indicates both
    the presence of SVE and the Vector Quotient - the number of 128bit chunks in
    an SVE Z register.  HAS_PAUTH_P indicates the presence of the PAUTH
-   feature.  */
+   feature.
 
-target_desc *aarch64_create_target_description (uint64_t vq, bool has_pauth_p);
+   MTE_P indicates the presence of the Memory Tagging Extension feature.  */
+
+target_desc *aarch64_create_target_description (uint64_t vq, bool has_pauth_p,
+                                               bool mte_p);
 
 /* Register numbers of various important registers.
    Note that on SVE, the Z registers reuse the V register numbers and the V
index 5049b88d3ea7ad07e2689ce9f0b9d6678d55b4fe..522ad58aab0fd93786140f9bb25d496bca2d0d88 100644 (file)
@@ -202,6 +202,7 @@ $(outdir)/%.dat: %.xml number-regs.xsl sort-regs.xsl gdbserver-regs.xsl
 FEATURE_XMLFILES = aarch64-core.xml \
        aarch64-fpu.xml \
        aarch64-pauth.xml \
+       aarch64-mte.xml \
        arc/v1-core.xml \
        arc/v1-aux.xml \
        arc/v2-core.xml \
diff --git a/gdb/features/aarch64-mte.c b/gdb/features/aarch64-mte.c
new file mode 100644 (file)
index 0000000..883b19c
--- /dev/null
@@ -0,0 +1,14 @@
+/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
+  Original: aarch64-mte.xml */
+
+#include "gdbsupport/tdesc.h"
+
+static int
+create_feature_aarch64_mte (struct target_desc *result, long regnum)
+{
+  struct tdesc_feature *feature;
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.aarch64.mte");
+  tdesc_create_reg (feature, "tag_ctl", regnum++, 0, "system", 64, "uint64");
+  return regnum;
+}
diff --git a/gdb/features/aarch64-mte.xml b/gdb/features/aarch64-mte.xml
new file mode 100644 (file)
index 0000000..da6c7bf
--- /dev/null
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2021 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.aarch64.mte">
+  <reg name="tag_ctl" bitsize="64" type="uint64" group="system" save-restore="no"/>
+</feature>
index 51c059caf082f729106d9786fe6d9f366af2b931..db906600b2874fb64ba8966b6d678932d44c16eb 100644 (file)
@@ -1,3 +1,17 @@
+2021-03-24  Luis Machado  <luis.machado@linaro.org>
+
+       * linux-aarch64-ipa.cc (get_ipa_tdesc): Update call to
+       aarch64_linux_read_description.
+       (initialize_low_tracepoint): Likewise.
+       * linux-aarch64-low.cc (aarch64_target::low_arch_setup): Take MTE flag
+       into account.
+       * linux-aarch64-tdesc.cc (tdesc_aarch64_list): Add one more dimension
+       for MTE.
+       (aarch64_linux_read_description): Add mte_p parameter and update to
+       use it.
+       * linux-aarch64-tdesc.h (aarch64_linux_read_description): Add mte_p
+       parameter.
+
 2021-03-24  Luis Machado  <luis.machado@linaro.org>
 
        * linux-aarch64-low.cc: Include arch/aarch64-mte-linux.h.
index 24211df55863d3146685e18d17d5676ca87bad36..ebf017ed1146e596cd91cbca378dba96dbcf469e 100644 (file)
@@ -147,12 +147,12 @@ get_raw_reg (const unsigned char *raw_regs, int regnum)
 
 /* Return target_desc to use for IPA, given the tdesc index passed by
    gdbserver.  Index is ignored, since we have only one tdesc
-   at the moment.  SVE and pauth not yet supported.  */
+   at the moment.  SVE, pauth and MTE not yet supported.  */
 
 const struct target_desc *
 get_ipa_tdesc (int idx)
 {
-  return aarch64_linux_read_description (0, false);
+  return aarch64_linux_read_description (0, false, false);
 }
 
 /* Allocate buffer for the jump pads.  The branch instruction has a reach
@@ -204,6 +204,6 @@ alloc_jump_pad_buffer (size_t size)
 void
 initialize_low_tracepoint (void)
 {
-  /* SVE and pauth not yet supported.  */
-  aarch64_linux_read_description (0, false);
+  /* SVE, pauth and MTE not yet supported.  */
+  aarch64_linux_read_description (0, false, false);
 }
index 7d7da87fdc2708fcba9fe8ae33f3db9331eb0292..14493c1fbe72d47062461cac0eff3e6a86a24e86 100644 (file)
@@ -664,9 +664,13 @@ aarch64_target::low_arch_setup ()
     {
       uint64_t vq = aarch64_sve_get_vq (tid);
       unsigned long hwcap = linux_get_hwcap (8);
+      unsigned long hwcap2 = linux_get_hwcap2 (8);
       bool pauth_p = hwcap & AARCH64_HWCAP_PACA;
+      /* MTE is AArch64-only.  */
+      bool mte_p = hwcap2 & HWCAP2_MTE;
 
-      current_process ()->tdesc = aarch64_linux_read_description (vq, pauth_p);
+      current_process ()->tdesc
+       = aarch64_linux_read_description (vq, pauth_p, mte_p);
     }
   else
     current_process ()->tdesc = aarch32_linux_read_description ();
index a7f728ecda67f8ef60eb177d052375c444dc02d9..ee005b8ea18fd2f59af1a321bae35bf2076793d7 100644 (file)
 #include <inttypes.h>
 
 /* All possible aarch64 target descriptors.  */
-struct target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1][2/*pauth*/];
+struct target_desc *tdesc_aarch64_list[AARCH64_MAX_SVE_VQ + 1][2/*pauth*/][2 /* mte */];
 
 /* Create the aarch64 target description.  */
 
 const target_desc *
-aarch64_linux_read_description (uint64_t vq, bool pauth_p)
+aarch64_linux_read_description (uint64_t vq, bool pauth_p, bool mte_p)
 {
   if (vq > AARCH64_MAX_SVE_VQ)
     error (_("VQ is %" PRIu64 ", maximum supported value is %d"), vq,
           AARCH64_MAX_SVE_VQ);
 
-  struct target_desc *tdesc = tdesc_aarch64_list[vq][pauth_p];
+  struct target_desc *tdesc = tdesc_aarch64_list[vq][pauth_p][mte_p];
 
   if (tdesc == NULL)
     {
-      tdesc = aarch64_create_target_description (vq, pauth_p);
+      tdesc = aarch64_create_target_description (vq, pauth_p, mte_p);
 
       static const char *expedite_regs_aarch64[] = { "x29", "sp", "pc", NULL };
       static const char *expedite_regs_aarch64_sve[] = { "x29", "sp", "pc",
@@ -53,7 +53,7 @@ aarch64_linux_read_description (uint64_t vq, bool pauth_p)
       else
        init_target_desc (tdesc, expedite_regs_aarch64_sve);
 
-      tdesc_aarch64_list[vq][pauth_p] = tdesc;
+      tdesc_aarch64_list[vq][pauth_p][mte_p] = tdesc;
     }
 
   return tdesc;
index 95f115c2de9d09ea900199a34920788fef73150e..8319ca7d68b3d1f70abd257bc10c24e9a760e6c4 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef GDBSERVER_LINUX_AARCH64_TDESC_H
 #define GDBSERVER_LINUX_AARCH64_TDESC_H
 
-const target_desc * aarch64_linux_read_description (uint64_t vq, bool pauth_p);
+const target_desc * aarch64_linux_read_description (uint64_t vq, bool pauth_p,
+                                                   bool mte_p);
 
 #endif /* GDBSERVER_LINUX_AARCH64_TDESC_H */