aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog9
-rw-r--r--gdb/aarch64-linux-tdep.c70
-rw-r--r--gdb/arch/aarch64-mte-linux.h6
3 files changed, 85 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ce3373b..52e0dde 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,14 @@
2021-03-24 Luis Machado <luis.machado@linaro.org>
+ * aarch64-linux-tdep.c
+ (aarch64_linux_report_signal_info): New function.
+ (aarch64_linux_init_abi): Register
+ aarch64_linux_report_signal_info as the report_signal_info hook.
+ * arch/aarch64-linux.h (SEGV_MTEAERR): Define.
+ (SEGV_MTESERR): Define.
+
+2021-03-24 Luis Machado <luis.machado@linaro.org>
+
* aarch64-linux-tdep.c: Include gdbsupport/selftest.h.
(aarch64_linux_ltag_tests): New function.
(_initialize_aarch64_linux_tdep): Register aarch64_linux_ltag_tests.
diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index e71f062..15bbdb2 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -1685,6 +1685,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 +1832,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. */
diff --git a/gdb/arch/aarch64-mte-linux.h b/gdb/arch/aarch64-mte-linux.h
index f517638..2aa97eb 100644
--- a/gdb/arch/aarch64-mte-linux.h
+++ b/gdb/arch/aarch64-mte-linux.h
@@ -35,6 +35,12 @@
#define AARCH64_MTE_LOGICAL_TAG_START_BIT 56
#define AARCH64_MTE_LOGICAL_MAX_VALUE 0xf
+/* Memory tagging definitions. */
+#ifndef SEGV_MTEAERR
+# define SEGV_MTEAERR 8
+# define SEGV_MTESERR 9
+#endif
+
/* Memory tag types for AArch64. */
enum class aarch64_memtag_type
{