summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuis Machado <luis.machado@linaro.org>2020-06-15 15:44:20 -0300
committerLuis Machado <luis.machado@linaro.org>2020-06-16 09:58:32 -0300
commita08d973656aceb94187d5d283bff2e042fe234b5 (patch)
tree623ecc9312cd4650475b3765ffc9aeeadf9d46b1
parent9e45a8561d934bc1ae07ff4356312afb69e0bd00 (diff)
downloadbinutils-gdb-a08d973656aceb94187d5d283bff2e042fe234b5.tar.gz
Report TAG violation error information
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.
-rw-r--r--gdb/aarch64-linux-tdep.c54
-rw-r--r--gdb/arch/aarch64-linux.h6
2 files changed, 60 insertions, 0 deletions
diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index 6fee4437f23..66c8fa0ac5a 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -1700,6 +1700,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)
{
@@ -1780,6 +1831,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-linux.h b/gdb/arch/aarch64-linux.h
index 23cd98f1f30..3006b316fd5 100644
--- a/gdb/arch/aarch64-linux.h
+++ b/gdb/arch/aarch64-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 int get_tag_granules (CORE_ADDR addr, size_t len,