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-2010 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
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 = ®s->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 = ®s->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)( ®s->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)(®s->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( ®s->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 /* Extend the stack segment downwards if needed so as to ensure the
396 new signal frames are mapped to something. Return a Bool
397 indicating whether or not the operation was successful.
398 */
extend(ThreadState * tst,Addr addr,SizeT size)399 static Bool extend ( ThreadState *tst, Addr addr, SizeT size )
400 {
401 ThreadId tid = tst->tid;
402 NSegment const* stackseg = NULL;
403
404 if (VG_(extend_stack)(addr, tst->client_stack_szB)) {
405 stackseg = VG_(am_find_nsegment)(addr);
406 if (0 && stackseg)
407 VG_(printf)("frame=%#lx seg=%#lx-%#lx\n",
408 addr, stackseg->start, stackseg->end);
409 }
410
411 if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) {
412 VG_(message)(
413 Vg_UserMsg,
414 "Can't extend stack to %#lx during signal delivery for thread %d:\n",
415 addr, tid);
416 if (stackseg == NULL)
417 VG_(message)(Vg_UserMsg, " no stack segment\n");
418 else
419 VG_(message)(Vg_UserMsg, " too small or bad protection modes\n");
420
421 /* set SIGSEGV to default handler */
422 VG_(set_default_handler)(VKI_SIGSEGV);
423 VG_(synth_fault_mapping)(tid, addr);
424
425 /* The whole process should be about to die, since the default
426 action of SIGSEGV to kill the whole process. */
427 return False;
428 }
429
430 /* For tracking memory events, indicate the entire frame has been
431 allocated. */
432 VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB,
433 size + VG_STACK_REDZONE_SZB, tid );
434
435 return True;
436 }
437
438
439 /* Build the Valgrind-specific part of a signal frame. */
440
build_vg_sigframe(struct vg_sigframe * frame,ThreadState * tst,UInt flags,Int sigNo)441 static void build_vg_sigframe(struct vg_sigframe *frame,
442 ThreadState *tst,
443 UInt flags,
444 Int sigNo)
445 {
446 frame->sigNo_private = sigNo;
447 frame->magicPI = 0x31415927;
448 frame->vex_shadow1 = tst->arch.vex_shadow1;
449 frame->vex_shadow2 = tst->arch.vex_shadow2;
450 /* HACK ALERT */
451 frame->vex = tst->arch.vex;
452 /* end HACK ALERT */
453 frame->mask = tst->sig_mask;
454 frame->handlerflags = flags;
455 frame->magicE = 0x27182818;
456 }
457
458
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)459 static Addr build_sigframe(ThreadState *tst,
460 Addr esp_top_of_frame,
461 const vki_siginfo_t *siginfo,
462 const struct vki_ucontext *siguc,
463 UInt flags,
464 const vki_sigset_t *mask,
465 void *restorer)
466 {
467 struct sigframe *frame;
468 Addr esp = esp_top_of_frame;
469 Int sigNo = siginfo->si_signo;
470 UWord trapno;
471 UWord err;
472 struct vki_ucontext uc;
473
474 vg_assert((flags & VKI_SA_SIGINFO) == 0);
475
476 esp -= sizeof(*frame);
477 esp = VG_ROUNDDN(esp, 16);
478 frame = (struct sigframe *)esp;
479
480 if (!extend(tst, esp, sizeof(*frame)))
481 return esp_top_of_frame;
482
483 /* retaddr, sigNo, siguContext fields are to be written */
484 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame",
485 esp, offsetof(struct sigframe, vg) );
486
487 frame->sigNo = sigNo;
488
489 if (flags & VKI_SA_RESTORER)
490 frame->retaddr = (Addr)restorer;
491 else
492 frame->retaddr = (Addr)&VG_(x86_linux_SUBST_FOR_sigreturn);
493
494 if (siguc) {
495 trapno = siguc->uc_mcontext.trapno;
496 err = siguc->uc_mcontext.err;
497 } else {
498 trapno = 0;
499 err = 0;
500 }
501
502 synth_ucontext(tst->tid, siginfo, trapno, err, mask, &uc, &frame->fpstate);
503
504 VG_(memcpy)(&frame->sigContext, &uc.uc_mcontext,
505 sizeof(struct vki_sigcontext));
506 frame->sigContext.oldmask = mask->sig[0];
507
508 VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
509 esp, offsetof(struct sigframe, vg) );
510
511 build_vg_sigframe(&frame->vg, tst, flags, sigNo);
512
513 return esp;
514 }
515
516
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)517 static Addr build_rt_sigframe(ThreadState *tst,
518 Addr esp_top_of_frame,
519 const vki_siginfo_t *siginfo,
520 const struct vki_ucontext *siguc,
521 UInt flags,
522 const vki_sigset_t *mask,
523 void *restorer)
524 {
525 struct rt_sigframe *frame;
526 Addr esp = esp_top_of_frame;
527 Int sigNo = siginfo->si_signo;
528 UWord trapno;
529 UWord err;
530
531 vg_assert((flags & VKI_SA_SIGINFO) != 0);
532
533 esp -= sizeof(*frame);
534 esp = VG_ROUNDDN(esp, 16);
535 frame = (struct rt_sigframe *)esp;
536
537 if (!extend(tst, esp, sizeof(*frame)))
538 return esp_top_of_frame;
539
540 /* retaddr, sigNo, pSiginfo, puContext fields are to be written */
541 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "rt signal handler frame",
542 esp, offsetof(struct rt_sigframe, vg) );
543
544 frame->sigNo = sigNo;
545
546 if (flags & VKI_SA_RESTORER)
547 frame->retaddr = (Addr)restorer;
548 else
549 frame->retaddr = (Addr)&VG_(x86_linux_SUBST_FOR_rt_sigreturn);
550
551 if (siguc) {
552 trapno = siguc->uc_mcontext.trapno;
553 err = siguc->uc_mcontext.err;
554 } else {
555 trapno = 0;
556 err = 0;
557 }
558
559 frame->psigInfo = (Addr)&frame->sigInfo;
560 frame->puContext = (Addr)&frame->uContext;
561 VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
562
563 /* SIGILL defines addr to be the faulting address */
564 if (sigNo == VKI_SIGILL && siginfo->si_code > 0)
565 frame->sigInfo._sifields._sigfault._addr
566 = (void*)tst->arch.vex.guest_EIP;
567
568 synth_ucontext(tst->tid, siginfo, trapno, err, mask,
569 &frame->uContext, &frame->fpstate);
570
571 VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
572 esp, offsetof(struct rt_sigframe, vg) );
573
574 build_vg_sigframe(&frame->vg, tst, flags, sigNo);
575
576 return esp;
577 }
578
579
580 /* EXPORTED */
VG_(sigframe_create)581 void VG_(sigframe_create)( ThreadId tid,
582 Addr esp_top_of_frame,
583 const vki_siginfo_t *siginfo,
584 const struct vki_ucontext *siguc,
585 void *handler,
586 UInt flags,
587 const vki_sigset_t *mask,
588 void *restorer )
589 {
590 Addr esp;
591 ThreadState* tst = VG_(get_ThreadState)(tid);
592
593 if (flags & VKI_SA_SIGINFO)
594 esp = build_rt_sigframe(tst, esp_top_of_frame, siginfo, siguc,
595 flags, mask, restorer);
596 else
597 esp = build_sigframe(tst, esp_top_of_frame, siginfo, siguc,
598 flags, mask, restorer);
599
600 /* Set the thread so it will next run the handler. */
601 /* tst->m_esp = esp; also notify the tool we've updated ESP */
602 VG_(set_SP)(tid, esp);
603 VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr));
604
605 //VG_(printf)("handler = %p\n", handler);
606 tst->arch.vex.guest_EIP = (Addr) handler;
607 /* This thread needs to be marked runnable, but we leave that the
608 caller to do. */
609
610 if (0)
611 VG_(printf)("pushed signal frame; %%ESP now = %#lx, "
612 "next %%EIP = %#x, status=%d\n",
613 esp, tst->arch.vex.guest_EIP, tst->status);
614 }
615
616
617 /*------------------------------------------------------------*/
618 /*--- Destroying signal frames ---*/
619 /*------------------------------------------------------------*/
620
621 /* Return False and don't do anything, just set the client to take a
622 segfault, if it looks like the frame is corrupted. */
623 static
restore_vg_sigframe(ThreadState * tst,struct vg_sigframe * frame,Int * sigNo)624 Bool restore_vg_sigframe ( ThreadState *tst,
625 struct vg_sigframe *frame, Int *sigNo )
626 {
627 if (frame->magicPI != 0x31415927 ||
628 frame->magicE != 0x27182818) {
629 VG_(message)(Vg_UserMsg, "Thread %d return signal frame "
630 "corrupted. Killing process.\n",
631 tst->tid);
632 VG_(set_default_handler)(VKI_SIGSEGV);
633 VG_(synth_fault)(tst->tid);
634 *sigNo = VKI_SIGSEGV;
635 return False;
636 }
637 tst->sig_mask = frame->mask;
638 tst->tmp_sig_mask = frame->mask;
639 tst->arch.vex_shadow1 = frame->vex_shadow1;
640 tst->arch.vex_shadow2 = frame->vex_shadow2;
641 /* HACK ALERT */
642 tst->arch.vex = frame->vex;
643 /* end HACK ALERT */
644 *sigNo = frame->sigNo_private;
645 return True;
646 }
647
648 static
restore_sigcontext(ThreadState * tst,struct vki_sigcontext * sc,struct _vki_fpstate * fpstate)649 void restore_sigcontext( ThreadState *tst,
650 struct vki_sigcontext *sc,
651 struct _vki_fpstate *fpstate )
652 {
653 tst->arch.vex.guest_EAX = sc->eax;
654 tst->arch.vex.guest_ECX = sc->ecx;
655 tst->arch.vex.guest_EDX = sc->edx;
656 tst->arch.vex.guest_EBX = sc->ebx;
657 tst->arch.vex.guest_EBP = sc->ebp;
658 tst->arch.vex.guest_ESP = sc->esp;
659 tst->arch.vex.guest_ESI = sc->esi;
660 tst->arch.vex.guest_EDI = sc->edi;
661 //:: tst->arch.vex.guest_eflags = sc->eflags;
662 tst->arch.vex.guest_EIP = sc->eip;
663 tst->arch.vex.guest_CS = sc->cs;
664 tst->arch.vex.guest_SS = sc->ss;
665 tst->arch.vex.guest_DS = sc->ds;
666 tst->arch.vex.guest_ES = sc->es;
667 tst->arch.vex.guest_FS = sc->fs;
668 tst->arch.vex.guest_GS = sc->gs;
669
670 //:: restore_i387(&tst->arch, fpstate);
671 }
672
673
674 static
restore_sigframe(ThreadState * tst,struct sigframe * frame,Int * sigNo)675 SizeT restore_sigframe ( ThreadState *tst,
676 struct sigframe *frame, Int *sigNo )
677 {
678 if (restore_vg_sigframe(tst, &frame->vg, sigNo))
679 restore_sigcontext(tst, &frame->sigContext, &frame->fpstate);
680
681 return sizeof(*frame);
682 }
683
684 static
restore_rt_sigframe(ThreadState * tst,struct rt_sigframe * frame,Int * sigNo)685 SizeT restore_rt_sigframe ( ThreadState *tst,
686 struct rt_sigframe *frame, Int *sigNo )
687 {
688 if (restore_vg_sigframe(tst, &frame->vg, sigNo))
689 restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate);
690
691 return sizeof(*frame);
692 }
693
694
695 /* EXPORTED */
VG_(sigframe_destroy)696 void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
697 {
698 Addr esp;
699 ThreadState* tst;
700 SizeT size;
701 Int sigNo;
702
703 tst = VG_(get_ThreadState)(tid);
704
705 /* Correctly reestablish the frame base address. */
706 esp = tst->arch.vex.guest_ESP;
707
708 if (!isRT)
709 size = restore_sigframe(tst, (struct sigframe *)esp, &sigNo);
710 else
711 size = restore_rt_sigframe(tst, (struct rt_sigframe *)esp, &sigNo);
712
713 VG_TRACK( die_mem_stack_signal, esp - VG_STACK_REDZONE_SZB,
714 size + VG_STACK_REDZONE_SZB );
715
716 if (VG_(clo_trace_signals))
717 VG_(message)(
718 Vg_DebugMsg,
719 "VG_(signal_return) (thread %d): isRT=%d valid magic; EIP=%#x\n",
720 tid, isRT, tst->arch.vex.guest_EIP);
721
722 /* tell the tools */
723 VG_TRACK( post_deliver_signal, tid, sigNo );
724 }
725
726 #endif // defined(VGP_x86_linux)
727
728 /*--------------------------------------------------------------------*/
729 /*--- end ---*/
730 /*--------------------------------------------------------------------*/
731