From 049e2ba1b9734ec027765cd9449cb29a9bc0d974 Mon Sep 17 00:00:00 2001 From: Zachary T Welch Date: Tue, 15 Mar 2011 18:15:41 +0000 Subject: [PATCH] Add ARM signal frame detection Implements a check for call to sigreturn that the kernel will have setup before jumping to the signal handler. Signed-off-by: Ken Werner --- src/arm/Gis_signal_frame.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/arm/Gis_signal_frame.c b/src/arm/Gis_signal_frame.c index 77548d5c..a7461825 100644 --- a/src/arm/Gis_signal_frame.c +++ b/src/arm/Gis_signal_frame.c @@ -1,5 +1,6 @@ /* libunwind - a platform-independent unwind library Copyright (C) 2008 CodeSourcery + Copyright 2011 Linaro Limited This file is part of libunwind. @@ -25,11 +26,39 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #include #include "unwind_i.h" -/* FIXME for ARM. */ +#ifdef __linux__ +#include + +#define ARM_SIGRETURN (0xef000000UL |(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE)) +#define THUMB_SIGRETURN (0xdf00UL << 16 | 0x2700 | (__NR_sigreturn - __NR_SYSCALL_BASE)) +#define MOV_R7_SIGRETURN (0xe3a07000UL | (__NR_sigreturn - __NR_SYSCALL_BASE)) +#endif PROTECTED int unw_is_signal_frame (unw_cursor_t *cursor) { +#ifdef __linux__ + 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 (as); + arg = c->dwarf.as_arg; + + ip = c->dwarf.ip; + if ((ret = (*a->access_mem) (as, ip, &w0, 0, arg)) < 0) + return ret; + ret = (w0 == ARM_SIGRETURN) || (w0 == MOV_R7_SIGRETURN) + || (w0 == THUMB_SIGRETURN); + fprintf (stderr, "w0=%8.8x ret=%d\n", w0, ret); + Debug (16, "returning %d\n", ret); + return ret; +#else printf ("%s: implement me\n", __FUNCTION__); return -UNW_ENOINFO; +#endif }