xref: /kvm-unit-tests/lib/arm/stack.c (revision 6444ae208ce0085d0f5c5ffb15909ca3bbd49c84)
12c92230aSAndrew Jones /*
22c92230aSAndrew Jones  * backtrace support (this is a modified lib/x86/stack.c)
32c92230aSAndrew Jones  *
42c92230aSAndrew Jones  * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
52c92230aSAndrew Jones  *
62c92230aSAndrew Jones  * This work is licensed under the terms of the GNU LGPL, version 2.
72c92230aSAndrew Jones  */
82c92230aSAndrew Jones #include <libcflat.h>
92c92230aSAndrew Jones #include <stack.h>
102c92230aSAndrew Jones 
arch_backtrace_frame(const void * frame,const void ** return_addrs,int max_depth,bool current_frame)11*a8a78d75SAndrew Jones int arch_backtrace_frame(const void *frame, const void **return_addrs,
12*a8a78d75SAndrew Jones 			 int max_depth, bool current_frame)
132c92230aSAndrew Jones {
142c92230aSAndrew Jones 	static int walking;
152c92230aSAndrew Jones 	int depth;
162c92230aSAndrew Jones 	const unsigned long *fp = (unsigned long *)frame;
172c92230aSAndrew Jones 
18*a8a78d75SAndrew Jones 	if (current_frame)
19*a8a78d75SAndrew Jones 		fp = __builtin_frame_address(0);
20*a8a78d75SAndrew Jones 
212c92230aSAndrew Jones 	if (walking) {
222c92230aSAndrew Jones 		printf("RECURSIVE STACK WALK!!!\n");
232c92230aSAndrew Jones 		return 0;
242c92230aSAndrew Jones 	}
252c92230aSAndrew Jones 	walking = 1;
262c92230aSAndrew Jones 
272c92230aSAndrew Jones 	for (depth = 0; depth < max_depth; depth++) {
282c92230aSAndrew Jones 		if (!fp)
292c92230aSAndrew Jones 			break;
302c92230aSAndrew Jones 		return_addrs[depth] = (void *)fp[0];
312c92230aSAndrew Jones 		if (return_addrs[depth] == 0)
322c92230aSAndrew Jones 			break;
332c92230aSAndrew Jones 		fp = (unsigned long *)fp[-1];
342c92230aSAndrew Jones 	}
352c92230aSAndrew Jones 
362c92230aSAndrew Jones 	walking = 0;
372c92230aSAndrew Jones 	return depth;
382c92230aSAndrew Jones }
39