Home | History | Annotate | Download | only in m_sigframe
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Create/destroy signal delivery frames.                       ---*/
      4 /*---                                         sigframe-x86-linux.c ---*/
      5 /*--------------------------------------------------------------------*/
      6 
      7 /*
      8    This file is part of Valgrind, a dynamic binary instrumentation
      9    framework.
     10 
     11    Copyright (C) 2000-2015 Nicholas Nethercote
     12       njn (at) valgrind.org
     13 
     14    This program is free software; you can redistribute it and/or
     15    modify it under the terms of the GNU General Public License as
     16    published by the Free Software Foundation; either version 2 of the
     17    License, or (at your option) any later version.
     18 
     19    This program is distributed in the hope that it will be useful, but
     20    WITHOUT ANY WARRANTY; without even the implied warranty of
     21    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     22    General Public License for more details.
     23 
     24    You should have received a copy of the GNU General Public License
     25    along with this program; if not, write to the Free Software
     26    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     27    02111-1307, USA.
     28 
     29    The GNU General Public License is contained in the file COPYING.
     30 */
     31 
     32 #if defined(VGP_x86_linux)
     33 
     34 #include "pub_core_basics.h"
     35 #include "pub_core_vki.h"
     36 #include "pub_core_threadstate.h"
     37 #include "pub_core_aspacemgr.h" /* find_segment */
     38 #include "pub_core_libcbase.h"
     39 #include "pub_core_libcassert.h"
     40 #include "pub_core_libcprint.h"
     41 #include "pub_core_machine.h"
     42 #include "pub_core_options.h"
     43 #include "pub_core_signals.h"
     44 #include "pub_core_tooliface.h"
     45 #include "pub_core_trampoline.h"
     46 #include "pub_core_sigframe.h"   /* self */
     47 #include "priv_sigframe.h"
     48 
     49 /* This module creates and removes signal frames for signal deliveries
     50    on x86-linux.
     51 
     52    Note, this file contains kernel-specific knowledge in the form of
     53    'struct sigframe' and 'struct rt_sigframe'.  How does that relate
     54    to the vki kernel interface stuff?
     55 
     56    Either a 'struct sigframe' or a 'struct rtsigframe' is pushed
     57    onto the client's stack.  This contains a subsidiary
     58    vki_ucontext.  That holds the vcpu's state across the signal,
     59    so that the sighandler can mess with the vcpu state if it
     60    really wants.
     61 
     62    FIXME: sigcontexting is basically broken for the moment.  When
     63    delivering a signal, the integer registers and %eflags are
     64    correctly written into the sigcontext, however the FP and SSE state
     65    is not.  When returning from a signal, only the integer registers
     66    are restored from the sigcontext; the rest of the CPU state is
     67    restored to what it was before the signal.
     68 
     69    This will be fixed.
     70 */
     71 
     72 
     73 /*------------------------------------------------------------*/
     74 /*--- Signal frame layouts                                 ---*/
     75 /*------------------------------------------------------------*/
     76 
     77 // A structure in which to save the application's registers
     78 // during the execution of signal handlers.
     79 
     80 // Linux has 2 signal frame structures: one for normal signal
     81 // deliveries, and one for SA_SIGINFO deliveries (also known as RT
     82 // signals).
     83 //
     84 // In theory, so long as we get the arguments to the handler function
     85 // right, it doesn't matter what the exact layout of the rest of the
     86 // frame is.  Unfortunately, things like gcc's exception unwinding
     87 // make assumptions about the locations of various parts of the frame,
     88 // so we need to duplicate it exactly.
     89 
     90 /* Valgrind-specific parts of the signal frame */
     91 struct vg_sigframe
     92 {
     93    /* Sanity check word. */
     94    UInt magicPI;
     95 
     96    UInt handlerflags;	/* flags for signal handler */
     97 
     98 
     99    /* Safely-saved version of sigNo, as described above. */
    100    Int  sigNo_private;
    101 
    102    /* XXX This is wrong.  Surely we should store the shadow values
    103       into the shadow memory behind the actual values? */
    104    VexGuestX86State vex_shadow1;
    105    VexGuestX86State vex_shadow2;
    106 
    107    /* HACK ALERT */
    108    VexGuestX86State vex;
    109    /* end HACK ALERT */
    110 
    111    /* saved signal mask to be restored when handler returns */
    112    vki_sigset_t	mask;
    113 
    114    /* Sanity check word.  Is the highest-addressed word; do not
    115       move!*/
    116    UInt magicE;
    117 };
    118 
    119 struct sigframe
    120 {
    121    /* Sig handler's return address */
    122    Addr retaddr;
    123    Int  sigNo;
    124 
    125    struct vki_sigcontext sigContext;
    126    struct _vki_fpstate fpstate;
    127 
    128    struct vg_sigframe vg;
    129 };
    130 
    131 struct rt_sigframe
    132 {
    133    /* Sig handler's return address */
    134    Addr retaddr;
    135    Int  sigNo;
    136 
    137    /* ptr to siginfo_t. */
    138    Addr psigInfo;
    139 
    140    /* ptr to ucontext */
    141    Addr puContext;
    142    /* pointed to by psigInfo */
    143    vki_siginfo_t sigInfo;
    144 
    145    /* pointed to by puContext */
    146    struct vki_ucontext uContext;
    147    struct _vki_fpstate fpstate;
    148 
    149    struct vg_sigframe vg;
    150 };
    151 
    152 
    153 //:: /*------------------------------------------------------------*/
    154 //:: /*--- Signal operations                                    ---*/
    155 //:: /*------------------------------------------------------------*/
    156 //::
    157 //:: /*
    158 //::    Great gobs of FP state conversion taken wholesale from
    159 //::    linux/arch/i386/kernel/i387.c
    160 //::  */
    161 //::
    162 //:: /*
    163 //::  * FXSR floating point environment conversions.
    164 //::  */
    165 //:: #define X86_FXSR_MAGIC		0x0000
    166 //::
    167 //:: /*
    168 //::  * FPU tag word conversions.
    169 //::  */
    170 //::
    171 //:: static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
    172 //:: {
    173 //::    unsigned int tmp; /* to avoid 16 bit prefixes in the code */
    174 //::
    175 //::    /* Transform each pair of bits into 01 (valid) or 00 (empty) */
    176 //::    tmp = ~twd;
    177 //::    tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
    178 //::    /* and move the valid bits to the lower byte. */
    179 //::    tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
    180 //::    tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
    181 //::    tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
    182 //::    return tmp;
    183 //:: }
    184 //::
    185 //:: static unsigned long twd_fxsr_to_i387( const struct i387_fxsave_struct *fxsave )
    186 //:: {
    187 //::    struct _vki_fpxreg *st = NULL;
    188 //::    unsigned long twd = (unsigned long) fxsave->twd;
    189 //::    unsigned long tag;
    190 //::    unsigned long ret = 0xffff0000u;
    191 //::    int i;
    192 //::
    193 //:: #define FPREG_ADDR(f, n)	((char *)&(f)->st_space + (n) * 16);
    194 //::
    195 //::    for ( i = 0 ; i < 8 ; i++ ) {
    196 //::       if ( twd & 0x1 ) {
    197 //:: 	 st = (struct _vki_fpxreg *) FPREG_ADDR( fxsave, i );
    198 //::
    199 //:: 	 switch ( st->exponent & 0x7fff ) {
    200 //:: 	 case 0x7fff:
    201 //:: 	    tag = 2;		/* Special */
    202 //:: 	    break;
    203 //:: 	 case 0x0000:
    204 //:: 	    if ( !st->significand[0] &&
    205 //:: 		 !st->significand[1] &&
    206 //:: 		 !st->significand[2] &&
    207 //:: 		 !st->significand[3] ) {
    208 //:: 	       tag = 1;	/* Zero */
    209 //:: 	    } else {
    210 //:: 	       tag = 2;	/* Special */
    211 //:: 	    }
    212 //:: 	    break;
    213 //:: 	 default:
    214 //:: 	    if ( st->significand[3] & 0x8000 ) {
    215 //:: 	       tag = 0;	/* Valid */
    216 //:: 	    } else {
    217 //:: 	       tag = 2;	/* Special */
    218 //:: 	    }
    219 //:: 	    break;
    220 //:: 	 }
    221 //::       } else {
    222 //:: 	 tag = 3;			/* Empty */
    223 //::       }
    224 //::       ret |= (tag << (2 * i));
    225 //::       twd = twd >> 1;
    226 //::    }
    227 //::    return ret;
    228 //:: }
    229 //::
    230 //:: static void convert_fxsr_to_user( struct _vki_fpstate *buf,
    231 //:: 				  const struct i387_fxsave_struct *fxsave )
    232 //:: {
    233 //::    unsigned long env[7];
    234 //::    struct _vki_fpreg *to;
    235 //::    struct _vki_fpxreg *from;
    236 //::    int i;
    237 //::
    238 //::    env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul;
    239 //::    env[1] = (unsigned long)fxsave->swd | 0xffff0000ul;
    240 //::    env[2] = twd_fxsr_to_i387(fxsave);
    241 //::    env[3] = fxsave->fip;
    242 //::    env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
    243 //::    env[5] = fxsave->foo;
    244 //::    env[6] = fxsave->fos;
    245 //::
    246 //::    VG_(memcpy)(buf, env, 7 * sizeof(unsigned long));
    247 //::
    248 //::    to = &buf->_st[0];
    249 //::    from = (struct _vki_fpxreg *) &fxsave->st_space[0];
    250 //::    for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
    251 //::       unsigned long __user *t = (unsigned long __user *)to;
    252 //::       unsigned long *f = (unsigned long *)from;
    253 //::
    254 //::       t[0] = f[0];
    255 //::       t[1] = f[1];
    256 //::       to->exponent = from->exponent;
    257 //::    }
    258 //:: }
    259 //::
    260 //:: static void convert_fxsr_from_user( struct i387_fxsave_struct *fxsave,
    261 //:: 				    const struct _vki_fpstate *buf )
    262 //:: {
    263 //::    unsigned long env[7];
    264 //::    struct _vki_fpxreg *to;
    265 //::    const struct _vki_fpreg *from;
    266 //::    int i;
    267 //::
    268 //::    VG_(memcpy)(env, buf, 7 * sizeof(long));
    269 //::
    270 //::    fxsave->cwd = (unsigned short)(env[0] & 0xffff);
    271 //::    fxsave->swd = (unsigned short)(env[1] & 0xffff);
    272 //::    fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
    273 //::    fxsave->fip = env[3];
    274 //::    fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16);
    275 //::    fxsave->fcs = (env[4] & 0xffff);
    276 //::    fxsave->foo = env[5];
    277 //::    fxsave->fos = env[6];
    278 //::
    279 //::    to = (struct _vki_fpxreg *) &fxsave->st_space[0];
    280 //::    from = &buf->_st[0];
    281 //::    for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
    282 //::       unsigned long *t = (unsigned long *)to;
    283 //::       unsigned long __user *f = (unsigned long __user *)from;
    284 //::
    285 //::       t[0] = f[0];
    286 //::       t[1] = f[1];
    287 //::       to->exponent = from->exponent;
    288 //::    }
    289 //:: }
    290 //::
    291 //:: static inline void save_i387_fsave( arch_thread_t *regs, struct _vki_fpstate *buf )
    292 //:: {
    293 //::    struct i387_fsave_struct *fs = &regs->m_sse.fsave;
    294 //::
    295 //::    fs->status = fs->swd;
    296 //::    VG_(memcpy)(buf, fs, sizeof(*fs));
    297 //:: }
    298 //::
    299 //:: static void save_i387_fxsave( arch_thread_t *regs, struct _vki_fpstate *buf )
    300 //:: {
    301 //::    const struct i387_fxsave_struct *fx = &regs->m_sse.fxsave;
    302 //::    convert_fxsr_to_user( buf, fx );
    303 //::
    304 //::    buf->status = fx->swd;
    305 //::    buf->magic = X86_FXSR_MAGIC;
    306 //::    VG_(memcpy)(buf->_fxsr_env, fx, sizeof(struct i387_fxsave_struct));
    307 //:: }
    308 //::
    309 //:: static void save_i387( arch_thread_t *regs, struct _vki_fpstate *buf )
    310 //:: {
    311 //::    if ( VG_(have_ssestate) )
    312 //::       save_i387_fxsave( regs, buf );
    313 //::    else
    314 //::       save_i387_fsave( regs, buf );
    315 //:: }
    316 //::
    317 //:: static inline void restore_i387_fsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
    318 //:: {
    319 //::    VG_(memcpy)( &regs->m_sse.fsave, buf, sizeof(struct i387_fsave_struct) );
    320 //:: }
    321 //::
    322 //:: static void restore_i387_fxsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
    323 //:: {
    324 //::    VG_(memcpy)(&regs->m_sse.fxsave, &buf->_fxsr_env[0],
    325 //:: 	       sizeof(struct i387_fxsave_struct) );
    326 //::    /* mxcsr reserved bits must be masked to zero for security reasons */
    327 //::    regs->m_sse.fxsave.mxcsr &= 0xffbf;
    328 //::    convert_fxsr_from_user( &regs->m_sse.fxsave, buf );
    329 //:: }
    330 //::
    331 //:: static void restore_i387( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
    332 //:: {
    333 //::    if ( VG_(have_ssestate) ) {
    334 //::       restore_i387_fxsave( regs, buf );
    335 //::    } else {
    336 //::       restore_i387_fsave( regs, buf );
    337 //::    }
    338 //:: }
    339 
    340 
    341 /*------------------------------------------------------------*/
    342 /*--- Creating signal frames                               ---*/
    343 /*------------------------------------------------------------*/
    344 
    345 /* Create a plausible-looking sigcontext from the thread's
    346    Vex guest state.  NOTE: does not fill in the FP or SSE
    347    bits of sigcontext at the moment.
    348 */
    349 static
    350 void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,
    351                     UWord trapno, UWord err, const vki_sigset_t *set,
    352                     struct vki_ucontext *uc, struct _vki_fpstate *fpstate)
    353 {
    354    ThreadState *tst = VG_(get_ThreadState)(tid);
    355    struct vki_sigcontext *sc = &uc->uc_mcontext;
    356 
    357    VG_(memset)(uc, 0, sizeof(*uc));
    358 
    359    uc->uc_flags = 0;
    360    uc->uc_link = 0;
    361    uc->uc_sigmask = *set;
    362    uc->uc_stack = tst->altstack;
    363    sc->fpstate = fpstate;
    364 
    365    // FIXME: save_i387(&tst->arch, fpstate);
    366 
    367 #  define SC2(reg,REG)  sc->reg = tst->arch.vex.guest_##REG
    368    SC2(gs,GS);
    369    SC2(fs,FS);
    370    SC2(es,ES);
    371    SC2(ds,DS);
    372 
    373    SC2(edi,EDI);
    374    SC2(esi,ESI);
    375    SC2(ebp,EBP);
    376    SC2(esp,ESP);
    377    SC2(ebx,EBX);
    378    SC2(edx,EDX);
    379    SC2(ecx,ECX);
    380    SC2(eax,EAX);
    381 
    382    SC2(eip,EIP);
    383    SC2(cs,CS);
    384    sc->eflags = LibVEX_GuestX86_get_eflags(&tst->arch.vex);
    385    SC2(ss,SS);
    386    /* XXX esp_at_signal */
    387    sc->trapno = trapno;
    388    sc->err = err;
    389 #  undef SC2
    390 
    391    sc->cr2 = (UInt)si->_sifields._sigfault._addr;
    392 }
    393 
    394 
    395 /* Build the Valgrind-specific part of a signal frame. */
    396 
    397 static void build_vg_sigframe(struct vg_sigframe *frame,
    398 			      ThreadState *tst,
    399 			      UInt flags,
    400 			      Int sigNo)
    401 {
    402    frame->sigNo_private = sigNo;
    403    frame->magicPI       = 0x31415927;
    404    frame->vex_shadow1   = tst->arch.vex_shadow1;
    405    frame->vex_shadow2   = tst->arch.vex_shadow2;
    406    /* HACK ALERT */
    407    frame->vex           = tst->arch.vex;
    408    /* end HACK ALERT */
    409    frame->mask          = tst->sig_mask;
    410    frame->handlerflags  = flags;
    411    frame->magicE        = 0x27182818;
    412 }
    413 
    414 
    415 static Addr build_sigframe(ThreadState *tst,
    416 			   Addr esp_top_of_frame,
    417 			   const vki_siginfo_t *siginfo,
    418                            const struct vki_ucontext *siguc,
    419 			   UInt flags,
    420 			   const vki_sigset_t *mask,
    421 			   void *restorer)
    422 {
    423    struct sigframe *frame;
    424    Addr esp = esp_top_of_frame;
    425    Int	sigNo = siginfo->si_signo;
    426    UWord trapno;
    427    UWord err;
    428    struct vki_ucontext uc;
    429 
    430    vg_assert((flags & VKI_SA_SIGINFO) == 0);
    431 
    432    esp -= sizeof(*frame);
    433    esp = VG_ROUNDDN(esp, 16);
    434    frame = (struct sigframe *)esp;
    435 
    436    if (! ML_(sf_maybe_extend_stack)(tst, esp, sizeof(*frame), flags))
    437       return esp_top_of_frame;
    438 
    439    /* retaddr, sigNo, siguContext fields are to be written */
    440    VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame",
    441 	     esp, offsetof(struct sigframe, vg) );
    442 
    443    frame->sigNo = sigNo;
    444 
    445    if (flags & VKI_SA_RESTORER)
    446       frame->retaddr = (Addr)restorer;
    447    else
    448       frame->retaddr = (Addr)&VG_(x86_linux_SUBST_FOR_sigreturn);
    449 
    450    if (siguc) {
    451       trapno = siguc->uc_mcontext.trapno;
    452       err = siguc->uc_mcontext.err;
    453    } else {
    454       trapno = 0;
    455       err = 0;
    456    }
    457 
    458    synth_ucontext(tst->tid, siginfo, trapno, err, mask, &uc, &frame->fpstate);
    459 
    460    VG_(memcpy)(&frame->sigContext, &uc.uc_mcontext,
    461 	       sizeof(struct vki_sigcontext));
    462    frame->sigContext.oldmask = mask->sig[0];
    463 
    464    VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
    465              esp, offsetof(struct sigframe, vg) );
    466 
    467    build_vg_sigframe(&frame->vg, tst, flags, sigNo);
    468 
    469    return esp;
    470 }
    471 
    472 
    473 static Addr build_rt_sigframe(ThreadState *tst,
    474 			      Addr esp_top_of_frame,
    475 			      const vki_siginfo_t *siginfo,
    476                               const struct vki_ucontext *siguc,
    477 			      UInt flags,
    478 			      const vki_sigset_t *mask,
    479 			      void *restorer)
    480 {
    481    struct rt_sigframe *frame;
    482    Addr esp = esp_top_of_frame;
    483    Int	sigNo = siginfo->si_signo;
    484    UWord trapno;
    485    UWord err;
    486 
    487    vg_assert((flags & VKI_SA_SIGINFO) != 0);
    488 
    489    esp -= sizeof(*frame);
    490    esp = VG_ROUNDDN(esp, 16);
    491    frame = (struct rt_sigframe *)esp;
    492 
    493    if (! ML_(sf_maybe_extend_stack)(tst, esp, sizeof(*frame), flags))
    494       return esp_top_of_frame;
    495 
    496    /* retaddr, sigNo, pSiginfo, puContext fields are to be written */
    497    VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "rt signal handler frame",
    498 	     esp, offsetof(struct rt_sigframe, vg) );
    499 
    500    frame->sigNo = sigNo;
    501 
    502    if (flags & VKI_SA_RESTORER)
    503       frame->retaddr = (Addr)restorer;
    504    else
    505       frame->retaddr = (Addr)&VG_(x86_linux_SUBST_FOR_rt_sigreturn);
    506 
    507    if (siguc) {
    508       trapno = siguc->uc_mcontext.trapno;
    509       err = siguc->uc_mcontext.err;
    510    } else {
    511       trapno = 0;
    512       err = 0;
    513    }
    514 
    515    frame->psigInfo = (Addr)&frame->sigInfo;
    516    frame->puContext = (Addr)&frame->uContext;
    517    VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
    518 
    519    /* SIGILL defines addr to be the faulting address */
    520    if (sigNo == VKI_SIGILL && siginfo->si_code > 0)
    521       frame->sigInfo._sifields._sigfault._addr
    522          = (void*)tst->arch.vex.guest_EIP;
    523 
    524    synth_ucontext(tst->tid, siginfo, trapno, err, mask,
    525                   &frame->uContext, &frame->fpstate);
    526 
    527    VG_TRACK( post_mem_write,  Vg_CoreSignal, tst->tid,
    528              esp, offsetof(struct rt_sigframe, vg) );
    529 
    530    build_vg_sigframe(&frame->vg, tst, flags, sigNo);
    531 
    532    return esp;
    533 }
    534 
    535 
    536 /* EXPORTED */
    537 void VG_(sigframe_create)( ThreadId tid,
    538                            Bool on_altstack,
    539                            Addr esp_top_of_frame,
    540                            const vki_siginfo_t *siginfo,
    541                            const struct vki_ucontext *siguc,
    542                            void *handler,
    543                            UInt flags,
    544                            const vki_sigset_t *mask,
    545 		           void *restorer )
    546 {
    547    Addr		esp;
    548    ThreadState* tst = VG_(get_ThreadState)(tid);
    549 
    550    if (flags & VKI_SA_SIGINFO)
    551       esp = build_rt_sigframe(tst, esp_top_of_frame, siginfo, siguc,
    552                                    flags, mask, restorer);
    553    else
    554       esp = build_sigframe(tst, esp_top_of_frame, siginfo, siguc,
    555                                 flags, mask, restorer);
    556 
    557    /* Set the thread so it will next run the handler. */
    558    /* tst->m_esp  = esp;  also notify the tool we've updated ESP */
    559    VG_(set_SP)(tid, esp);
    560    VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr));
    561 
    562    //VG_(printf)("handler = %p\n", handler);
    563    tst->arch.vex.guest_EIP = (Addr) handler;
    564    /* This thread needs to be marked runnable, but we leave that the
    565       caller to do. */
    566 
    567    if (0)
    568       VG_(printf)("pushed signal frame; %%ESP now = %#lx, "
    569                   "next %%EIP = %#x, status=%d\n",
    570 		  esp, tst->arch.vex.guest_EIP, (Int)tst->status);
    571 }
    572 
    573 
    574 /*------------------------------------------------------------*/
    575 /*--- Destroying signal frames                             ---*/
    576 /*------------------------------------------------------------*/
    577 
    578 /* Return False and don't do anything, just set the client to take a
    579    segfault, if it looks like the frame is corrupted. */
    580 static
    581 Bool restore_vg_sigframe ( ThreadState *tst,
    582                            struct vg_sigframe *frame, Int *sigNo )
    583 {
    584    if (frame->magicPI != 0x31415927 ||
    585        frame->magicE  != 0x27182818) {
    586       VG_(message)(Vg_UserMsg, "Thread %u return signal frame "
    587                                "corrupted.  Killing process.\n",
    588 		   tst->tid);
    589       VG_(set_default_handler)(VKI_SIGSEGV);
    590       VG_(synth_fault)(tst->tid);
    591       *sigNo = VKI_SIGSEGV;
    592       return False;
    593    }
    594    tst->sig_mask         = frame->mask;
    595    tst->tmp_sig_mask     = frame->mask;
    596    tst->arch.vex_shadow1 = frame->vex_shadow1;
    597    tst->arch.vex_shadow2 = frame->vex_shadow2;
    598    /* HACK ALERT */
    599    tst->arch.vex         = frame->vex;
    600    /* end HACK ALERT */
    601    *sigNo                = frame->sigNo_private;
    602    return True;
    603 }
    604 
    605 static
    606 void restore_sigcontext( ThreadState *tst,
    607                          struct vki_sigcontext *sc,
    608                          struct _vki_fpstate *fpstate )
    609 {
    610    tst->arch.vex.guest_EAX     = sc->eax;
    611    tst->arch.vex.guest_ECX     = sc->ecx;
    612    tst->arch.vex.guest_EDX     = sc->edx;
    613    tst->arch.vex.guest_EBX     = sc->ebx;
    614    tst->arch.vex.guest_EBP     = sc->ebp;
    615    tst->arch.vex.guest_ESP     = sc->esp;
    616    tst->arch.vex.guest_ESI     = sc->esi;
    617    tst->arch.vex.guest_EDI     = sc->edi;
    618 //::    tst->arch.vex.guest_eflags  = sc->eflags;
    619    tst->arch.vex.guest_EIP     = sc->eip;
    620    tst->arch.vex.guest_CS      = sc->cs;
    621    tst->arch.vex.guest_SS      = sc->ss;
    622    tst->arch.vex.guest_DS      = sc->ds;
    623    tst->arch.vex.guest_ES      = sc->es;
    624    tst->arch.vex.guest_FS      = sc->fs;
    625    tst->arch.vex.guest_GS      = sc->gs;
    626 
    627 //::    restore_i387(&tst->arch, fpstate);
    628 }
    629 
    630 
    631 static
    632 SizeT restore_sigframe ( ThreadState *tst,
    633                          struct sigframe *frame, Int *sigNo )
    634 {
    635    if (restore_vg_sigframe(tst, &frame->vg, sigNo))
    636       restore_sigcontext(tst, &frame->sigContext, &frame->fpstate);
    637 
    638    return sizeof(*frame);
    639 }
    640 
    641 static
    642 SizeT restore_rt_sigframe ( ThreadState *tst,
    643                             struct rt_sigframe *frame, Int *sigNo )
    644 {
    645    if (restore_vg_sigframe(tst, &frame->vg, sigNo))
    646       restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate);
    647 
    648    return sizeof(*frame);
    649 }
    650 
    651 
    652 /* EXPORTED */
    653 void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
    654 {
    655    Addr          esp;
    656    ThreadState*  tst;
    657    SizeT	 size;
    658    Int		 sigNo;
    659 
    660    tst = VG_(get_ThreadState)(tid);
    661 
    662    /* Correctly reestablish the frame base address. */
    663    esp   = tst->arch.vex.guest_ESP;
    664 
    665    if (!isRT)
    666       size = restore_sigframe(tst, (struct sigframe *)esp, &sigNo);
    667    else
    668       size = restore_rt_sigframe(tst, (struct rt_sigframe *)esp, &sigNo);
    669 
    670    VG_TRACK( die_mem_stack_signal, esp - VG_STACK_REDZONE_SZB,
    671              size + VG_STACK_REDZONE_SZB );
    672 
    673    if (VG_(clo_trace_signals))
    674       VG_(message)(
    675          Vg_DebugMsg,
    676          "VG_(signal_return) (thread %u): isRT=%d valid magic; EIP=%#x\n",
    677          tid, isRT, tst->arch.vex.guest_EIP);
    678 
    679    /* tell the tools */
    680    VG_TRACK( post_deliver_signal, tid, sigNo );
    681 }
    682 
    683 #endif // defined(VGP_x86_linux)
    684 
    685 /*--------------------------------------------------------------------*/
    686 /*--- end                                                          ---*/
    687 /*--------------------------------------------------------------------*/
    688