From: Julian Seward Date: Sun, 20 Nov 2011 09:35:51 +0000 (+0000) Subject: arm-linux: fix signal returning so that if SA_RESTORER is not X-Git-Tag: svn/VALGRIND_3_8_0~580 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3f4bbbc0b72e92acf9bca6fbb07b65a058e99d3b;p=thirdparty%2Fvalgrind.git arm-linux: fix signal returning so that if SA_RESTORER is not specified, the handler returns to the previous context rather than to whatever value happens to be parked in the link register (duh). Previous behaviour made complete nonsense of signal returning on Android. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12273 --- diff --git a/coregrind/m_sigframe/sigframe-arm-linux.c b/coregrind/m_sigframe/sigframe-arm-linux.c index 441c351465..cf68bdefdb 100644 --- a/coregrind/m_sigframe/sigframe-arm-linux.c +++ b/coregrind/m_sigframe/sigframe-arm-linux.c @@ -259,7 +259,12 @@ void VG_(sigframe_create)( ThreadId tid, tst->arch.vex.guest_R0 = sigNo; if (flags & VKI_SA_RESTORER) - tst->arch.vex.guest_R14 = (Addr) restorer; + tst->arch.vex.guest_R14 = (Addr)restorer; + else + tst->arch.vex.guest_R14 + = (flags & VKI_SA_SIGINFO) + ? (Addr)&VG_(arm_linux_SUBST_FOR_rt_sigreturn) + : (Addr)&VG_(arm_linux_SUBST_FOR_sigreturn); tst->arch.vex.guest_R15T = (Addr) handler; /* R15 == PC */ } diff --git a/coregrind/m_trampoline.S b/coregrind/m_trampoline.S index bc227005e1..a9acfa6922 100644 --- a/coregrind/m_trampoline.S +++ b/coregrind/m_trampoline.S @@ -517,6 +517,22 @@ VG_(trampoline_stuff_end): .global VG_(trampoline_stuff_start) VG_(trampoline_stuff_start): +.global VG_(arm_linux_SUBST_FOR_sigreturn) +.type VG_(arm_linux_SUBST_FOR_sigreturn),#function +VG_(arm_linux_SUBST_FOR_sigreturn): + mov r7, # __NR_sigreturn + svc #0 + .long 0xFFFFFFFF /*illegal insn*/ +.size VG_(arm_linux_SUBST_FOR_sigreturn), .-VG_(arm_linux_SUBST_FOR_sigreturn) + +.global VG_(arm_linux_SUBST_FOR_rt_sigreturn) +.type VG_(arm_linux_SUBST_FOR_rt_sigreturn),#function +VG_(arm_linux_SUBST_FOR_rt_sigreturn): + mov r7, # __NR_rt_sigreturn + svc #0 + .long 0xFFFFFFFF /*illegal insn*/ +.size VG_(arm_linux_SUBST_FOR_rt_sigreturn), .-VG_(arm_linux_SUBST_FOR_rt_sigreturn) + .global VG_(arm_linux_REDIR_FOR_strlen) VG_(arm_linux_REDIR_FOR_strlen): mov r2, r0 diff --git a/coregrind/pub_core_trampoline.h b/coregrind/pub_core_trampoline.h index 87fd86841e..72b577e976 100644 --- a/coregrind/pub_core_trampoline.h +++ b/coregrind/pub_core_trampoline.h @@ -93,6 +93,8 @@ extern Addr VG_(ppctoc_magic_redirect_return_stub); #endif #if defined(VGP_arm_linux) +extern Addr VG_(arm_linux_SUBST_FOR_sigreturn); +extern Addr VG_(arm_linux_SUBST_FOR_rt_sigreturn); extern UInt VG_(arm_linux_REDIR_FOR_strlen)( void* ); //extern void* VG_(arm_linux_REDIR_FOR_index) ( void*, Int ); extern void* VG_(arm_linux_REDIR_FOR_memcpy)( void*, void*, Int );