]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[Morello] Add capability fault codes and report fault information
authorLuis Machado <luis.machado@arm.com>
Thu, 3 Sep 2020 17:20:46 +0000 (14:20 -0300)
committerLuis Machado <luis.machado@linaro.org>
Tue, 20 Oct 2020 18:05:43 +0000 (15:05 -0300)
Report capability faults with additional information, like tag, bounds,
sealed permissions and access faults.

gdb/ChangeLog

2020-10-20  Luis Machado  <luis.machado@arm.com>

* aarch64-linux-tdep.c: Include value.h.
(aarch64_linux_report_signal_info): New function.
(aarch64_linux_init_abi): Register hook for reporting signal
information.
* arch/aarch64-cap-linux.h (SEGV_CAPTAGERR, SEGV_CAPSEALEDERR)
(SEGV_CAPBOUNDSERR, SEGV_CAPPERMERR, SEGV_CAPSTORETAGERR): New
constants.

gdb/ChangeLog
gdb/aarch64-linux-tdep.c
gdb/arch/aarch64-cap-linux.h

index 1a40953f3ac81581fd92d5116dd7cfb82aa88d0d..59b06a9c81d31f94261a07cfffc455e3821ada09 100644 (file)
@@ -1,3 +1,13 @@
+2020-10-20  Luis Machado  <luis.machado@arm.com>
+
+       * aarch64-linux-tdep.c: Include value.h.
+       (aarch64_linux_report_signal_info): New function.
+       (aarch64_linux_init_abi): Register hook for reporting signal
+       information.
+       * arch/aarch64-cap-linux.h (SEGV_CAPTAGERR, SEGV_CAPSEALEDERR)
+       (SEGV_CAPBOUNDSERR, SEGV_CAPPERMERR, SEGV_CAPSTORETAGERR): New
+       constants.
+
 2020-10-20  Luis Machado  <luis.machado@arm.com>
 
        * aarch64-tdep.c (set_aarch64_cmdlist, show_aarch64_cmdlist,
index 46a0a25f953a64a38d339bd0df637a5fac198521..7492437e97ebfe680052547a743c789824bbfc2e 100644 (file)
@@ -45,6 +45,8 @@
 #include "record-full.h"
 #include "linux-record.h"
 
+#include "value.h"
+
 /* Signal frame handling.
 
       +------------+  ^
@@ -1436,6 +1438,78 @@ aarch64_linux_gcc_target_options (struct gdbarch *gdbarch)
   return {};
 }
 
+/* AArch64 Linux implementation of the report_signal_info gdbarch
+   hook.  Displays information about possible memory tag violations or
+   capability 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_capability () || siggnal != GDB_SIGNAL_SEGV)
+    return;
+
+  CORE_ADDR fault_addr = 0;
+  long si_code = 0;
+
+  try
+    {
+      /* Sigcode tells us if the segfault is actually a capability
+        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 capability violation, just return.  */
+  if (si_code != SEGV_CAPTAGERR && si_code != SEGV_CAPSEALEDERR
+      && si_code != SEGV_CAPBOUNDSERR && si_code != SEGV_CAPPERMERR
+      && si_code != SEGV_CAPSTORETAGERR)
+    return;
+
+  uiout->text ("\n");
+
+  std::string str_si_code;
+
+  switch (si_code)
+    {
+      case SEGV_CAPTAGERR:
+       str_si_code = "tag";
+       break;
+      case SEGV_CAPSEALEDERR:
+       str_si_code = "sealed";
+       break;
+      case SEGV_CAPBOUNDSERR:
+       str_si_code = "bounds";
+       break;
+      case SEGV_CAPPERMERR:
+       str_si_code = "permission";
+       break;
+      case SEGV_CAPSTORETAGERR:
+       str_si_code = "access";
+       break;
+      default:
+       str_si_code = "unknown";
+       break;
+    }
+
+  std::string str_meaning = "Capability " + str_si_code + " fault";
+  uiout->field_string ("sigcode-meaning", str_meaning);
+
+  /* FIXME-Morello: Show more information about the faults.  */
+  uiout->text (_(" while accessing address "));
+  uiout->field_core_addr ("fault-addr", gdbarch, fault_addr);
+  uiout->text ("\n");
+}
+
 static void
 aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -1667,6 +1741,12 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
                                            aarch64_displaced_step_hw_singlestep);
 
   set_gdbarch_gcc_target_options (gdbarch, aarch64_linux_gcc_target_options);
+
+  if (tdep->has_capability ())
+    {
+      set_gdbarch_report_signal_info (gdbarch,
+                                     aarch64_linux_report_signal_info);
+    }
 }
 
 void _initialize_aarch64_linux_tdep ();
index 7fd0ec9aaf9658420f6ae40e0f2950f6afe843f5..aff7f87c5e21c261bff3f241047202437d5a5a05 100644 (file)
 #define AARCH64_MORELLO_REGS_NUM 41
 #define AARCH64_C_REGS_NUM 31
 
+/* Capability fault si_code numbers.  */
+#define SEGV_CAPTAGERR       10  /* Capability tag fault */
+#define SEGV_CAPSEALEDERR     11  /* Capability sealed fault */
+#define SEGV_CAPBOUNDSERR     12  /* Capability bounds fault */
+#define SEGV_CAPPERMERR              13  /* Capability permission fault */
+#define SEGV_CAPSTORETAGERR   14  /* Capability tag store fault */
+
 #endif /*ARCH_AARCH64_LINUX_H */