diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2009-02-11 13:07:53 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-02-12 13:21:17 +0000 |
commit | 2d7c11bfc91637e5f9bc5f8c9a82aaffcc0e97aa (patch) | |
tree | 0bb67dae38b1185089b6c9813769689cb79c5ee3 /arch/arm/kernel/process.c | |
parent | 67a94c23bb7338c321ae71aa33f8d398c94e1d0c (diff) |
[ARM] 5382/1: unwind: Reorganise the stacktrace support
This patch changes the walk_stacktrace and its callers for easier
integration of stack unwinding. The arch/arm/kernel/stacktrace.h file is
also moved to arch/arm/include/asm/stacktrace.h.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/process.c')
-rw-r--r-- | arch/arm/kernel/process.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index d3ea6fa8952..af377c73d90 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -34,6 +34,7 @@ #include <asm/processor.h> #include <asm/system.h> #include <asm/thread_notify.h> +#include <asm/stacktrace.h> #include <asm/mach/time.h> static const char *processor_modes[] = { @@ -372,23 +373,21 @@ EXPORT_SYMBOL(kernel_thread); unsigned long get_wchan(struct task_struct *p) { - unsigned long fp, lr; - unsigned long stack_start, stack_end; + struct stackframe frame; int count = 0; if (!p || p == current || p->state == TASK_RUNNING) return 0; - stack_start = (unsigned long)end_of_stack(p); - stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE; - - fp = thread_saved_fp(p); + frame.fp = thread_saved_fp(p); + frame.sp = thread_saved_sp(p); + frame.lr = 0; /* recovered from the stack */ + frame.pc = thread_saved_pc(p); do { - if (fp < stack_start || fp > stack_end) + int ret = unwind_frame(&frame); + if (ret < 0) return 0; - lr = ((unsigned long *)fp)[-1]; - if (!in_sched_functions(lr)) - return lr; - fp = *(unsigned long *) (fp - 12); + if (!in_sched_functions(frame.pc)) + return frame.pc; } while (count ++ < 16); return 0; } |