diff options
Diffstat (limited to 'gdb/sparc64-linux-tdep.c')
-rw-r--r-- | gdb/sparc64-linux-tdep.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/gdb/sparc64-linux-tdep.c b/gdb/sparc64-linux-tdep.c index 814bc29ce29..2da978fbf80 100644 --- a/gdb/sparc64-linux-tdep.c +++ b/gdb/sparc64-linux-tdep.c @@ -33,6 +33,17 @@ #include "xml-syscall.h" #include "linux-tdep.h" +/* ADI specific si_code */ +#ifndef SEGV_ACCADI +#define SEGV_ACCADI 3 +#endif +#ifndef SEGV_ADIDERR +#define SEGV_ADIDERR 4 +#endif +#ifndef SEGV_ADIPERR +#define SEGV_ADIPERR 5 +#endif + /* The syscall's XML filename for sparc 64-bit. */ #define XML_SYSCALL_FILENAME_SPARC64 "syscalls/sparc64-linux.xml" @@ -104,6 +115,62 @@ sparc64_linux_sigframe_init (const struct tramp_frame *self, } trad_frame_set_id (this_cache, frame_id_build (base, func)); } + +/* sparc64 GNU/Linux implementation of the handle_segmentation_fault + gdbarch hook. + Displays information related to ADI memory corruptions. */ + +void +sparc64_linux_handle_segmentation_fault (struct gdbarch *gdbarch, + struct ui_out *uiout) +{ + if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word != 64) + return; + + CORE_ADDR addr = 0; + long si_code = 0; + + TRY + { + /* Evaluate si_code to see if the segfault is ADI related. */ + si_code = parse_and_eval_long ("$_siginfo.si_code\n"); + + if (si_code >= SEGV_ACCADI && si_code <= SEGV_ADIPERR) + addr = parse_and_eval_long ("$_siginfo._sifields._sigfault.si_addr"); + } + CATCH (exception, RETURN_MASK_ALL) + { + return; + } + END_CATCH + + /* Print out ADI event based on sig_code value */ + switch (si_code) + { + case SEGV_ACCADI: /* adi not enabled */ + uiout->text ("\n"); + uiout->field_string ("sigcode-meaning", _("ADI disabled")); + uiout->text (_(" while accessing address ")); + uiout->field_fmt ("bound-access", "%s", paddress (gdbarch, addr)); + break; + case SEGV_ADIDERR: /* disrupting mismatch */ + uiout->text ("\n"); + uiout->field_string ("sigcode-meaning", _("ADI deferred mismatch")); + uiout->text (_(" while accessing address ")); + uiout->field_fmt ("bound-access", "%s", paddress (gdbarch, addr)); + break; + case SEGV_ADIPERR: /* precise mismatch */ + uiout->text ("\n"); + uiout->field_string ("sigcode-meaning", _("ADI precise mismatch")); + uiout->text (_(" while accessing address ")); + uiout->field_fmt ("bound-access", "%s", paddress (gdbarch, addr)); + break; + default: + break; + } + +} + /* Return the address of a system call's alternative return address. */ @@ -338,6 +405,8 @@ sparc64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_xml_syscall_file_name (gdbarch, XML_SYSCALL_FILENAME_SPARC64); set_gdbarch_get_syscall_number (gdbarch, sparc64_linux_get_syscall_number); + set_gdbarch_handle_segmentation_fault (gdbarch, + sparc64_linux_handle_segmentation_fault); } |