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 Jonesint 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