16fba6b84SAndrew Jones // SPDX-License-Identifier: GPL-2.0-only
26fba6b84SAndrew Jones #include <libcflat.h>
36fba6b84SAndrew Jones #include <stack.h>
46fba6b84SAndrew Jones
5a1f2b0e1SAndrew Jones #ifdef CONFIG_RELOC
6a1f2b0e1SAndrew Jones extern char ImageBase, _text, _etext;
7a1f2b0e1SAndrew Jones
base_address(const void * rebased_addr,unsigned long * addr)8*ab0bbb9fSAndrew Jones bool base_address(const void *rebased_addr, unsigned long *addr)
9a1f2b0e1SAndrew Jones {
10a1f2b0e1SAndrew Jones unsigned long ra = (unsigned long)rebased_addr;
11a1f2b0e1SAndrew Jones unsigned long base = (unsigned long)&ImageBase;
12a1f2b0e1SAndrew Jones unsigned long start = (unsigned long)&_text;
13a1f2b0e1SAndrew Jones unsigned long end = (unsigned long)&_etext;
14a1f2b0e1SAndrew Jones
15a1f2b0e1SAndrew Jones if (ra < start || ra >= end)
16a1f2b0e1SAndrew Jones return false;
17a1f2b0e1SAndrew Jones
18a1f2b0e1SAndrew Jones *addr = ra - base;
19a1f2b0e1SAndrew Jones return true;
20a1f2b0e1SAndrew Jones }
21a1f2b0e1SAndrew Jones #endif
22a1f2b0e1SAndrew Jones
arch_backtrace_frame(const void * frame,const void ** return_addrs,int max_depth,bool current_frame)23a8a78d75SAndrew Jones int arch_backtrace_frame(const void *frame, const void **return_addrs,
24a8a78d75SAndrew Jones int max_depth, bool current_frame)
256fba6b84SAndrew Jones {
266fba6b84SAndrew Jones static bool walking;
276fba6b84SAndrew Jones const unsigned long *fp = (unsigned long *)frame;
286fba6b84SAndrew Jones int depth;
296fba6b84SAndrew Jones
30a8a78d75SAndrew Jones if (current_frame)
31a8a78d75SAndrew Jones fp = __builtin_frame_address(0);
32a8a78d75SAndrew Jones
336fba6b84SAndrew Jones if (walking) {
346fba6b84SAndrew Jones printf("RECURSIVE STACK WALK!!!\n");
356fba6b84SAndrew Jones return 0;
366fba6b84SAndrew Jones }
376fba6b84SAndrew Jones walking = true;
386fba6b84SAndrew Jones
396fba6b84SAndrew Jones for (depth = 0; fp && depth < max_depth; ++depth) {
406fba6b84SAndrew Jones return_addrs[depth] = (void *)fp[-1];
416fba6b84SAndrew Jones if (return_addrs[depth] == 0)
426fba6b84SAndrew Jones break;
436fba6b84SAndrew Jones fp = (unsigned long *)fp[-2];
446fba6b84SAndrew Jones }
456fba6b84SAndrew Jones
466fba6b84SAndrew Jones walking = false;
476fba6b84SAndrew Jones return depth;
486fba6b84SAndrew Jones }
49