summaryrefslogtreecommitdiff
path: root/gdb/sparc64-linux-tdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/sparc64-linux-tdep.c')
-rw-r--r--gdb/sparc64-linux-tdep.c69
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);
}