MIPS: Add new unwind_stack variant

The unwind_stack_by_address variant supports unwinding based
on any kernel code address.
This symbol is also exported so it can be called from modules.

Signed-off-by: Daniel Kalmar <kalmard@homejinni.com>
Signed-off-by: Gergely Kis <gergely@homejinni.com>
Signed-off-by: Robert Richter <robert.richter@amd.com>
This commit is contained in:
Daniel Kalmar
2011-05-13 08:38:04 -04:00
committed by Robert Richter
parent 2c53b436a3
commit 94ea09c6a8
2 changed files with 18 additions and 5 deletions

View File

@@ -7,6 +7,10 @@
extern int raw_show_trace; extern int raw_show_trace;
extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, extern unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
unsigned long pc, unsigned long *ra); unsigned long pc, unsigned long *ra);
extern unsigned long unwind_stack_by_address(unsigned long stack_page,
unsigned long *sp,
unsigned long pc,
unsigned long *ra);
#else #else
#define raw_show_trace 1 #define raw_show_trace 1
static inline unsigned long unwind_stack(struct task_struct *task, static inline unsigned long unwind_stack(struct task_struct *task,

View File

@@ -373,18 +373,18 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
#ifdef CONFIG_KALLSYMS #ifdef CONFIG_KALLSYMS
/* used by show_backtrace() */ /* generic stack unwinding function */
unsigned long unwind_stack(struct task_struct *task, unsigned long *sp, unsigned long notrace unwind_stack_by_address(unsigned long stack_page,
unsigned long pc, unsigned long *ra) unsigned long *sp,
unsigned long pc,
unsigned long *ra)
{ {
unsigned long stack_page;
struct mips_frame_info info; struct mips_frame_info info;
unsigned long size, ofs; unsigned long size, ofs;
int leaf; int leaf;
extern void ret_from_irq(void); extern void ret_from_irq(void);
extern void ret_from_exception(void); extern void ret_from_exception(void);
stack_page = (unsigned long)task_stack_page(task);
if (!stack_page) if (!stack_page)
return 0; return 0;
@@ -443,6 +443,15 @@ unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
*ra = 0; *ra = 0;
return __kernel_text_address(pc) ? pc : 0; return __kernel_text_address(pc) ? pc : 0;
} }
EXPORT_SYMBOL(unwind_stack_by_address);
/* used by show_backtrace() */
unsigned long unwind_stack(struct task_struct *task, unsigned long *sp,
unsigned long pc, unsigned long *ra)
{
unsigned long stack_page = (unsigned long)task_stack_page(task);
return unwind_stack_by_address(stack_page, sp, pc, ra);
}
#endif #endif
/* /*