1 // SPDX-License-Identifier: GPL-2.0-only
2 #include <libcflat.h>
3 #include <stack.h>
4
5 #ifdef CONFIG_RELOC
6 extern char ImageBase, _text, _etext;
7
base_address(const void * rebased_addr,unsigned long * addr)8 bool base_address(const void *rebased_addr, unsigned long *addr)
9 {
10 unsigned long ra = (unsigned long)rebased_addr;
11 unsigned long base = (unsigned long)&ImageBase;
12 unsigned long start = (unsigned long)&_text;
13 unsigned long end = (unsigned long)&_etext;
14
15 if (ra < start || ra >= end)
16 return false;
17
18 *addr = ra - base;
19 return true;
20 }
21 #endif
22
arch_backtrace_frame(const void * frame,const void ** return_addrs,int max_depth,bool current_frame)23 int arch_backtrace_frame(const void *frame, const void **return_addrs,
24 int max_depth, bool current_frame)
25 {
26 static bool walking;
27 const unsigned long *fp = (unsigned long *)frame;
28 int depth;
29
30 if (current_frame)
31 fp = __builtin_frame_address(0);
32
33 if (walking) {
34 printf("RECURSIVE STACK WALK!!!\n");
35 return 0;
36 }
37 walking = true;
38
39 for (depth = 0; fp && depth < max_depth; ++depth) {
40 return_addrs[depth] = (void *)fp[-1];
41 if (return_addrs[depth] == 0)
42 break;
43 fp = (unsigned long *)fp[-2];
44 }
45
46 walking = false;
47 return depth;
48 }
49