From e7295ce37994854d419e8d06eb9a5d95ae7282c7 Mon Sep 17 00:00:00 2001 From: Luis Machado Date: Thu, 3 Sep 2020 14:20:46 -0300 Subject: [PATCH] [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. --- gdb/aarch64-linux-tdep.c | 113 +++++++++++++++++++++++++---------- gdb/arch/aarch64-cap-linux.h | 7 +++ 2 files changed, 89 insertions(+), 31 deletions(-) diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c index 10f0bf72916..29e5051dd63 100644 --- a/gdb/aarch64-linux-tdep.c +++ b/gdb/aarch64-linux-tdep.c @@ -1741,7 +1741,8 @@ aarch64_linux_memtag_to_string (struct gdbarch *gdbarch, struct value *tag_value } /* AArch64 Linux implementation of the report_signal_info gdbarch - hook. Displays information about possible memory tag violations. */ + hook. Displays information about possible memory tag violations or + capability violations. */ static void aarch64_linux_report_signal_info (struct gdbarch *gdbarch, @@ -1750,7 +1751,8 @@ aarch64_linux_report_signal_info (struct gdbarch *gdbarch, { aarch64_gdbarch_tdep *tdep = (aarch64_gdbarch_tdep *) gdbarch_tdep (gdbarch); - if (!tdep->has_mte () || siggnal != GDB_SIGNAL_SEGV) + if ((!tdep->has_mte () && !!tdep->has_capability ()) + || siggnal != GDB_SIGNAL_SEGV) return; CORE_ADDR fault_addr = 0; @@ -1758,8 +1760,8 @@ aarch64_linux_report_signal_info (struct gdbarch *gdbarch, try { - /* Sigcode tells us if the segfault is actually a memory tag - violation. */ + /* Sigcode tells us if the segfault is actually a memory tag or + capability violation. */ si_code = parse_and_eval_long ("$_siginfo.si_code"); fault_addr @@ -1771,40 +1773,83 @@ aarch64_linux_report_signal_info (struct gdbarch *gdbarch, return; } - /* If this is not a memory tag violation, just return. */ - if (si_code != SEGV_MTEAERR && si_code != SEGV_MTESERR) + /* If this is not a memory tag or capability violation, just return. */ + if (si_code != SEGV_MTEAERR && si_code != SEGV_MTESERR + && si_code != SEGV_CAPTAGERR && si_code != SEGV_CAPSEALEDERR + && si_code != SEGV_CAPBOUNDSERR && si_code != SEGV_CAPPERMERR + && si_code != SEGV_CAPSTORETAGERR) return; uiout->text ("\n"); - uiout->field_string ("sigcode-meaning", _("Memory tag violation")); - - /* For synchronous faults, show additional information. */ - if (si_code == SEGV_MTESERR) + switch (si_code) { - uiout->text (_(" while accessing address ")); - uiout->field_core_addr ("fault-addr", gdbarch, fault_addr); - uiout->text ("\n"); + case SEGV_MTEAERR: + case SEGV_MTESERR: + uiout->field_string ("sigcode-meaning", _("Memory tag violation")); - gdb::optional atag - = aarch64_mte_get_atag (address_significant (gdbarch, fault_addr)); - gdb_byte ltag = aarch64_mte_get_ltag (fault_addr); + /* 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"); - 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")); + gdb::optional atag + = aarch64_mte_get_atag (address_significant (gdbarch, 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")); + } + break; + case SEGV_CAPTAGERR: + case SEGV_CAPSEALEDERR: + case SEGV_CAPBOUNDSERR: + case SEGV_CAPPERMERR: + case SEGV_CAPSTORETAGERR: + 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; + } + + 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"); + break; } } @@ -2234,6 +2279,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); + } } #if GDB_SELF_TEST diff --git a/gdb/arch/aarch64-cap-linux.h b/gdb/arch/aarch64-cap-linux.h index f62bc7f2f8d..519c9b25cd6 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_CAP_LINUX_H */ -- 2.47.2