]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 511329 - Darwin and FreeBSD: Move setting of carry flag out of ML_(do_syscall_for...
authorPaul Floyd <pjfloyd@wanadoo.fr>
Wed, 29 Oct 2025 18:50:05 +0000 (19:50 +0100)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Wed, 29 Oct 2025 19:18:04 +0000 (20:18 +0100)
This changeset includes the changes to ML_(do_syscall_for_client_WRK)
for the 3 supported FreeBSD platforms.

To come: Darwin x86/amd64 and removing the SETC flag from the guest state
(and its OFFSET).

coregrind/m_syswrap/syscall-amd64-freebsd.S
coregrind/m_syswrap/syscall-arm64-freebsd.S
coregrind/m_syswrap/syscall-x86-freebsd.S
coregrind/m_syswrap/syswrap-main.c

index 0d25efdccc86a7d98b357e0eb569f88681301964..22a0127957e25d71a67af70e1ef0c668d34fd71f 100644 (file)
@@ -69,7 +69,8 @@
                                  void* guest_state,            // rsi
                                  const vki_sigset_t *sysmask,  // rdx
                                  const vki_sigset_t *postmask, // rcx
-                                 Int sigsetSzB)                // r8
+                                  Int sigsetSzB,               // r8
+                                  UCHar *cflag)                        // r9
 */
 
 /* from vki_arch.h */
@@ -85,6 +86,7 @@ ML_(do_syscall_for_client_WRK):
    pushq %rdx  // -24(%rbp)  sysmask
    pushq %rcx  // -32(%rbp)  postmask
    pushq %r8   // -40(%rbp)  sigsetSzB
+   pushq %r9   // -48(%rbp)  cflag
 
 1: /* Even though we can't take a signal until the sigprocmask completes,
       start the range early.
@@ -132,23 +134,12 @@ ML_(do_syscall_for_client_WRK):
 3:   /* In the range [3, 4), the syscall result is in %rax,
       but hasn't been committed to RAX. */
 
-   /* stack contents: 3 words for syscall above, plus our prologue */
-   setc  0(%rsp)         /* stash returned carry flag */
 
-   movq  -16(%rbp), %r11 /* r11 = VexGuestAMD64State * */
+   movq  -16(%rbp), %r11                 /* r11 = VexGuestAMD64State * */
    movq  %rax, OFFSET_amd64_RAX(%r11)    /* save back to RAX */
    movq  %rdx, OFFSET_amd64_RDX(%r11)    /* save back to RDX */
-
-   /* save carry flag to VEX */
-   xorq  %rax, %rax
-   movb  0(%rsp), %al
-   movq  %rax, %rdi      /* arg1 = new flag */
-   movq  %r11, %rsi      /* arg2 = vex state */
-   addq  $24, %rsp       /* remove syscall parameters */
-   movl  $1, OFFSET_amd64_SETC(%r11)
-   call  LibVEX_GuestAMD64_put_rflag_c
-   movq  -16(%rbp), %r11 /* r11 = VexGuestAMD64State * */
-   movl  $0, OFFSET_amd64_SETC(%r11)
+   movq        -48(%rbp), %rcx
+   setc        0(%rcx)                          /* save returned carry flag */
 
 4: /* Re-block signals.  If eip is in [4,5), then the syscall
       is complete and we needn't worry about it. */
index fb7c687687c0885e598584bd9c99f9755d2bc8a0..3e01dc557e7579e145e8c52bee466a8b37489968 100644 (file)
@@ -67,7 +67,8 @@
               void* guest_state,             // x1
               const vki_sigset_t *sysmask,   // x2
               const vki_sigset_t *postmask,  // x3
-              Int nsigwords)                 // x4
+              Int nsigwords,                 // x4
+              UChar *cflag,                  // x5
 */
 /* from vki-arm64-freebsd.h */
 #define VKI_SIG_SETMASK 3
@@ -110,23 +111,15 @@ ML_(do_syscall_for_client_WRK):
 2: svc 0x00000000
 3:
 
