1*6fba6b84SAndrew Jones // SPDX-License-Identifier: GPL-2.0-only 2*6fba6b84SAndrew Jones #include <libcflat.h> 3*6fba6b84SAndrew Jones #include <stack.h> 4*6fba6b84SAndrew Jones 5*6fba6b84SAndrew Jones int backtrace_frame(const void *frame, const void **return_addrs, int max_depth) 6*6fba6b84SAndrew Jones { 7*6fba6b84SAndrew Jones static bool walking; 8*6fba6b84SAndrew Jones const unsigned long *fp = (unsigned long *)frame; 9*6fba6b84SAndrew Jones int depth; 10*6fba6b84SAndrew Jones 11*6fba6b84SAndrew Jones if (walking) { 12*6fba6b84SAndrew Jones printf("RECURSIVE STACK WALK!!!\n"); 13*6fba6b84SAndrew Jones return 0; 14*6fba6b84SAndrew Jones } 15*6fba6b84SAndrew Jones walking = true; 16*6fba6b84SAndrew Jones 17*6fba6b84SAndrew Jones for (depth = 0; fp && depth < max_depth; ++depth) { 18*6fba6b84SAndrew Jones return_addrs[depth] = (void *)fp[-1]; 19*6fba6b84SAndrew Jones if (return_addrs[depth] == 0) 20*6fba6b84SAndrew Jones break; 21*6fba6b84SAndrew Jones fp = (unsigned long *)fp[-2]; 22*6fba6b84SAndrew Jones } 23*6fba6b84SAndrew Jones 24*6fba6b84SAndrew Jones walking = false; 25*6fba6b84SAndrew Jones return depth; 26*6fba6b84SAndrew Jones } 27*6fba6b84SAndrew Jones 28*6fba6b84SAndrew Jones int backtrace(const void **return_addrs, int max_depth) 29*6fba6b84SAndrew Jones { 30*6fba6b84SAndrew Jones return backtrace_frame(__builtin_frame_address(0), 31*6fba6b84SAndrew Jones return_addrs, max_depth); 32*6fba6b84SAndrew Jones } 33