From 81f2de00830e7d68add0c12b68a3c67778acaf6d Mon Sep 17 00:00:00 2001 From: Konstantin Belousov <kostik@pooma.home> Date: Sat, 6 Mar 2010 18:08:44 +0200 Subject: [PATCH] Add implementation of unw_is_signal_frame for freebsd. --- src/x86_64/Gis_signal_frame.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/x86_64/Gis_signal_frame.c b/src/x86_64/Gis_signal_frame.c index e51fc672..3bee93a8 100644 --- a/src/x86_64/Gis_signal_frame.c +++ b/src/x86_64/Gis_signal_frame.c @@ -72,8 +72,35 @@ PROTECTED int unw_is_signal_frame (unw_cursor_t *cursor) { /* XXXKIB */ - printf ("%s: implement me\n", __FUNCTION__); - return -UNW_ENOINFO; + struct cursor *c = (struct cursor *) cursor; + unw_word_t w0, w1, w2, w3, w4, ip; + unw_addr_space_t as; + unw_accessors_t *a; + void *arg; + int ret; + + as = c->dwarf.as; + a = unw_get_accessors (as); + arg = c->dwarf.as_arg; + + /* Check if RIP points at sigreturn sequence. +48 8d 7c 24 10 lea SIGF_UC(%rsp),%rdi +6a 00 pushq $0 +48 c7 c0 a1 01 00 00 movq $SYS_sigreturn,%rax +0f 05 syscall +f4 0: hlt +eb fd jmp 0b + */ + + ip = c->dwarf.ip; + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0 + || (ret = (*a->access_mem) (as, ip + 8, &w1, 0, arg)) < 0 + || (ret = (*a->access_mem) (as, ip + 16, &w2, 0, arg)) < 0) + return 0; + w2 &= 0xffffff; + return (w0 == 0x48006a10247c8d48 && + w1 == 0x050f000001a1c0c7 && + w2 == 0x0000000000fdebf4); } #else /* __linux__ */