[PATCH 16/23] AArch64: Report tag violation error information
Luis Machado
luis.machado@linaro.org
Wed Jul 15 19:45:06 GMT 2020
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
no 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 | 58 ++++++++++++++++++++++++++++++++++++
gdb/arch/aarch64-mte-linux.h | 6 ++++
2 files changed, 64 insertions(+)
diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index 5cb66fbb14..e89e3a5467 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -1626,6 +1626,61 @@ 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;
+
+ 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"));
+
+ /* 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");
+
+ CORE_ADDR atag;
+ 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);
+ }
+ }
+ else
+ {
+ uiout->text ("\n");
+ uiout->text (_("Fault address unavailable"));
+ }
+}
+
static void
aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
@@ -1706,6 +1761,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. */
diff --git a/gdb/arch/aarch64-mte-linux.h b/gdb/arch/aarch64-mte-linux.h
index 5c5783f28b..a5a980ed49 100644
--- a/gdb/arch/aarch64-mte-linux.h
+++ b/gdb/arch/aarch64-mte-linux.h
@@ -35,6 +35,12 @@
#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 size_t get_tag_granules (CORE_ADDR addr, size_t len,
--
2.17.1
More information about the Gdb-patches
mailing list