Merge branch 'sh/multi-unwinders' into sh-latest

This commit is contained in:
Paul Mundt
2012-06-13 12:12:14 +09:00
當前提交 f21efd4536
共有 6 個文件被更改,包括 102 次插入98 次删除

查看文件

@@ -16,6 +16,8 @@
#include <asm/ptrace.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/unwinder.h>
#include <asm/stacktrace.h>
static u8 regcache[63];
@@ -199,8 +201,11 @@ static int lookup_prev_stack_frame(unsigned long fp, unsigned long pc,
return 0;
}
/* Don't put this on the stack since we'll want to call sh64_unwind
* when we're close to underflowing the stack anyway. */
/*
* Don't put this on the stack since we'll want to call in to
* sh64_unwinder_dump() when we're close to underflowing the stack
* anyway.
*/
static struct pt_regs here_regs;
extern const char syscall_ret;
@@ -208,17 +213,19 @@ extern const char ret_from_syscall;
extern const char ret_from_exception;
extern const char ret_from_irq;
static void sh64_unwind_inner(struct pt_regs *regs);
static void sh64_unwind_inner(const struct stacktrace_ops *ops,
void *data, struct pt_regs *regs);
static void unwind_nested (unsigned long pc, unsigned long fp)
static inline void unwind_nested(const struct stacktrace_ops *ops, void *data,
unsigned long pc, unsigned long fp)
{
if ((fp >= __MEMORY_START) &&
((fp & 7) == 0)) {
sh64_unwind_inner((struct pt_regs *) fp);
}
((fp & 7) == 0))
sh64_unwind_inner(ops, data, (struct pt_regs *)fp);
}
static void sh64_unwind_inner(struct pt_regs *regs)
static void sh64_unwind_inner(const struct stacktrace_ops *ops,
void *data, struct pt_regs *regs)
{
unsigned long pc, fp;
int ofs = 0;
@@ -232,29 +239,29 @@ static void sh64_unwind_inner(struct pt_regs *regs)
int cond;
unsigned long next_fp, next_pc;
if (pc == ((unsigned long) &syscall_ret & ~1)) {
if (pc == ((unsigned long)&syscall_ret & ~1)) {
printk("SYSCALL\n");
unwind_nested(pc,fp);
unwind_nested(ops, data, pc, fp);
return;
}
if (pc == ((unsigned long) &ret_from_syscall & ~1)) {
if (pc == ((unsigned long)&ret_from_syscall & ~1)) {
printk("SYSCALL (PREEMPTED)\n");
unwind_nested(pc,fp);
unwind_nested(ops, data, pc, fp);
return;
}
/* In this case, the PC is discovered by lookup_prev_stack_frame but
it has 4 taken off it to look like the 'caller' */
if (pc == ((unsigned long) &ret_from_exception & ~1)) {
if (pc == ((unsigned long)&ret_from_exception & ~1)) {
printk("EXCEPTION\n");
unwind_nested(pc,fp);
unwind_nested(ops, data, pc, fp);
return;
}
if (pc == ((unsigned long) &ret_from_irq & ~1)) {
if (pc == ((unsigned long)&ret_from_irq & ~1)) {
printk("IRQ\n");
unwind_nested(pc,fp);
unwind_nested(ops, data, pc, fp);
return;
}
@@ -263,8 +270,7 @@ static void sh64_unwind_inner(struct pt_regs *regs)
pc -= ofs;
printk("[<%08lx>] ", pc);
print_symbol("%s\n", pc);
ops->address(data, pc, 1);
if (first_pass) {
/* If the innermost frame is a leaf function, it's
@@ -287,10 +293,13 @@ static void sh64_unwind_inner(struct pt_regs *regs)
}
printk("\n");
}
void sh64_unwind(struct pt_regs *regs)
static void sh64_unwinder_dump(struct task_struct *task,
struct pt_regs *regs,
unsigned long *sp,
const struct stacktrace_ops *ops,
void *data)
{
if (!regs) {
/*
@@ -320,7 +329,17 @@ void sh64_unwind(struct pt_regs *regs)
);
}
printk("\nCall Trace:\n");
sh64_unwind_inner(regs);
sh64_unwind_inner(ops, data, regs);
}
static struct unwinder sh64_unwinder = {
.name = "sh64-unwinder",
.dump = sh64_unwinder_dump,
.rating = 150,
};
static int __init sh64_unwinder_init(void)
{
return unwinder_register(&sh64_unwinder);
}
early_initcall(sh64_unwinder_init);