123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- /*
- * stack related functions
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Library General Public License version 2.
- */
- #include <libcflat.h>
- #include <stack.h>
- #define MAX_DEPTH 20
- static void print_stack(const void **return_addrs, int depth,
- bool top_is_return_address)
- {
- int i = 0;
- printf("\tSTACK:");
- /* @addr indicates a non-return address, as expected by the stack
- * pretty printer script. */
- if (depth > 0 && !top_is_return_address) {
- printf(" @%lx", (unsigned long) return_addrs[0]);
- i++;
- }
- for (; i < depth; i++) {
- printf(" %lx", (unsigned long) return_addrs[i]);
- }
- printf("\n");
- }
- void dump_stack(void)
- {
- const void *return_addrs[MAX_DEPTH];
- int depth;
- depth = backtrace(return_addrs, MAX_DEPTH);
- print_stack(&return_addrs[1], depth ? depth - 1 : 0, true);
- }
- void dump_frame_stack(const void *instruction, const void *frame)
- {
- const void *return_addrs[MAX_DEPTH];
- int depth;
- return_addrs[0] = instruction;
- depth = backtrace_frame(frame, &return_addrs[1], MAX_DEPTH - 1);
- print_stack(return_addrs, depth + 1, false);
- }
- #ifndef HAVE_ARCH_BACKTRACE
- int backtrace(const void **return_addrs, int max_depth)
- {
- static int walking;
- int depth = 0;
- void *addr;
- if (walking) {
- printf("RECURSIVE STACK WALK!!!\n");
- return 0;
- }
- walking = 1;
- /* __builtin_return_address requires a compile-time constant argument */
- #define GET_RETURN_ADDRESS(i) \
- if (max_depth == i) \
- goto done; \
- addr = __builtin_return_address(i); \
- if (!addr) \
- goto done; \
- return_addrs[i] = __builtin_extract_return_addr(addr); \
- depth = i + 1; \
- GET_RETURN_ADDRESS(0)
- GET_RETURN_ADDRESS(1)
- GET_RETURN_ADDRESS(2)
- GET_RETURN_ADDRESS(3)
- GET_RETURN_ADDRESS(4)
- GET_RETURN_ADDRESS(5)
- GET_RETURN_ADDRESS(6)
- GET_RETURN_ADDRESS(7)
- GET_RETURN_ADDRESS(8)
- GET_RETURN_ADDRESS(9)
- GET_RETURN_ADDRESS(10)
- GET_RETURN_ADDRESS(11)
- GET_RETURN_ADDRESS(12)
- GET_RETURN_ADDRESS(13)
- GET_RETURN_ADDRESS(14)
- GET_RETURN_ADDRESS(15)
- GET_RETURN_ADDRESS(16)
- GET_RETURN_ADDRESS(17)
- GET_RETURN_ADDRESS(18)
- GET_RETURN_ADDRESS(19)
- GET_RETURN_ADDRESS(20)
- #undef GET_RETURN_ADDRESS
- done:
- walking = 0;
- return depth;
- }
- #endif /* HAVE_ARCH_BACKTRACE */
|