sh: Use the generalized stacktrace ops
Copy the stacktrace ops code from x86 and provide a central function for use by functions that need to dump a callstack. Signed-off-by: Matt Fleming <matt@console-pimps.org> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
@@ -20,6 +20,39 @@
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/stacktrace.h>
|
||||
|
||||
static void backtrace_warning_symbol(void *data, char *msg,
|
||||
unsigned long symbol)
|
||||
{
|
||||
/* Ignore warnings */
|
||||
}
|
||||
|
||||
static void backtrace_warning(void *data, char *msg)
|
||||
{
|
||||
/* Ignore warnings */
|
||||
}
|
||||
|
||||
static int backtrace_stack(void *data, char *name)
|
||||
{
|
||||
/* Yes, we want all stacks */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void backtrace_address(void *data, unsigned long addr, int reliable)
|
||||
{
|
||||
unsigned int *depth = data;
|
||||
|
||||
if ((*depth)--)
|
||||
oprofile_add_trace(addr);
|
||||
}
|
||||
|
||||
static struct stacktrace_ops backtrace_ops = {
|
||||
.warning = backtrace_warning,
|
||||
.warning_symbol = backtrace_warning_symbol,
|
||||
.stack = backtrace_stack,
|
||||
.address = backtrace_address,
|
||||
};
|
||||
|
||||
/* Limit to stop backtracing too far. */
|
||||
static int backtrace_limit = 20;
|
||||
@@ -74,23 +107,6 @@ static int valid_kernel_stack(unsigned long *stackaddr, struct pt_regs *regs)
|
||||
return ((unsigned long)stackaddr > stack) && ((unsigned long)stackaddr < stack_base);
|
||||
}
|
||||
|
||||
static unsigned long *
|
||||
kernel_backtrace(unsigned long *stackaddr, struct pt_regs *regs)
|
||||
{
|
||||
unsigned long addr;
|
||||
|
||||
/*
|
||||
* If not a valid kernel address, keep going till we find one
|
||||
* or the SP stops being a valid address.
|
||||
*/
|
||||
do {
|
||||
addr = *stackaddr++;
|
||||
oprofile_add_trace(addr);
|
||||
} while (valid_kernel_stack(stackaddr, regs));
|
||||
|
||||
return stackaddr;
|
||||
}
|
||||
|
||||
void sh_backtrace(struct pt_regs * const regs, unsigned int depth)
|
||||
{
|
||||
unsigned long *stackaddr;
|
||||
@@ -103,9 +119,9 @@ void sh_backtrace(struct pt_regs * const regs, unsigned int depth)
|
||||
|
||||
stackaddr = (unsigned long *)regs->regs[15];
|
||||
if (!user_mode(regs)) {
|
||||
while (depth-- && valid_kernel_stack(stackaddr, regs))
|
||||
stackaddr = kernel_backtrace(stackaddr, regs);
|
||||
|
||||
if (depth)
|
||||
dump_trace(NULL, regs, stackaddr,
|
||||
&backtrace_ops, &depth);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user