blob: e6f259de714726070be83f215a5654c26da3c1c7 [file] [log] [blame]
#include <libcflat.h>
#include <asm/ptrace.h>
#include <stack.h>
extern char do_handle_exception_return[];
int arch_backtrace_frame(const void *frame, const void **return_addrs,
int max_depth, bool current_frame)
{
static int walking;
int depth = 0;
const unsigned long *bp = (unsigned long *)frame;
void *return_addr;
asm volatile("" ::: "lr"); /* Force it to save LR */
if (walking) {
printf("RECURSIVE STACK WALK!!!\n");
return 0;
}
walking = 1;
if (current_frame)
bp = __builtin_frame_address(0);
bp = (unsigned long *)bp[0];
return_addr = (void *)bp[2];
for (depth = 0; bp && depth < max_depth; depth++) {
return_addrs[depth] = return_addr;
if (return_addrs[depth] == 0)
break;
if (return_addrs[depth] == do_handle_exception_return) {
struct pt_regs *regs;
regs = (void *)bp + STACK_FRAME_OVERHEAD;
bp = (unsigned long *)bp[0];
/* Represent interrupt frame with vector number */
return_addr = (void *)regs->trap;
if (depth + 1 < max_depth) {
depth++;
return_addrs[depth] = return_addr;
return_addr = (void *)regs->nip;
}
} else {
bp = (unsigned long *)bp[0];
return_addr = (void *)bp[2];
}
}
walking = 0;
return depth;
}