From: Luis Machado Date: Thu, 3 Sep 2020 17:20:46 +0000 (-0300) Subject: [Morello] Add capability fault codes and report fault information X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c8c305cdab5a8eea3f37d0101591b87f25d38b07;p=thirdparty%2Fbinutils-gdb.git [Morello] Add capability fault codes and report fault information Report capability faults with additional information, like tag, bounds, sealed permissions and access faults. gdb/ChangeLog 2020-10-20 Luis Machado * 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. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 1a40953f3ac..59b06a9c81d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,13 @@ +2020-10-20 Luis Machado + + * 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 * aarch64-tdep.c (set_aarch64_cmdlist, show_aarch64_cmdlist, diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c index 46a0a25f953..7492437e97e 100644 --- a/gdb/aarch64-linux-tdep.c +++ b/gdb/aarch64-linux-tdep.c @@ -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 (); diff --git a/gdb/arch/aarch64-cap-linux.h b/gdb/arch/aarch64-cap-linux.h index 7fd0ec9aaf9..aff7f87c5e2 100644 --- a/gdb/arch/aarch64-cap-linux.h +++ b/gdb/arch/aarch64-cap-linux.h @@ -30,4 +30,11 @@ #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 */