From: Julian Seward Date: Thu, 22 Dec 2005 19:28:37 +0000 (+0000) Subject: Make async-style syscalls work on ppc64, by using rt_sigprocmask X-Git-Tag: svn/VALGRIND_3_2_0~468 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e28aaa1d45939bc5b30a4bb0252827c51c88cb1d;p=thirdparty%2Fvalgrind.git Make async-style syscalls work on ppc64, by using rt_sigprocmask instead of sigprocmask. In the process, discover that error handling for ML_(do_syscall_for_client_WRK) on all platforms has always been broken, in the sense that the sigprocmasks (which are important) could silently fail. This commit fixes that up too (only on ppc64-linux at the moment, so all other platforms are probably broken now). git-svn-id: svn://svn.valgrind.org/valgrind/trunk@5407 --- diff --git a/coregrind/m_syswrap/syscall-ppc64-linux.S b/coregrind/m_syswrap/syscall-ppc64-linux.S index 0a31c24621..7212cfacec 100644 --- a/coregrind/m_syswrap/syscall-ppc64-linux.S +++ b/coregrind/m_syswrap/syscall-ppc64-linux.S @@ -50,9 +50,10 @@ back to regs->m_gpr[3]/m_xer/m_result on completion. Returns 0 if the syscall was successfully called (even if the - syscall itself failed), or a -ve error code if one of the - sigprocmasks failed (there's no way to determine which one - failed). + syscall itself failed), or an nonzero error code in the lowest + 8 bits if one of the sigprocmasks failed (there's no way to + determine which one failed). And there's no obvious way to + recover from that either, but nevertheless we want to know. VG_(fixup_guest_state_after_syscall_interrupted) does the thread state fixup in the case where we were interrupted by a @@ -60,7 +61,7 @@ Prototype: - Int ML_(do_syscall_for_client_WRK)( + UWord ML_(do_syscall_for_client_WRK)( Int syscallno, // r3 void* guest_state, // r4 const vki_sigset_t *sysmask, // r5 @@ -93,10 +94,11 @@ ML_(do_syscall_for_client_WRK): /* set the signal mask for doing the system call */ /* set up for sigprocmask(SIG_SETMASK, sysmask, postmask) */ -1: li 0,__NR_sigprocmask +1: li 0,__NR_rt_sigprocmask li 3,VKI_SIG_SETMASK mr 4,5 mr 5,6 + mr 6,7 sc /* set the mask */ bso 7f /* if the sigprocmask fails */ @@ -119,15 +121,15 @@ ML_(do_syscall_for_client_WRK): /* block signals again */ /* set up for sigprocmask(SIG_SETMASK, postmask, NULL) */ -4: li 0,__NR_sigprocmask +4: li 0,__NR_rt_sigprocmask li 3,VKI_SIG_SETMASK mr 4,29 li 5,0 mr 6,28 sc /* set the mask */ bso 7f /* if the sigprocmask fails */ - /* now safe from signals */ + li 3,0 /* SUCCESS */ /* pop off stack frame */ 5: ld 28,48(1) @@ -138,7 +140,7 @@ ML_(do_syscall_for_client_WRK): blr /* failure: return -ve error code */ -7: neg 3,3 +7: ori 3,3,0x8000 /* FAILURE -- ensure return value is nonzero */ b 5b .section .rodata diff --git a/coregrind/m_syswrap/syswrap-main.c b/coregrind/m_syswrap/syswrap-main.c index 8251d03956..b2b2642917 100644 --- a/coregrind/m_syswrap/syswrap-main.c +++ b/coregrind/m_syswrap/syswrap-main.c @@ -223,11 +223,11 @@ VG_(fixup_guest_state_after_syscall_interrupted) below for details. */ extern -void ML_(do_syscall_for_client_WRK)( Int syscallno, - void* guest_state, - const vki_sigset_t *syscall_mask, - const vki_sigset_t *restore_mask, - Int nsigwords ); +UWord ML_(do_syscall_for_client_WRK)( Int syscallno, + void* guest_state, + const vki_sigset_t *syscall_mask, + const vki_sigset_t *restore_mask, + Int nsigwords ); static void do_syscall_for_client ( Int syscallno, @@ -235,9 +235,15 @@ void do_syscall_for_client ( Int syscallno, const vki_sigset_t* syscall_mask ) { vki_sigset_t saved; - ML_(do_syscall_for_client_WRK)( - syscallno, &tst->arch.vex, - syscall_mask, &saved, _VKI_NSIG_WORDS * sizeof(UWord) + UWord err + = ML_(do_syscall_for_client_WRK)( + syscallno, &tst->arch.vex, + syscall_mask, &saved, _VKI_NSIG_WORDS * sizeof(UWord) + ); + vg_assert2( + err == 0, + "ML_(do_syscall_for_client_WRK): sigprocmask error %d", + (Int)(err & 0xFFF) ); }