diff options
author | dwilder <dwilder> | 2006-10-19 18:37:15 +0000 |
---|---|---|
committer | dwilder <dwilder> | 2006-10-19 18:37:15 +0000 |
commit | 24cb8c3b07c5fed086555b54f9f753bb78df6837 (patch) | |
tree | 9cdfcd666b46b16944ad23f41686cf7bfebfaafb /runtime/stack-s390.c | |
parent | 0b951e7c1aa8653655d63bda882d392f0c2216c8 (diff) | |
download | systemtap-steved-24cb8c3b07c5fed086555b54f9f753bb78df6837.tar.gz systemtap-steved-24cb8c3b07c5fed086555b54f9f753bb78df6837.tar.xz systemtap-steved-24cb8c3b07c5fed086555b54f9f753bb78df6837.zip |
Adding s390x support
Diffstat (limited to 'runtime/stack-s390.c')
-rw-r--r-- | runtime/stack-s390.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/runtime/stack-s390.c b/runtime/stack-s390.c new file mode 100644 index 00000000..c65de741 --- /dev/null +++ b/runtime/stack-s390.c @@ -0,0 +1,82 @@ +/* -*- 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 unsigned long +__stp_show_stack (String str, unsigned long sp, unsigned long low, + unsigned long high, int verbose) +{ + + struct stack_frame *sf; + struct pt_regs *regs; + unsigned long ip; + + while (1) { + sp = sp & PSW_ADDR_INSN; + /* fixme: verify this is a kernel stack */ + if (sp < low || sp > high - sizeof(*sf)) + return sp; + sf = (struct stack_frame *) sp; + ip = sf->gprs[8] & PSW_ADDR_INSN; + if (verbose) { + _stp_sprintf(str, "[%016lx] [%016lx] ", sp, ip); + _stp_symbol_sprint(str, ip); + _stp_string_cat(str, "\n"); + }else{ + _stp_sprintf(str,"%lx ", ip); + } + /* Follow the back_chain */ + while (1) { + low = sp; + sp = sf->back_chain & PSW_ADDR_INSN; + if (!sp) + break; + if (sp <= low || sp > high - sizeof(*sf)) + return sp; + sf = (struct stack_frame *) sp; + ip = sf->gprs[8] & PSW_ADDR_INSN; + if (verbose) { + _stp_sprintf(str, "[%016lx] [%016lx] ", sp, ip); + _stp_symbol_sprint(str, ip); + _stp_string_cat(str, "\n"); + }else{ + _stp_sprintf(str,"%lx ", ip); + } + } + /* Zero backchain detected, check for interrupt frame. */ + sp = (unsigned long) (sf + 1); + if (sp <= low || sp > high - sizeof(*regs)) + return sp; + regs = (struct pt_regs *) sp; + if (verbose) { + _stp_sprintf(str, "[%016lx] [%016lx] ", sp, ip); + _stp_symbol_sprint(str, ip); + _stp_string_cat(str, "\n"); + }else{ + _stp_sprintf(str,"%lx ", ip); + } + low = sp; + sp = regs->gprs[15]; + } +} + +static void __stp_stack_sprint (String str, struct pt_regs *regs, + int verbose, int levels) +{ + unsigned long *_sp = (unsigned long *)®_SP(regs); + unsigned long sp = (unsigned long)_sp; + // unsigned long sp = (unsigned long)*_sp; + + sp = __stp_show_stack(str, sp, + S390_lowcore.async_stack - ASYNC_SIZE, + S390_lowcore.async_stack,verbose); + + __stp_show_stack(str, sp, + S390_lowcore.thread_info, + S390_lowcore.thread_info + THREAD_SIZE,verbose); +} |