diff options
Diffstat (limited to 'runtime/stack-ppc64.c')
-rw-r--r-- | runtime/stack-ppc64.c | 62 |
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 *)®_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); +} |