1 /* 2 * stack related functions 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU Library General Public License version 2. 6 */ 7 8 #include <libcflat.h> 9 #include <stack.h> 10 11 #define MAX_DEPTH 20 12 13 static void print_stack(const void **return_addrs, int depth, 14 bool top_is_return_address) 15 { 16 int i = 0; 17 18 printf("\tSTACK:"); 19 20 /* @addr indicates a non-return address, as expected by the stack 21 * pretty printer script. */ 22 if (depth > 0 && !top_is_return_address) { 23 printf(" @%lx", (unsigned long) return_addrs[0]); 24 i++; 25 } 26 27 for (; i < depth; i++) { 28 printf(" %lx", (unsigned long) return_addrs[i]); 29 } 30 printf("\n"); 31 } 32 33 void dump_stack(void) 34 { 35 const void *return_addrs[MAX_DEPTH]; 36 int depth; 37 38 depth = backtrace(return_addrs, MAX_DEPTH); 39 print_stack(&return_addrs[1], depth ? depth - 1 : 0, true); 40 } 41 42 void dump_frame_stack(const void *instruction, const void *frame) 43 { 44 const void *return_addrs[MAX_DEPTH]; 45 int depth; 46 47 return_addrs[0] = instruction; 48 depth = backtrace_frame(frame, &return_addrs[1], MAX_DEPTH - 1); 49 print_stack(return_addrs, depth + 1, false); 50 } 51 52 #ifndef HAVE_ARCH_BACKTRACE 53 int backtrace(const void **return_addrs, int max_depth) 54 { 55 static int walking; 56 int depth = 0; 57 void *addr; 58 59 if (walking) { 60 printf("RECURSIVE STACK WALK!!!\n"); 61 return 0; 62 } 63 walking = 1; 64 65 /* __builtin_return_address requires a compile-time constant argument */ 66 #define GET_RETURN_ADDRESS(i) \ 67 if (max_depth == i) \ 68 goto done; \ 69 addr = __builtin_return_address(i); \ 70 if (!addr) \ 71 goto done; \ 72 return_addrs[i] = __builtin_extract_return_addr(addr); \ 73 depth = i + 1; \ 74 75 GET_RETURN_ADDRESS(0) 76 GET_RETURN_ADDRESS(1) 77 GET_RETURN_ADDRESS(2) 78 GET_RETURN_ADDRESS(3) 79 GET_RETURN_ADDRESS(4) 80 GET_RETURN_ADDRESS(5) 81 GET_RETURN_ADDRESS(6) 82 GET_RETURN_ADDRESS(7) 83 GET_RETURN_ADDRESS(8) 84 GET_RETURN_ADDRESS(9) 85 GET_RETURN_ADDRESS(10) 86 GET_RETURN_ADDRESS(11) 87 GET_RETURN_ADDRESS(12) 88 GET_RETURN_ADDRESS(13) 89 GET_RETURN_ADDRESS(14) 90 GET_RETURN_ADDRESS(15) 91 GET_RETURN_ADDRESS(16) 92 GET_RETURN_ADDRESS(17) 93 GET_RETURN_ADDRESS(18) 94 GET_RETURN_ADDRESS(19) 95 GET_RETURN_ADDRESS(20) 96 97 #undef GET_RETURN_ADDRESS 98 99 done: 100 walking = 0; 101 return depth; 102 } 103 #endif /* HAVE_ARCH_BACKTRACE */ 104