summaryrefslogtreecommitdiffstats
path: root/runtime/stack-ppc64.c
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/stack-ppc64.c')
-rw-r--r--runtime/stack-ppc64.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/runtime/stack-ppc64.c b/runtime/stack-ppc64.c
new file mode 100644
index 00000000..0a30bc84
--- /dev/null
+++ b/runtime/stack-ppc64.c
@@ -0,0 +1,62 @@
+/* -*- linux-c -*-
+ * ppc64 stack tracing functions
+ *
+ * This file is part of systemtap, and is free software. You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
+static void __stp_stack_sprint (String str, struct pt_regs *regs, int verbose, int levels)
+{
+ unsigned long ip, newsp, lr = 0;
+ int count = 0;
+ unsigned long sp = (unsigned long)_sp;
+ int firstframe = 1;
+ unsigned long *_sp = (unsigned long *)&REG_SP(regs);
+ lr = 0;
+ do {
+ if (sp < KERNELBASE)
+ return;
+ _sp = (unsigned long *) sp;
+ newsp = _sp[0];
+ ip = _sp[2];
+ if (!firstframe || ip != lr) {
+ if (verbose) {
+ _stp_sprintf(str, "[%016lx] [%016lx] ", sp, ip);
+ _stp_symbol_sprint(str, ip);
+ if (firstframe)
+ _stp_string_cat(str, " (unreliable)");
+ _stp_string_cat(str, "\n");
+ }
+ else
+ _stp_sprintf(str,"%lx ", ip);
+ }
+ firstframe = 0;
+ /*
+ * See if this is an exception frame.
+ * We look for the "regshere" marker in the current frame.
+ */
+ if ( _sp[12] == 0x7265677368657265ul) {
+ struct pt_regs *regs = (struct pt_regs *)
+ (sp + STACK_FRAME_OVERHEAD);
+ if (verbose) {
+ _stp_sprintf(str, "--- Exception: %lx at ",
+ regs->trap);
+ _stp_symbol_sprint(str, regs->nip);
+ _stp_string_cat(str, "\n");
+ lr = regs->link;
+ _stp_string_cat(str, " LR =");
+ _stp_symbol_sprint(str, lr);
+ _stp_string_cat(str, "\n");
+ firstframe = 1;
+ }
+ else {
+ _stp_sprintf(str, "%lx ",regs->nip);
+ _stp_sprintf(str, "%lx ",regs->link);
+ }
+ }
+
+ sp = newsp;
+ } while (str->len < STP_STRING_SIZE);
+}