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