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-2013 Nicholas Nethercote
12       njn@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
synth_ucontext(ThreadId tid,const vki_siginfo_t * si,UWord trapno,UWord err,const vki_sigset_t * set,struct vki_ucontext * uc,struct _vki_fpstate * fpstate)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 
build_vg_sigframe(struct vg_sigframe * frame,ThreadState * tst,UInt flags,Int sigNo)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 
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)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 
build_rt_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)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 */
VG_(sigframe_create)537 void VG_(sigframe_create)( ThreadId tid,
538                            Addr esp_top_of_frame,
539                            const vki_siginfo_t *siginfo,
540                            const struct vki_ucontext *siguc,
541                            void *handler,
542                            UInt flags,
543                            const vki_sigset_t *mask,
544 		           void *restorer )
545 {
546    Addr		esp;
547    ThreadState* tst = VG_(get_ThreadState)(tid);
548 
549    if (flags & VKI_SA_SIGINFO)
550       esp = build_rt_sigframe(tst, esp_top_of_frame, siginfo, siguc,
551                                    flags, mask, restorer);
552    else
553       esp = build_sigframe(tst, esp_top_of_frame, siginfo, siguc,
554                                 flags, mask, restorer);
555 
556    /* Set the thread so it will next run the handler. */
557    /* tst->m_esp  = esp;  also notify the tool we've updated ESP */
558    VG_(set_SP)(tid, esp);
559    VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr));
560 
561    //VG_(printf)("handler = %p\n", handler);
562    tst->arch.vex.guest_EIP = (Addr) handler;
563    /* This thread needs to be marked runnable, but we leave that the
564       caller to do. */
565 
566    if (0)
567       VG_(printf)("pushed signal frame; %%ESP now = %#lx, "
568                   "next %%EIP = %#x, status=%d\n",
569 		  esp, tst->arch.vex.guest_EIP, tst->status);
570 }
571 
572 
573 /*------------------------------------------------------------*/
574 /*--- Destroying signal frames                             ---*/
575 /*------------------------------------------------------------*/
576 
577 /* Return False and don't do anything, just set the client to take a
578    segfault, if it looks like the frame is corrupted. */
579 static
restore_vg_sigframe(ThreadState * tst,struct vg_sigframe * frame,Int * sigNo)580 Bool restore_vg_sigframe ( ThreadState *tst,
581                            struct vg_sigframe *frame, Int *sigNo )
582 {
583    if (frame->magicPI != 0x31415927 ||
584        frame->magicE  != 0x27182818) {
585       VG_(message)(Vg_UserMsg, "Thread %d return signal frame "
586                                "corrupted.  Killing process.\n",
587 		   tst->tid);
588       VG_(set_default_handler)(VKI_SIGSEGV);
589       VG_(synth_fault)(tst->tid);
590       *sigNo = VKI_SIGSEGV;
591       return False;
592    }
593    tst->sig_mask         = frame->mask;
594    tst->tmp_sig_mask     = frame->mask;
595    tst->arch.vex_shadow1 = frame->vex_shadow1;
596    tst->arch.vex_shadow2 = frame->vex_shadow2;
597    /* HACK ALERT */
598    tst->arch.vex         = frame->vex;
599    /* end HACK ALERT */
600    *sigNo                = frame->sigNo_private;
601    return True;
602 }
603 
604 static
restore_sigcontext(ThreadState * tst,struct vki_sigcontext * sc,struct _vki_fpstate * fpstate)605 void restore_sigcontext( ThreadState *tst,
606                          struct vki_sigcontext *sc,
607                          struct _vki_fpstate *fpstate )
608 {
609    tst->arch.vex.guest_EAX     = sc->eax;
610    tst->arch.vex.guest_ECX     = sc->ecx;
611    tst->arch.vex.guest_EDX     = sc->edx;
612    tst->arch.vex.guest_EBX     = sc->ebx;
613    tst->arch.vex.guest_EBP     = sc->ebp;
614    tst->arch.vex.guest_ESP     = sc->esp;
615    tst->arch.vex.guest_ESI     = sc->esi;
616    tst->arch.vex.guest_EDI     = sc->edi;
617 //::    tst->arch.vex.guest_eflags  = sc->eflags;
618    tst->arch.vex.guest_EIP     = sc->eip;
619    tst->arch.vex.guest_CS      = sc->cs;
620    tst->arch.vex.guest_SS      = sc->ss;
621    tst->arch.vex.guest_DS      = sc->ds;
622    tst->arch.vex.guest_ES      = sc->es;
623    tst->arch.vex.guest_FS      = sc->fs;
624    tst->arch.vex.guest_GS      = sc->gs;
625 
626 //::    restore_i387(&tst->arch, fpstate);
627 }
628 
629 
630 static
restore_sigframe(ThreadState * tst,struct sigframe * frame,Int * sigNo)631 SizeT restore_sigframe ( ThreadState *tst,
632                          struct sigframe *frame, Int *sigNo )
633 {
634    if (restore_vg_sigframe(tst, &frame->vg, sigNo))
635       restore_sigcontext(tst, &frame->sigContext, &frame->fpstate);
636 
637    return sizeof(*frame);
638 }
639 
640 static
restore_rt_sigframe(ThreadState * tst,struct rt_sigframe * frame,Int * sigNo)641 SizeT restore_rt_sigframe ( ThreadState *tst,
642                             struct rt_sigframe *frame, Int *sigNo )
643 {
644    if (restore_vg_sigframe(tst, &frame->vg, sigNo))
645       restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate);
646 
647    return sizeof(*frame);
648 }
649 
650 
651 /* EXPORTED */
VG_(sigframe_destroy)652 void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
653 {
654    Addr          esp;
655    ThreadState*  tst;
656    SizeT	 size;
657    Int		 sigNo;
658 
659    tst = VG_(get_ThreadState)(tid);
660 
661    /* Correctly reestablish the frame base address. */
662    esp   = tst->arch.vex.guest_ESP;
663 
664    if (!isRT)
665       size = restore_sigframe(tst, (struct sigframe *)esp, &sigNo);
666    else
667       size = restore_rt_sigframe(tst, (struct rt_sigframe *)esp, &sigNo);
668 
669    VG_TRACK( die_mem_stack_signal, esp - VG_STACK_REDZONE_SZB,
670              size + VG_STACK_REDZONE_SZB );
671 
672    if (VG_(clo_trace_signals))
673       VG_(message)(
674          Vg_DebugMsg,
675          "VG_(signal_return) (thread %d): isRT=%d valid magic; EIP=%#x\n",
676          tid, isRT, tst->arch.vex.guest_EIP);
677 
678    /* tell the tools */
679    VG_TRACK( post_deliver_signal, tid, sigNo );
680 }
681 
682 #endif // defined(VGP_x86_linux)
683 
684 /*--------------------------------------------------------------------*/
685 /*--- end                                                          ---*/
686 /*--------------------------------------------------------------------*/
687