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 (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 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 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 */ 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 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 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 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 */ 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 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 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 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 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 */ 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