From 9533ea1a6adc91276cd779c598f5718c773c44c9 Mon Sep 17 00:00:00 2001 From: Ken Werner Date: Thu, 28 Apr 2011 17:14:30 +0200 Subject: [PATCH] Add support for RT signal frame detection on ARM. This patch adds a few more patterns to the check that detects if the IP points to a sigreturn sequence. Signed-off-by: Ken Werner --- src/arm/Gis_signal_frame.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/arm/Gis_signal_frame.c b/src/arm/Gis_signal_frame.c index e4721858..284289fa 100644 --- a/src/arm/Gis_signal_frame.c +++ b/src/arm/Gis_signal_frame.c @@ -29,11 +29,21 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #ifdef __linux__ #include +/* ARM EABI sigreturn (the syscall number is loaded into r7) */ +#define MOV_R7_SIGRETURN (0xe3a07000UL | __NR_sigreturn) +#define MOV_R7_RT_SIGRETURN (0xe3a07000UL | __NR_rt_sigreturn) + +/* ARM OABI sigreturn (using SWI) */ #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)) +#define ARM_RT_SIGRETURN (0xef000000UL |(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE)) + +/* Thumb sigreturn (two insns, syscall number is loaded into r7) */ +#define THUMB_SIGRETURN (0xdf00UL << 16 | 0x2700 | __NR_sigreturn) +#define THUMB_RT_SIGRETURN (0xdf00UL << 16 | 0x2700 | __NR_rt_sigreturn) #endif +/* Returns 1 in case of a non-RT signal frame and 2 in case of a RT signal + frame. */ PROTECTED int unw_is_signal_frame (unw_cursor_t *cursor) { @@ -50,13 +60,19 @@ unw_is_signal_frame (unw_cursor_t *cursor) 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; + + /* Return 1 if the IP points to a non-RT sigreturn sequence. */ + if (w0 == MOV_R7_SIGRETURN || w0 == ARM_SIGRETURN || w0 == THUMB_SIGRETURN) + return 1; + /* Return 2 if the IP points to a RT sigreturn sequence. */ + else if (w0 == MOV_R7_RT_SIGRETURN || w0 == ARM_RT_SIGRETURN + || w0 == THUMB_RT_SIGRETURN) + return 2; + + return 0; #else printf ("%s: implement me\n", __FUNCTION__); return -UNW_ENOINFO;