]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
AArch64: Report tag violation error information
authorLuis Machado <luis.machado@linaro.org>
Mon, 15 Jun 2020 18:44:20 +0000 (15:44 -0300)
committerLuis Machado <luis.machado@linaro.org>
Thu, 25 Jun 2020 16:23:38 +0000 (13:23 -0300)
Whenever a memory tag violation occurs, we get a SIGSEGV. Additional
information can be obtained through the siginfo data structure.

For AArch64 the Linux kernel may expose the fault address and tag
information, if we have a synchronous event. Otherwise there is
not fault address available.

gdb/ChangeLog:

YYYY-MM-DD  Luis Machado  <luis.machado@linaro.org>

* aarch64-linux-tdep.c
(aarch64_linux_handle_segmentation_fault): New function.
(aarch64_linux_init_abi): Register
aarch64_linux_handle_segmentation_fault as segmentation fault hook.
* arch/aarch64-linux.h (SEGV_MTEAERR): Define.
(SEGV_MTESERR): Define.

gdb/aarch64-linux-tdep.c
gdb/arch/aarch64-mte-linux.h

index 892977da55ae60e84787d80ea453ab90ce9f1959..c8fccdd09914ba62c6503ec284a12f4bb97a0ad9 100644 (file)
@@ -1644,6 +1644,57 @@ aarch64_linux_memtag_to_string (struct gdbarch *gdbarch,
   return string_printf ("0x%s", phex_nz (tag, sizeof (tag)));
 }
 
+/* AArch64 Linux implementation of the handle_segmentation_fault gdbarch
+   hook.  Displays information about possible memory tag violations.  */
+
+static void
+aarch64_linux_handle_segmentation_fault (struct gdbarch *gdbarch,
+                                        struct ui_out *uiout)
+{
+  CORE_ADDR fault_addr = 0;
+  long si_code = 0;
+  CORE_ADDR ltag;
+  CORE_ADDR atag;
+
+  try
+    {
+      /* Sigcode tells us if the segfault is actually a memory tag
+        violation.  */
+      si_code = parse_and_eval_long ("$_siginfo.si_code\n");
+
+      fault_addr
+       = parse_and_eval_long ("$_siginfo._sifields._sigfault.si_addr");
+    }
+  catch (const gdb_exception &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"));
+  uiout->text (_(" while accessing address "));
+  uiout->field_core_addr ("fault-addr", gdbarch, fault_addr);
+  uiout->text ("\n");
+
+  uiout->text (_("Logical tag "));
+  ltag = aarch64_linux_get_ltag (fault_addr);
+  uiout->field_core_addr ("logical-tag", gdbarch, ltag);
+  uiout->text ("\n");
+
+  if (aarch64_linux_get_atag (fault_addr, &atag) != 0)
+    uiout->text (_("Allocation tag unavailable"));
+  else
+    {
+      uiout->text (_("Allocation tag "));
+      uiout->field_core_addr ("allocation-tag", gdbarch, atag);
+    }
+}
+
 static void
 aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -1724,6 +1775,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_handle_segmentation_fault (gdbarch,
+                                     aarch64_linux_handle_segmentation_fault);
     }
 
   /* Initialize the aarch64_linux_record_tdep.  */
index 4ee6de34308c9aa364cbe71d6eb3d9048149c76b..79c662c0131786c76ec8e2f578edde5657d507ce 100644 (file)
 #define MTE_LOGICAL_TAG_START_BIT   56
 #define MTE_LOGICAL_MAX_VALUE      0xf
 
+/* Memory tagging definitions.  */
+#ifndef SEGV_MTEAERR
+# define SEGV_MTEAERR 8
+# define SEGV_MTESERR 9
+#endif
+
 /* Return the number of tag granules in the memory range
    [ADDR, ADDR + LEN) given GRANULE_SIZE.  */
 extern int get_tag_granules (CORE_ADDR addr, size_t len,