summaryrefslogtreecommitdiffstats
path: root/runtime/stack-ppc.c
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/stack-ppc.c')
-rw-r--r--runtime/stack-ppc.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/runtime/stack-ppc.c b/runtime/stack-ppc.c
new file mode 100644
index 00000000..3267194e
--- /dev/null
+++ b/runtime/stack-ppc.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_print (struct pt_regs *regs, int verbose, int levels,
+ struct task_struct *tsk)
+{
+ unsigned long ip, newsp, lr = 0;
+ int count = 0;
+ int firstframe = 1;
+ unsigned long *_sp = (unsigned long *)&REG_SP(regs);
+ unsigned long sp = (unsigned long)_sp;
+ lr = 0;
+ do {
+ if (sp < KERNELBASE)
+ return;
+ _sp = (unsigned long *) sp;
+ newsp = _sp[0];
+ ip = _sp[2];
+ if (!firstframe || ip != lr) {
+ if (verbose) {
+ _stp_printf("[0x%016lx] [0x%016lx] ", sp, ip);
+ _stp_symbol_print(ip);
+ if (firstframe)
+ _stp_print(" (unreliable)");
+ _stp_print_char('\n');
+ }
+ else
+ _stp_printf("0x%016lx ", 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_printf("--- Exception: %lx at ",regs->trap);
+ _stp_symbol_print(regs->nip);
+ _stp_print_char('\n');
+ lr = regs->link;
+ _stp_print(" LR =");
+ _stp_symbol_print(lr);
+ _stp_print_char('\n');
+ firstframe = 1;
+ }
+ else {
+ _stp_printf("0x%016lx ",regs->nip);
+ _stp_printf("0x%016lx ",regs->link);
+ }
+ }
+
+ sp = newsp;
+ } while (count++ < MAXBACKTRACE);
+}