gdb/python: print name of unwinder that claimed frame in debug message
[deliverable/binutils-gdb.git] / gdb / aarch64-linux-tdep.c
index e71f062e25d58ee810945c46448e0619d75f91e9..9602fc4b29a9e11c9b5a7f6f325fc011cd87de13 100644 (file)
@@ -728,6 +728,26 @@ aarch64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
          AARCH64_LINUX_SIZEOF_PAUTH, &aarch64_linux_pauth_regset,
          "pauth registers", cb_data);
     }
+
+  /* Handle MTE registers.  */
+  if (tdep->has_mte ())
+    {
+      /* Create this on the fly in order to handle the variable location.  */
+      const struct regcache_map_entry mte_regmap[] =
+       {
+         { 1, tdep->mte_reg_base, 4},
+         { 0 }
+       };
+
+      const struct regset aarch64_linux_mte_regset =
+       {
+         mte_regmap, regcache_supply_regset, regcache_collect_regset
+       };
+
+      cb (".reg-aarch-mte", AARCH64_LINUX_SIZEOF_MTE_REGSET,
+         AARCH64_LINUX_SIZEOF_MTE_REGSET, &aarch64_linux_mte_regset,
+         "MTE registers", cb_data);
+    }
 }
 
 /* Implement the "core_read_description" gdbarch method.  */
@@ -1685,6 +1705,73 @@ aarch64_linux_memtag_to_string (struct gdbarch *gdbarch, struct value *tag_value
   return string_printf ("0x%s", phex_nz (tag, sizeof (tag)));
 }
 
+/* AArch64 Linux implementation of the report_signal_info gdbarch
+   hook.  Displays information about possible memory tag violations.  */
+
+static void
+aarch64_linux_report_signal_info (struct gdbarch *gdbarch,
+                                 struct ui_out *uiout,
+                                 enum gdb_signal siggnal)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (!tdep->has_mte () || siggnal != GDB_SIGNAL_SEGV)
+    return;
+
+  CORE_ADDR fault_addr = 0;
+  long si_code = 0;
+
+  try
+    {
+      /* Sigcode tells us if the segfault is actually a memory tag
+        violation.  */
+      si_code = parse_and_eval_long ("$_siginfo.si_code");
+
+      fault_addr
+       = parse_and_eval_long ("$_siginfo._sifields._sigfault.si_addr");
+    }
+  catch (const gdb_exception_error &exception)
+    {
+      exception_print (gdb_stderr, exception);
+      return;
+    }
+
+  /* If this is not a memory tag violation, just return.  */
+  if (si_code != SEGV_MTEAERR && si_code != SEGV_MTESERR)
+    return;
+
+  uiout->text ("\n");
+
+  uiout->field_string ("sigcode-meaning", _("Memory tag violation"));
+
+  /* For synchronous faults, show additional information.  */
+  if (si_code == SEGV_MTESERR)
+    {
+      uiout->text (_(" while accessing address "));
+      uiout->field_core_addr ("fault-addr", gdbarch, fault_addr);
+      uiout->text ("\n");
+
+      gdb::optional<CORE_ADDR> atag = aarch64_mte_get_atag (fault_addr);
+      gdb_byte ltag = aarch64_mte_get_ltag (fault_addr);
+
+      if (!atag.has_value ())
+       uiout->text (_("Allocation tag unavailable"));
+      else
+       {
+         uiout->text (_("Allocation tag "));
+         uiout->field_string ("allocation-tag", hex_string (*atag));
+         uiout->text ("\n");
+         uiout->text (_("Logical tag "));
+         uiout->field_string ("logical-tag", hex_string (ltag));
+       }
+    }
+  else
+    {
+      uiout->text ("\n");
+      uiout->text (_("Fault address unavailable"));
+    }
+}
+
 static void
 aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -1765,6 +1852,9 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
       /* Register a hook for converting a memory tag to a string.  */
       set_gdbarch_memtag_to_string (gdbarch, aarch64_linux_memtag_to_string);
+
+      set_gdbarch_report_signal_info (gdbarch,
+                                     aarch64_linux_report_signal_info);
     }
 
   /* Initialize the aarch64_linux_record_tdep.  */
This page took 0.026887 seconds and 4 git commands to generate.