-   /* stash returned carry flag */
-   mov x4, 1
-   csel x4, x4, xzr, cs
 
    ldr x5, [sp, #8] /* saved x1 == guest_state */
    str x0, [x5, #OFFSET_arm64_X0]
    str x1, [x5, #OFFSET_arm64_X1]
-
-   /* save carry flag to VEX */
-   mov x0, x4       /* arg1 = new flag */
-   ldr x1, [sp, #8] /* arg2 = vex state */
-   mov x20, 1
-   str x20, [x1, #OFFSET_arm64_SETC]
-   bl LibVEX_GuestARM64_put_nzcv_c
-   ldr x1, [sp, #8] /* arg2 = vex state */
-   mov x20, 0
-   str x20, [x1, #OFFSET_arm64_SETC]
+   /* stash returned carry flag */
+   mov x4, 1
+   csel x4, x4, xzr, cs
+   ldr  x5, [sp, #40] /* saved x5 == cflag */
+   strb w4, [x5]
 
 4:
    mov x8, #__NR_sigprocmask
index 9e69d85becde25e9901b4279f1ac96fcaa677eec..22fe6e6add33f195c704bb95d6b4810bd81709d7 100644 (file)
@@ -69,7 +69,8 @@
            void* guest_state,             // ebp+12
            const vki_sigset_t *sysmask,   // ebp+16
            const vki_sigset_t *postmask,  // ebp+20
-           Int sigsetSzB)                 // ebp+24
+           Int sigsetSzB,                 // ebp+24
+           UChar* cflag)                  // ebp+28
 
    Note that sigsetSzB is totally ignored (and irrelevant).
 */
@@ -133,21 +134,11 @@ ML_(do_syscall_for_client_WRK):
 
 3: /* In the range [3, 4), the syscall result is in %eax and %edx and C,
       but hasn't been committed to the thread state. */
-   setc  0(%esp)                               /* stash returned carry flag */
    movl  12(%ebp), %ecx
    movl  %eax, OFFSET_x86_EAX(%ecx)    /* save EAX to vex */
    movl  %edx, OFFSET_x86_EDX(%ecx)    /* save EDX to vex */
-   /* save carry flag to vex */
-   subl  $12, %esp
-   movl  %ecx, 4(%esp)
-   movl  $0, 0(%esp)
-   movb  12(%esp), %al
-   movb  %al, 0(%esp)
-   movl  $1, OFFSET_x86_SETC(%ecx)
-   call  LibVEX_GuestX86_put_eflag_c
-   movl  12(%ebp), %ecx
-   movl  $0, OFFSET_x86_SETC(%ecx)
-   addl  $12, %esp
+   movl         28(%ebp), %ecx
+   setc         0(%ecx)                        /* save returned carry flag */
 
 4: /* Re-block signals.  If eip is in [4,5), then the syscall is
       complete and we needn't worry about it. */
index c7dbd6b92f88fe3636eeef59b68ea6147cc78ff4..6f982998f8bc67e9ef70bfab155e1582840c2079 100644 (file)
@@ -302,11 +302,12 @@ UWord ML_(do_syscall_for_client_WRK)( Word syscallno,
                                       Word sigsetSzB );
 #elif defined(VGO_freebsd)
 extern
-UWord ML_(do_syscall_for_client_WRK)( Word syscallno, 
-                                      void* guest_state,
-                                      const vki_sigset_t *syscall_mask,
-                                      const vki_sigset_t *restore_mask,
-                                      Word sigsetSzB );
+UWord ML_(do_syscall_for_client_WRK)(Word syscallno,
+                                     void* guest_state,
+                                     const vki_sigset_t *syscall_mask,
+                                     const vki_sigset_t *restore_mask,
+                                     Word sigsetSzB,
+                                     UChar *cflag);
 #elif defined(VGO_darwin)
 extern
 UWord ML_(do_syscall_for_client_unix_WRK)( Word syscallno, 
@@ -357,6 +358,7 @@ void do_syscall_for_client ( Int syscallno,
          );
 #  elif defined(VGO_freebsd)
    Word real_syscallno;
+   UChar cflag;
    VG_(sigemptyset)(&saved);
    if (tst->arch.vex.guest_SC_CLASS == VG_FREEBSD_SYSCALL0)
       real_syscallno = __NR_syscall;
@@ -366,8 +368,20 @@ void do_syscall_for_client ( Int syscallno,
       real_syscallno = syscallno;
    err = ML_(do_syscall_for_client_WRK)(
             real_syscallno, &tst->arch.vex,
-            syscall_mask, &saved, sizeof(vki_sigset_t)
+            syscall_mask, &saved, sizeof(vki_sigset_t),
+            &cflag
          );
+   /* Save the carry flag. */
+#  if defined(VGP_amd64_freebsd)
+   LibVEX_GuestAMD64_put_rflag_c(cflag, &tst->arch.vex);
+
+#  elif defined(VGP_arm64_freebsd)
+   LibVEX_GuestARM64_put_nzcv_c(cflag, &tst->arch.vex);
+#  elif defined(VGP_x86_freebsd)
+   LibVEX_GuestX86_put_eflag_c(cflag, &tst->arch.vex);
+#  else
+#    error "Unknown platform"
+#  endif
 #  elif defined(VGO_darwin)
    switch (VG_DARWIN_SYSNO_CLASS(syscallno)) {
       case VG_DARWIN_SYSCALL_CLASS_UNIX: