PERFORCE change 168154 for review

Stanislav Sedov stas at FreeBSD.org
Fri Sep 4 12:57:59 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=168154

Change 168154 by stas at 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


More information about the p4-projects mailing list