xref: /kvm-unit-tests/lib/riscv/stack.c (revision ab0bbb9fd1eb426a8f43ac74eb762bc135568023)
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