1*d9de8051SNadav Amit // SPDX-License-Identifier: GPL-2.0-only 2*d9de8051SNadav Amit /* 3*d9de8051SNadav Amit * Backtrace support. 4*d9de8051SNadav Amit */ 5*d9de8051SNadav Amit #include <libcflat.h> 6*d9de8051SNadav Amit #include <stdbool.h> 7*d9de8051SNadav Amit #include <stack.h> 8*d9de8051SNadav Amit 9*d9de8051SNadav Amit int backtrace_frame(const void *frame, const void **return_addrs, int max_depth) 10*d9de8051SNadav Amit { 11*d9de8051SNadav Amit const void *fp = frame; 12*d9de8051SNadav Amit static bool walking; 13*d9de8051SNadav Amit void *lr; 14*d9de8051SNadav Amit int depth; 15*d9de8051SNadav Amit 16*d9de8051SNadav Amit if (walking) { 17*d9de8051SNadav Amit printf("RECURSIVE STACK WALK!!!\n"); 18*d9de8051SNadav Amit return 0; 19*d9de8051SNadav Amit } 20*d9de8051SNadav Amit walking = true; 21*d9de8051SNadav Amit 22*d9de8051SNadav Amit /* 23*d9de8051SNadav Amit * ARM64 stack grows down. fp points to the previous fp on the stack, 24*d9de8051SNadav Amit * and lr is just above it 25*d9de8051SNadav Amit */ 26*d9de8051SNadav Amit for (depth = 0; fp && depth < max_depth; ++depth) { 27*d9de8051SNadav Amit 28*d9de8051SNadav Amit asm volatile ("ldp %0, %1, [%2]" 29*d9de8051SNadav Amit : "=r" (fp), "=r" (lr) 30*d9de8051SNadav Amit : "r" (fp) 31*d9de8051SNadav Amit : ); 32*d9de8051SNadav Amit 33*d9de8051SNadav Amit return_addrs[depth] = lr; 34*d9de8051SNadav Amit } 35*d9de8051SNadav Amit 36*d9de8051SNadav Amit walking = false; 37*d9de8051SNadav Amit return depth; 38*d9de8051SNadav Amit } 39*d9de8051SNadav Amit 40*d9de8051SNadav Amit int backtrace(const void **return_addrs, int max_depth) 41*d9de8051SNadav Amit { 42*d9de8051SNadav Amit return backtrace_frame(__builtin_frame_address(0), 43*d9de8051SNadav Amit return_addrs, max_depth); 44*d9de8051SNadav Amit } 45