]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Make async-style syscalls work on ppc64, by using rt_sigprocmask
authorJulian Seward <jseward@acm.org>
Thu, 22 Dec 2005 19:28:37 +0000 (19:28 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 22 Dec 2005 19:28:37 +0000 (19:28 +0000)
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

coregrind/m_syswrap/syscall-ppc64-linux.S
coregrind/m_syswrap/syswrap-main.c

index 0a31c24621f9f4ff78ca33076b636cdda190e002..7212cfacecb2f56d822bfd4677ae96b65e1299e6 100644 (file)
         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
index 8251d03956d92e253cc17cff32409a59a55ca8de..b2b26429177088538ffdbf6aed1ef6656b155c15 100644 (file)
    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)
    );
 }