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 */
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.
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. */
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
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
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).
*/
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. */
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,
);
# 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;
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: