diff options
author | Dmitry Torokhov <dtor@insightbb.com> | 2007-02-10 01:26:32 -0500 |
---|---|---|
committer | Dmitry Torokhov <dtor@insightbb.com> | 2007-02-10 01:26:32 -0500 |
commit | b22364c8eec89e6b0c081a237f3b6348df87796f (patch) | |
tree | 233a923281fb640106465d076997ff511efb6edf /arch/sparc64/kernel/stacktrace.c | |
parent | 2c8dc071517ec2843869024dc82be2e246f41064 (diff) | |
parent | 66efc5a7e3061c3597ac43a8bb1026488d57e66b (diff) |
Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'arch/sparc64/kernel/stacktrace.c')
-rw-r--r-- | arch/sparc64/kernel/stacktrace.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/stacktrace.c b/arch/sparc64/kernel/stacktrace.c new file mode 100644 index 00000000000..c4d15f2762b --- /dev/null +++ b/arch/sparc64/kernel/stacktrace.c @@ -0,0 +1,41 @@ +#include <linux/sched.h> +#include <linux/stacktrace.h> +#include <linux/thread_info.h> +#include <asm/ptrace.h> + +void save_stack_trace(struct stack_trace *trace, struct task_struct *task) +{ + unsigned long ksp, fp, thread_base; + struct thread_info *tp; + + if (!task) + task = current; + tp = task_thread_info(task); + if (task == current) { + flushw_all(); + __asm__ __volatile__( + "mov %%fp, %0" + : "=r" (ksp) + ); + } else + ksp = tp->ksp; + + fp = ksp + STACK_BIAS; + thread_base = (unsigned long) tp; + do { + struct reg_window *rw; + + /* Bogus frame pointer? */ + if (fp < (thread_base + sizeof(struct thread_info)) || + fp >= (thread_base + THREAD_SIZE)) + break; + + rw = (struct reg_window *) fp; + if (trace->skip > 0) + trace->skip--; + else + trace->entries[trace->nr_entries++] = rw->ins[7]; + + fp = rw->ins[6] + STACK_BIAS; + } while (trace->nr_entries < trace->max_entries); +} |