From 714fec1a92591bcd07454ebcb755c049f5c66a9f Mon Sep 17 00:00:00 2001 From: Paul Floyd Date: Wed, 29 Oct 2025 19:50:05 +0100 Subject: [PATCH] Bug 511329 - Darwin and FreeBSD: Move setting of carry flag out of ML_(do_syscall_for_client_WRK) part 1 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 | 21 +++++------------ coregrind/m_syswrap/syscall-arm64-freebsd.S | 21 ++++++----------- coregrind/m_syswrap/syscall-x86-freebsd.S | 17 ++++---------- coregrind/m_syswrap/syswrap-main.c | 26 ++++++++++++++++----- 4 files changed, 37 insertions(+), 48 deletions(-) diff --git a/coregrind/m_syswrap/syscall-amd64-freebsd.S b/coregrind/m_syswrap/syscall-amd64-freebsd.S index 0d25efdcc..22a012795 100644 --- a/coregrind/m_syswrap/syscall-amd64-freebsd.S +++ b/coregrind/m_syswrap/syscall-amd64-freebsd.S @@ -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. */ diff --git a/coregrind/m_syswrap/syscall-arm64-freebsd.S b/coregrind/m_syswrap/syscall-arm64-freebsd.S index fb7c68768..3e01dc557 100644 --- a/coregrind/m_syswrap/syscall-arm64-freebsd.S +++ b/coregrind/m_syswrap/syscall-arm64-freebsd.S @@ -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 diff --git a/coregrind/m_syswrap/syscall-x86-freebsd.S b/coregrind/m_syswrap/syscall-x86-freebsd.S index 9e69d85be..22fe6e6ad 100644 --- a/coregrind/m_syswrap/syscall-x86-freebsd.S +++ b/coregrind/m_syswrap/syscall-x86-freebsd.S @@ -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. */ diff --git a/coregrind/m_syswrap/syswrap-main.c b/coregrind/m_syswrap/syswrap-main.c index c7dbd6b92..6f982998f 100644 --- a/coregrind/m_syswrap/syswrap-main.c +++ b/coregrind/m_syswrap/syswrap-main.c @@ -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: -- 2.47.3