From owner-p4-projects@FreeBSD.ORG Tue Aug 21 00:30:29 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 1936B16A469; Tue, 21 Aug 2007 00:30:29 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E313716A421 for ; Tue, 21 Aug 2007 00:30:28 +0000 (UTC) (envelope-from peter@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id D3B2013C4A5 for ; Tue, 21 Aug 2007 00:30:28 +0000 (UTC) (envelope-from peter@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id l7L0USE3014942 for ; Tue, 21 Aug 2007 00:30:28 GMT (envelope-from peter@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id l7L0USiP014939 for perforce@freebsd.org; Tue, 21 Aug 2007 00:30:28 GMT (envelope-from peter@freebsd.org) Date: Tue, 21 Aug 2007 00:30:28 GMT Message-Id: <200708210030.l7L0USiP014939@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to peter@freebsd.org using -f From: Peter Wemm To: Perforce Change Reviews Cc: Subject: PERFORCE change 125471 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 21 Aug 2007 00:30:29 -0000 http://perforce.freebsd.org/chv.cgi?CH=125471 Change 125471 by peter@peter_cheese on 2007/08/21 00:29:48 Hopefully solve the stack smashing problem with async syscalls. Change putSyscallArgsIntoGuestState() into a NOP for FreeBSD. On linux, this is harmless because it just writes into the VEX register state, and the syscalls are defined to trash all registers anyway. For FreeBSD, args are on the stack. We'd have to memcpy the new args over the stack frame belonging to the syscall's caller, which the compiler may expect to use later to restore registers (which is entirely reasonable). Pass &sci->args as an additional parameters to do_syscall_for_client() rather than putSyscallArgsIntoGuestState(). Affected files ... .. //depot/projects/valgrind/coregrind/m_syswrap/syscall-x86-freebsd.S#2 edit .. //depot/projects/valgrind/coregrind/m_syswrap/syswrap-main.c#3 edit Differences ... ==== //depot/projects/valgrind/coregrind/m_syswrap/syscall-x86-freebsd.S#2 (text+ko) ==== @@ -67,7 +67,23 @@ void* guest_state, // 4 const vki_sigset_t *sysmask, // 8 const vki_sigset_t *postmask, // 12 - Int nsigwords) // 16 + Int nsigwords, // 16 + SyscallArgs *args) // 20 + +See priv_types_n_macros.h for SyscallArgs layout: + UWord sysno; // 0 + UWord arg1; // 4 + UWord arg2; // 8 + UWord arg3; // 12 + UWord arg4; // 16 + UWord arg5; // 20 + UWord arg6; // 24 +#ifdef VGO_freebsd + UWord arg7; // 28 + UWord arg8; // 32 + Word indir_sysno; // 36 (-1 if indirect syscall() or __syscall()) + UWord nargs; // 40 +#endif */ @@ -101,8 +117,7 @@ jb 7f /* sigprocmask failed */ /* We have already collapsed the stupid FreeBSD/i386 indirect syscalls */ - movl 4+FSZ(%esp), %eax /* eax == ThreadState * */ - movl OFFSET_x86_ESP(%eax), %ebx + movl 20+FSZ(%esp), %ebx movl 0+FSZ(%esp), %eax /* use syscallno argument rather than thread EAX */ /* copy 8 args */ movl 4(%ebx), %ecx ==== //depot/projects/valgrind/coregrind/m_syswrap/syswrap-main.c#3 (text+ko) ==== @@ -227,18 +227,20 @@ void* guest_state, const vki_sigset_t *syscall_mask, const vki_sigset_t *restore_mask, - Int nsigwords ); + Int nsigwords, SyscallArgs *args ); static void do_syscall_for_client ( Int syscallno, ThreadState* tst, - const vki_sigset_t* syscall_mask ) + const vki_sigset_t* syscall_mask, + SyscallArgs * args ) { vki_sigset_t saved; UWord err = ML_(do_syscall_for_client_WRK)( syscallno, &tst->arch.vex, - syscall_mask, &saved, _VKI_NSIG_WORDS * sizeof(UWord) + syscall_mask, &saved, _VKI_NSIG_WORDS * sizeof(UWord), + args ); vg_assert2( err == 0, @@ -411,8 +413,7 @@ gst->guest_EDI = canonical->arg5; gst->guest_EBP = canonical->arg6; -// AAA: missing 7th arg for freebsd/amd64 -#elif defined(VGP_amd64_linux) || defined(VGP_amd64_freebsd) +#elif defined(VGP_amd64_linux) VexGuestAMD64State* gst = (VexGuestAMD64State*)gst_vanilla; gst->guest_RAX = canonical->sysno; gst->guest_RDI = canonical->arg1; @@ -442,11 +443,9 @@ gst->guest_GPR7 = canonical->arg5; gst->guest_GPR8 = canonical->arg6; -#elif defined(VGP_x86_freebsd) - VexGuestX86State* gst = (VexGuestX86State*)gst_vanilla; - UWord *argv = (void *)(UWord)gst->guest_ESP; - gst->guest_EAX = canonical->sysno; - memcpy(&argv[1], &canonical->arg1, canonical->nargs * sizeof(UWord)); +#elif defined(VGP_x86_freebsd) || defined(VGP_amd64_freebsd) + /* Nothing. Uses args passed out of band. */ +#endif #else # error "putSyscallArgsIntoGuestState: unknown arch" @@ -905,6 +904,10 @@ /* Gack. More impedance matching. Copy the possibly modified syscall args back into the guest state. */ vg_assert(eq_SyscallArgs(&sci->args, &sci->orig_args)); + /* This is a NOP on FreeBSD - syscall args came from + the user's private stack. We can't change it because + the compiler sometimes expects to restore registers + after the call returns. */ putSyscallArgsIntoGuestState( &sci->args, &tst->arch.vex ); /* Drop the lock */ @@ -912,7 +915,7 @@ /* Do the call, which operates directly on the guest state, not on our abstracted copies of the args/result. */ - do_syscall_for_client(sysno, tst, &mask); + do_syscall_for_client(sysno, tst, &mask, &sci->args); /* do_syscall_for_client may not return if the syscall was interrupted by a signal. In that case, flow of control is