diff mbox

[1/3] Add ARM signal frame detection

Message ID 1300819028-31314-2-git-send-email-ken.werner@linaro.org
State Accepted
Commit 049e2ba1b9734ec027765cd9449cb29a9bc0d974
Headers show

Commit Message

Ken Werner March 22, 2011, 6:37 p.m. UTC
From: Zachary T Welch <zwelch@codesourcery.com>

Implements a check for call to sigreturn that the kernel will have
setup before jumping to the signal handler.

Signed-off-by: Ken Werner <ken.werner@linaro.org>
---
 src/arm/Gis_signal_frame.c |   31 ++++++++++++++++++++++++++++++-
 1 files changed, 30 insertions(+), 1 deletions(-)
diff mbox

Patch

diff --git a/src/arm/Gis_signal_frame.c b/src/arm/Gis_signal_frame.c
index 77548d5..a746182 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 <stdio.h>
 #include "unwind_i.h"
 
-/* FIXME for ARM.  */
+#ifdef __linux__
+#include <sys/syscall.h>
+
+#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
 }