+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,
#include "record-full.h"
#include "linux-record.h"
+#include "value.h"
+
/* Signal frame handling.
+------------+ ^
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)
{
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 ();
#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 */