1 #include <libcflat.h> 2 #include <asm/ptrace.h> 3 #include <stack.h> 4 5 extern char do_handle_exception_return[]; 6 arch_backtrace_frame(const void * frame,const void ** return_addrs,int max_depth,bool current_frame)7int arch_backtrace_frame(const void *frame, const void **return_addrs, 8 int max_depth, bool current_frame) 9 { 10 static int walking; 11 int depth = 0; 12 const unsigned long *bp = (unsigned long *)frame; 13 void *return_addr; 14 15 asm volatile("" ::: "lr"); /* Force it to save LR */ 16 17 if (walking) { 18 printf("RECURSIVE STACK WALK!!!\n"); 19 return 0; 20 } 21 walking = 1; 22 23 if (current_frame) 24 bp = __builtin_frame_address(0); 25 26 bp = (unsigned long *)bp[0]; 27 return_addr = (void *)bp[2]; 28 29 for (depth = 0; bp && depth < max_depth; depth++) { 30 return_addrs[depth] = return_addr; 31 if (return_addrs[depth] == 0) 32 break; 33 if (return_addrs[depth] == do_handle_exception_return) { 34 struct pt_regs *regs; 35 36 regs = (void *)bp + STACK_FRAME_OVERHEAD; 37 bp = (unsigned long *)bp[0]; 38 /* Represent interrupt frame with vector number */ 39 return_addr = (void *)regs->trap; 40 if (depth + 1 < max_depth) { 41 depth++; 42 return_addrs[depth] = return_addr; 43 return_addr = (void *)regs->nip; 44 } 45 } else { 46 bp = (unsigned long *)bp[0]; 47 return_addr = (void *)bp[2]; 48 } 49 } 50 51 walking = 0; 52 return depth; 53 } 54