#include "unwind_i.h"
#if defined(__linux__)
# define SIGNAL_RETURN 0xd4000001d2801168
#elif defined(__FreeBSD__)
# define SIGNAL_RETURN 0x91014000910003e0
#elif defined(__QNX__)
# define SIGNAL_RETURN 0x14000000aa1303e0
# define HANDLER_CALL 0xd63f0060f9400260
#endif
int
unw_is_signal_frame (unw_cursor_t *cursor)
{
#if defined(__linux__) || defined(__FreeBSD__) || defined(__QNX__)
struct cursor *c = (struct cursor *) cursor;
unw_word_t w0, ip;
unw_addr_space_t as;
unw_accessors_t *a;
void *arg;
int ret;
as = c->dwarf.as;
a = unw_get_accessors_int (as);
arg = c->dwarf.as_arg;
ip = c->dwarf.ip;
ret = (*a->access_mem) (as, ip, &w0, 0, arg);
if (ret < 0)
return ret;
if ((w0 & SIGNAL_RETURN) != SIGNAL_RETURN)
return 0;
#if defined(__FreeBSD__)
ip += 8;
ret = (*a->access_mem) (as, ip, &w0, 0, arg);
if (ret < 0)
return ret;
if (w0 != 0xd4000001d2803428)
return 0;
#elif defined(__QNX__)
unw_word_t w1 = 0;
ret = (*a->access_mem) (as, ip-sizeof(w1), &w1, 0, arg);
if (ret < 0)
return ret;
if ((w1 & HANDLER_CALL) != HANDLER_CALL)
{
return 0;
}
#endif
return 1;
#else
return -UNW_ENOINFO;
#endif
}