#if !defined(UNW_REMOTE_ONLY) && !defined(UNW_LOCAL_ONLY)
#define UNW_LOCAL_ONLY
#include <libunwind.h>
#include <libunwind_i.h>
#include <string.h>
static ALWAYS_INLINE int
slow_backtrace (void **buffer, int size, unw_context_t *uc, int flag)
{
unw_cursor_t cursor;
unw_word_t ip;
int n = 0;
if (unlikely (unw_init_local2 (&cursor, uc, flag) < 0))
return 0;
while (unw_step (&cursor) > 0)
{
if (n >= size)
return n;
if (unw_get_reg (&cursor, UNW_REG_IP, &ip) < 0)
return n;
buffer[n++] = (void *) (uintptr_t) ip;
}
return n;
}
int
unw_backtrace (void **buffer, int size)
{
unw_cursor_t cursor;
unw_context_t uc;
int n = size;
tdep_getcontext_trace (&uc);
if (unlikely (unw_init_local (&cursor, &uc) < 0))
return 0;
if (unlikely (tdep_trace (&cursor, buffer, &n) < 0))
{
unw_getcontext (&uc);
return slow_backtrace (buffer, size, &uc, 0);
}
return n;
}
int
unw_backtrace2 (void **buffer, int size, unw_context_t* uc2, int flag)
{
if (size == 0)
return 0;
if (uc2 == NULL)
return unw_backtrace(buffer, size);
unw_cursor_t cursor;
unw_context_t uc = *(unw_context_t*)uc2;
if (unlikely (unw_init_local2 (&cursor, &uc, flag) < 0))
return 0;
unw_word_t ip;
if (unw_get_reg (&cursor, UNW_REG_IP, &ip) < 0)
return 0;
buffer[0] = (void *) (uintptr_t)ip;
buffer = buffer+1;
int remaining_size = size-1;
int n = remaining_size;
if (unlikely (tdep_trace (&cursor, buffer, &n) < 0))
{
return slow_backtrace (buffer, remaining_size, &uc, flag) + 1;
}
return n + 1;
}
#ifdef CONFIG_WEAK_BACKTRACE
extern int backtrace (void **buffer, int size)
WEAK ALIAS(unw_backtrace);
#endif
#endif