From owner-p4-projects@FreeBSD.ORG Fri Sep 4 12:57:59 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id CFB9B1065676; Fri, 4 Sep 2009 12:57:58 +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 7AF8C1065670 for ; Fri, 4 Sep 2009 12:57:58 +0000 (UTC) (envelope-from stas@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 6978C8FC15 for ; Fri, 4 Sep 2009 12:57:58 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n84Cvw4H062901 for ; Fri, 4 Sep 2009 12:57:58 GMT (envelope-from stas@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n84CvwqH062899 for perforce@freebsd.org; Fri, 4 Sep 2009 12:57:58 GMT (envelope-from stas@freebsd.org) Date: Fri, 4 Sep 2009 12:57:58 GMT Message-Id: <200909041257.n84CvwqH062899@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to stas@freebsd.org using -f From: Stanislav Sedov To: Perforce Change Reviews Cc: Subject: PERFORCE change 168154 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: Fri, 04 Sep 2009 12:57:59 -0000 http://perforce.freebsd.org/chv.cgi?CH=168154 Change 168154 by stas@stas_yandex on 2009/09/04 12:57:35 - Fix signals on x86. Affected files ... .. //depot/projects/valgrind/coregrind/m_sigframe/sigframe-x86-freebsd.c#6 edit .. //depot/projects/valgrind/coregrind/m_trampoline.S#8 edit Differences ... ==== //depot/projects/valgrind/coregrind/m_sigframe/sigframe-x86-freebsd.c#6 (text+ko) ==== @@ -46,20 +46,8 @@ #include "pub_core_sigframe.h" /* self */ -#warning Needs love! - - /* This module creates and removes signal frames for signal deliveries on x86-freebsd. - - FIXME: sigcontexting is basically broken for the moment. When - delivering a signal, the integer registers and %eflags are - correctly written into the sigcontext, however the FP and SSE state - is not. When returning from a signal, only the integer registers - are restored from the sigcontext; the rest of the CPU state is - restored to what it was before the signal. - - This should be fixed. */ @@ -109,9 +97,18 @@ { /* Sig handler's return address */ Addr retaddr; + Int sigNo; + Addr psigInfo; /* code or pointer to sigContext */ + Addr puContext; /* points to uContext */ + Addr addr; /* "secret" 4th argument */ + Addr phandler; /* "action" or "handler" */ + + /* pointed to by puContext */ + struct vki_ucontext uContext; - struct vki_sigcontext sigContext; + vki_siginfo_t sigInfo; + struct _vki_fpstate fpstate; struct vg_sigframe vg; @@ -123,8 +120,7 @@ /*------------------------------------------------------------*/ /* Create a plausible-looking sigcontext from the thread's - Vex guest state. NOTE: does not fill in the FP or SSE - bits of sigcontext at the moment. + Vex guest state. */ static void synth_ucontext(ThreadId tid, const vki_siginfo_t *si, @@ -142,8 +138,6 @@ uc->uc_stack = tst->altstack; VG_(memcpy)(&sc->fpstate, fpstate, sizeof(*fpstate)); - // FIXME: save_i387(&tst->arch, fpstate); - # define SC2(reg,REG) sc->reg = tst->arch.vex.guest_##REG SC2(gs,GS); SC2(fs,FS); @@ -163,9 +157,12 @@ SC2(cs,CS); sc->eflags = LibVEX_GuestX86_get_eflags(&tst->arch.vex); SC2(ss,SS); - /* XXX esp_at_signal */ sc->trapno = trapno; sc->err = err; +// sc->addr = (UWord)si->si_addr; + sc->fpformat = VKI_FPFMT_NODEV; + sc->len = sizeof(*sc); + sc->ownedfp = VKI_FPOWNED_NONE; # undef SC2 // sc->cr2 = (UInt)si->_sifields._sigfault._addr; @@ -220,6 +217,7 @@ static void build_vg_sigframe(struct vg_sigframe *frame, ThreadState *tst, + const vki_sigset_t *mask, UInt flags, Int sigNo) { @@ -235,21 +233,19 @@ frame->magicE = 0x27182818; } - static Addr build_sigframe(ThreadState *tst, - Addr esp_top_of_frame, - const vki_siginfo_t *siginfo, - const struct vki_ucontext *siguc, - UInt flags, - const vki_sigset_t *mask, - void *restorer) + Addr esp_top_of_frame, + const vki_siginfo_t *siginfo, + const struct vki_ucontext *siguc, + void *handler, UInt flags, + const vki_sigset_t *mask, + void *restorer) { struct sigframe *frame; Addr esp = esp_top_of_frame; - Int sigNo = siginfo->si_signo; + Int sigNo = siginfo->si_signo; UWord trapno; UWord err; - struct vki_ucontext uc; esp -= sizeof(*frame); esp = VG_ROUNDDN(esp, 16); @@ -258,37 +254,35 @@ if (!extend(tst, esp, sizeof(*frame))) return esp_top_of_frame; - /* retaddr, sigNo, siguContext fields are to be written */ - VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame", - esp, offsetof(struct sigframe, vg) ); + /* retaddr, siginfo, uContext fields are to be written */ + VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame", + esp, offsetof(struct sigframe, vg) ); frame->sigNo = sigNo; - frame->retaddr = (Addr)&VG_(x86_freebsd_SUBST_FOR_sigreturn); + if ((flags & VKI_SA_SIGINFO) == 0) + frame->psigInfo = (Addr)siginfo->si_code; + else + frame->psigInfo = (Addr)&frame->sigInfo; + VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t)); - if (siguc) { - trapno = siguc->uc_mcontext.trapno; - err = siguc->uc_mcontext.err; - } else { - trapno = 0; - err = 0; - } + trapno = siguc->uc_mcontext.trapno; + err = siguc->uc_mcontext.err; - synth_ucontext(tst->tid, siginfo, trapno, err, mask, &uc, &frame->fpstate); + synth_ucontext(tst->tid, siginfo, trapno, err, mask, + &frame->uContext, &frame->fpstate); - VG_(memcpy)(&frame->sigContext, &uc.uc_mcontext, - sizeof(struct vki_sigcontext)); -// frame->sigContext.oldmask = mask->sig[0]; + if (sigNo == VKI_SIGILL && siginfo->si_code > 0) + frame->sigInfo.si_addr = (void*)tst->arch.vex.guest_EIP; - VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, + VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, esp, offsetof(struct sigframe, vg) ); - build_vg_sigframe(&frame->vg, tst, flags, sigNo); - + build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo); + return esp; } - /* EXPORTED */ void VG_(sigframe_create)( ThreadId tid, Addr esp_top_of_frame, @@ -302,7 +296,7 @@ Addr esp; ThreadState* tst = VG_(get_ThreadState)(tid); - esp = build_sigframe(tst, esp_top_of_frame, siginfo, siguc, + esp = build_sigframe(tst, esp_top_of_frame, siginfo, siguc, handler, flags, mask, restorer); /* Set the thread so it will next run the handler. */ @@ -310,8 +304,8 @@ VG_(set_SP)(tid, esp); VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr)); - //VG_(printf)("handler = %p\n", handler); tst->arch.vex.guest_EIP = (Addr) handler; +// tst->arch.vex.guest_EDI = (ULong) siginfo->si_signo; /* This thread needs to be marked runnable, but we leave that the caller to do. */ @@ -335,8 +329,7 @@ if (frame->magicPI != 0x31415927 || frame->magicE != 0x27182818) { VG_(message)(Vg_UserMsg, "Thread %d return signal frame " - "corrupted. Killing process.\n", - tst->tid); + "corrupted. Killing process.", tst->tid); VG_(set_default_handler)(VKI_SIGSEGV); VG_(synth_fault)(tst->tid); *sigNo = VKI_SIGSEGV; @@ -355,7 +348,7 @@ static void restore_sigcontext( ThreadState *tst, - struct vki_sigcontext *sc, + struct vki_mcontext *sc, struct _vki_fpstate *fpstate ) { tst->arch.vex.guest_EAX = sc->eax; @@ -374,8 +367,7 @@ tst->arch.vex.guest_ES = sc->es; tst->arch.vex.guest_FS = sc->fs; tst->arch.vex.guest_GS = sc->gs; - -//:: restore_i387(&tst->arch, fpstate); + VG_(memcpy)(fpstate, &sc->fpstate, sizeof(*fpstate)); } @@ -384,7 +376,7 @@ struct sigframe *frame, Int *sigNo ) { if (restore_vg_sigframe(tst, &frame->vg, sigNo)) - restore_sigcontext(tst, &frame->sigContext, &frame->fpstate); + restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate); return sizeof(*frame); } @@ -401,6 +393,7 @@ /* Correctly reestablish the frame base address. */ esp = tst->arch.vex.guest_ESP; + esp += 8; /* Clean up stack from argument/ret passed to sigreturn(2) */ size = restore_sigframe(tst, (struct sigframe *)esp, &sigNo); ==== //depot/projects/valgrind/coregrind/m_trampoline.S#8 (text+ko) ==== @@ -788,8 +788,6 @@ .global VG_(trampoline_stuff_start) VG_(trampoline_stuff_start): -// AAA check for 64 bit correctness here. also, assumes linux style syscall -// args where sigframe is top-of-stack, not a pointer as an argument .global VG_(amd64_freebsd_SUBST_FOR_sigreturn) VG_(amd64_freebsd_SUBST_FOR_sigreturn): /* This is a very specific sequence which GDB uses to