1 2 /*--------------------------------------------------------------------*/ 3 /*--- Create/destroy signal delivery frames. ---*/ 4 /*--- sigframe-amd64-linux.c ---*/ 5 /*--------------------------------------------------------------------*/ 6 7 /* 8 This file is part of Valgrind, a dynamic binary instrumentation 9 framework. 10 11 Copyright (C) 2000-2012 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_amd64_linux) 33 34 #include "pub_core_basics.h" 35 #include "pub_core_vki.h" 36 #include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy 37 #include "pub_core_threadstate.h" 38 #include "pub_core_aspacemgr.h" 39 #include "pub_core_libcbase.h" 40 #include "pub_core_libcassert.h" 41 #include "pub_core_libcprint.h" 42 #include "pub_core_machine.h" 43 #include "pub_core_options.h" 44 #include "pub_core_signals.h" 45 #include "pub_core_tooliface.h" 46 #include "pub_core_trampoline.h" 47 #include "pub_core_sigframe.h" /* self */ 48 49 /* This module creates and removes signal frames for signal deliveries 50 on amd64-linux. 51 52 Note, this file contains kernel-specific knowledge in the form of 53 'struct rt_sigframe'. How does that relate to the vki kernel 54 interface stuff? 55 56 A 'struct rtsigframe' is pushed onto the client's stack. This 57 contains a subsidiary vki_ucontext. That holds the vcpu's state 58 across the signal, so that the sighandler can mess with the vcpu 59 state if it really wants. 60 61 FIXME: sigcontexting is basically broken for the moment. When 62 delivering a signal, the integer registers and %rflags are 63 correctly written into the sigcontext, however the FP and SSE state 64 is not. When returning from a signal, only the integer registers 65 are restored from the sigcontext; the rest of the CPU state is 66 restored to what it was before the signal. 67 68 This will be fixed. 69 */ 70 71 72 /*------------------------------------------------------------*/ 73 /*--- Signal frame layouts ---*/ 74 /*------------------------------------------------------------*/ 75 76 // A structure in which to save the application's registers 77 // during the execution of signal handlers. 78 79 // In theory, so long as we get the arguments to the handler function 80 // right, it doesn't matter what the exact layout of the rest of the 81 // frame is. Unfortunately, things like gcc's exception unwinding 82 // make assumptions about the locations of various parts of the frame, 83 // so we need to duplicate it exactly. 84 85 /* Valgrind-specific parts of the signal frame */ 86 struct vg_sigframe 87 { 88 /* Sanity check word. */ 89 UInt magicPI; 90 91 UInt handlerflags; /* flags for signal handler */ 92 93 94 /* Safely-saved version of sigNo, as described above. */ 95 Int sigNo_private; 96 97 /* XXX This is wrong. Surely we should store the shadow values 98 into the shadow memory behind the actual values? */ 99 VexGuestAMD64State vex_shadow1; 100 VexGuestAMD64State vex_shadow2; 101 102 /* HACK ALERT */ 103 VexGuestAMD64State vex; 104 /* end HACK ALERT */ 105 106 /* saved signal mask to be restored when handler returns */ 107 vki_sigset_t mask; 108 109 /* Sanity check word. Is the highest-addressed word; do not 110 move!*/ 111 UInt magicE; 112 }; 113 114 struct rt_sigframe 115 { 116 /* Sig handler's return address */ 117 Addr retaddr; 118 119 /* ucontext */ 120 struct vki_ucontext uContext; 121 122 /* siginfo */ 123 vki_siginfo_t sigInfo; 124 struct _vki_fpstate fpstate; 125 126 struct vg_sigframe vg; 127 }; 128 129 130 //:: /*------------------------------------------------------------*/ 131 //:: /*--- Signal operations ---*/ 132 //:: /*------------------------------------------------------------*/ 133 //:: 134 //:: /* 135 //:: Great gobs of FP state conversion taken wholesale from 136 //:: linux/arch/i386/kernel/i387.c 137 //:: */ 138 //:: 139 //:: /* 140 //:: * FXSR floating point environment conversions. 141 //:: */ 142 //:: #define X86_FXSR_MAGIC 0x0000 143 //:: 144 //:: /* 145 //:: * FPU tag word conversions. 146 //:: */ 147 //:: 148 //:: static inline unsigned short twd_i387_to_fxsr( unsigned short twd ) 149 //:: { 150 //:: unsigned int tmp; /* to avoid 16 bit prefixes in the code */ 151 //:: 152 //:: /* Transform each pair of bits into 01 (valid) or 00 (empty) */ 153 //:: tmp = ~twd; 154 //:: tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */ 155 //:: /* and move the valid bits to the lower byte. */ 156 //:: tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */ 157 //:: tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */ 158 //:: tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */ 159 //:: return tmp; 160 //:: } 161 //:: 162 //:: static unsigned long twd_fxsr_to_i387( const struct i387_fxsave_struct *fxsave ) 163 //:: { 164 //:: struct _vki_fpxreg *st = NULL; 165 //:: unsigned long twd = (unsigned long) fxsave->twd; 166 //:: unsigned long tag; 167 //:: unsigned long ret = 0xffff0000u; 168 //:: int i; 169 //:: 170 //:: #define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16); 171 //:: 172 //:: for ( i = 0 ; i < 8 ; i++ ) { 173 //:: if ( twd & 0x1 ) { 174 //:: st = (struct _vki_fpxreg *) FPREG_ADDR( fxsave, i ); 175 //:: 176 //:: switch ( st->exponent & 0x7fff ) { 177 //:: case 0x7fff: 178 //:: tag = 2; /* Special */ 179 //:: break; 180 //:: case 0x0000: 181 //:: if ( !st->significand[0] && 182 //:: !st->significand[1] && 183 //:: !st->significand[2] && 184 //:: !st->significand[3] ) { 185 //:: tag = 1; /* Zero */ 186 //:: } else { 187 //:: tag = 2; /* Special */ 188 //:: } 189 //:: break; 190 //:: default: 191 //:: if ( st->significand[3] & 0x8000 ) { 192 //:: tag = 0; /* Valid */ 193 //:: } else { 194 //:: tag = 2; /* Special */ 195 //:: } 196 //:: break; 197 //:: } 198 //:: } else { 199 //:: tag = 3; /* Empty */ 200 //:: } 201 //:: ret |= (tag << (2 * i)); 202 //:: twd = twd >> 1; 203 //:: } 204 //:: return ret; 205 //:: } 206 //:: 207 //:: static void convert_fxsr_to_user( struct _vki_fpstate *buf, 208 //:: const struct i387_fxsave_struct *fxsave ) 209 //:: { 210 //:: unsigned long env[7]; 211 //:: struct _vki_fpreg *to; 212 //:: struct _vki_fpxreg *from; 213 //:: int i; 214 //:: 215 //:: env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul; 216 //:: env[1] = (unsigned long)fxsave->swd | 0xffff0000ul; 217 //:: env[2] = twd_fxsr_to_i387(fxsave); 218 //:: env[3] = fxsave->fip; 219 //:: env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16); 220 //:: env[5] = fxsave->foo; 221 //:: env[6] = fxsave->fos; 222 //:: 223 //:: VG_(memcpy)(buf, env, 7 * sizeof(unsigned long)); 224 //:: 225 //:: to = &buf->_st[0]; 226 //:: from = (struct _vki_fpxreg *) &fxsave->st_space[0]; 227 //:: for ( i = 0 ; i < 8 ; i++, to++, from++ ) { 228 //:: unsigned long __user *t = (unsigned long __user *)to; 229 //:: unsigned long *f = (unsigned long *)from; 230 //:: 231 //:: t[0] = f[0]; 232 //:: t[1] = f[1]; 233 //:: to->exponent = from->exponent; 234 //:: } 235 //:: } 236 //:: 237 //:: static void convert_fxsr_from_user( struct i387_fxsave_struct *fxsave, 238 //:: const struct _vki_fpstate *buf ) 239 //:: { 240 //:: unsigned long env[7]; 241 //:: struct _vki_fpxreg *to; 242 //:: const struct _vki_fpreg *from; 243 //:: int i; 244 //:: 245 //:: VG_(memcpy)(env, buf, 7 * sizeof(long)); 246 //:: 247 //:: fxsave->cwd = (unsigned short)(env[0] & 0xffff); 248 //:: fxsave->swd = (unsigned short)(env[1] & 0xffff); 249 //:: fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff)); 250 //:: fxsave->fip = env[3]; 251 //:: fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16); 252 //:: fxsave->fcs = (env[4] & 0xffff); 253 //:: fxsave->foo = env[5]; 254 //:: fxsave->fos = env[6]; 255 //:: 256 //:: to = (struct _vki_fpxreg *) &fxsave->st_space[0]; 257 //:: from = &buf->_st[0]; 258 //:: for ( i = 0 ; i < 8 ; i++, to++, from++ ) { 259 //:: unsigned long *t = (unsigned long *)to; 260 //:: unsigned long __user *f = (unsigned long __user *)from; 261 //:: 262 //:: t[0] = f[0]; 263 //:: t[1] = f[1]; 264 //:: to->exponent = from->exponent; 265 //:: } 266 //:: } 267 //:: 268 //:: static inline void save_i387_fsave( arch_thread_t *regs, struct _vki_fpstate *buf ) 269 //:: { 270 //:: struct i387_fsave_struct *fs = ®s->m_sse.fsave; 271 //:: 272 //:: fs->status = fs->swd; 273 //:: VG_(memcpy)(buf, fs, sizeof(*fs)); 274 //:: } 275 //:: 276 //:: static void save_i387_fxsave( arch_thread_t *regs, struct _vki_fpstate *buf ) 277 //:: { 278 //:: const struct i387_fxsave_struct *fx = ®s->m_sse.fxsave; 279 //:: convert_fxsr_to_user( buf, fx ); 280 //:: 281 //:: buf->status = fx->swd; 282 //:: buf->magic = X86_FXSR_MAGIC; 283 //:: VG_(memcpy)(buf->_fxsr_env, fx, sizeof(struct i387_fxsave_struct)); 284 //:: } 285 //:: 286 //:: static void save_i387( arch_thread_t *regs, struct _vki_fpstate *buf ) 287 //:: { 288 //:: if ( VG_(have_ssestate) ) 289 //:: save_i387_fxsave( regs, buf ); 290 //:: else 291 //:: save_i387_fsave( regs, buf ); 292 //:: } 293 //:: 294 //:: static inline void restore_i387_fsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf ) 295 //:: { 296 //:: VG_(memcpy)( ®s->m_sse.fsave, buf, sizeof(struct i387_fsave_struct) ); 297 //:: } 298 //:: 299 //:: static void restore_i387_fxsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf ) 300 //:: { 301 //:: VG_(memcpy)(®s->m_sse.fxsave, &buf->_fxsr_env[0], 302 //:: sizeof(struct i387_fxsave_struct) ); 303 //:: /* mxcsr reserved bits must be masked to zero for security reasons */ 304 //:: regs->m_sse.fxsave.mxcsr &= 0xffbf; 305 //:: convert_fxsr_from_user( ®s->m_sse.fxsave, buf ); 306 //:: } 307 //:: 308 //:: static void restore_i387( arch_thread_t *regs, const struct _vki_fpstate __user *buf ) 309 //:: { 310 //:: if ( VG_(have_ssestate) ) { 311 //:: restore_i387_fxsave( regs, buf ); 312 //:: } else { 313 //:: restore_i387_fsave( regs, buf ); 314 //:: } 315 //:: } 316 317 318 /*------------------------------------------------------------*/ 319 /*--- Creating signal frames ---*/ 320 /*------------------------------------------------------------*/ 321 322 /* Create a plausible-looking sigcontext from the thread's 323 Vex guest state. NOTE: does not fill in the FP or SSE 324 bits of sigcontext at the moment. 325 */ 326 static 327 void synth_ucontext(ThreadId tid, const vki_siginfo_t *si, 328 UWord trapno, UWord err, const vki_sigset_t *set, 329 struct vki_ucontext *uc, struct _vki_fpstate *fpstate) 330 { 331 ThreadState *tst = VG_(get_ThreadState)(tid); 332 struct vki_sigcontext *sc = &uc->uc_mcontext; 333 334 VG_(memset)(uc, 0, sizeof(*uc)); 335 336 uc->uc_flags = 0; 337 uc->uc_link = 0; 338 uc->uc_sigmask = *set; 339 uc->uc_stack = tst->altstack; 340 sc->fpstate = fpstate; 341 342 // FIXME: save_i387(&tst->arch, fpstate); 343 344 # define SC2(reg,REG) sc->reg = tst->arch.vex.guest_##REG 345 SC2(r8,R8); 346 SC2(r9,R9); 347 SC2(r10,R10); 348 SC2(r11,R11); 349 SC2(r12,R12); 350 SC2(r13,R13); 351 SC2(r14,R14); 352 SC2(r15,R15); 353 SC2(rdi,RDI); 354 SC2(rsi,RSI); 355 SC2(rbp,RBP); 356 SC2(rbx,RBX); 357 SC2(rdx,RDX); 358 SC2(rax,RAX); 359 SC2(rcx,RCX); 360 SC2(rsp,RSP); 361 362 SC2(rip,RIP); 363 sc->eflags = LibVEX_GuestAMD64_get_rflags(&tst->arch.vex); 364 // FIXME: SC2(cs,CS); 365 // FIXME: SC2(gs,GS); 366 // FIXME: SC2(fs,FS); 367 sc->trapno = trapno; 368 sc->err = err; 369 # undef SC2 370 371 sc->cr2 = (UWord)si->_sifields._sigfault._addr; 372 } 373 374 375 /* Extend the stack segment downwards if needed so as to ensure the 376 new signal frames are mapped to something. Return a Bool 377 indicating whether or not the operation was successful. 378 */ 379 static Bool extend ( ThreadState *tst, Addr addr, SizeT size ) 380 { 381 ThreadId tid = tst->tid; 382 NSegment const* stackseg = NULL; 383 384 if (VG_(extend_stack)(addr, tst->client_stack_szB)) { 385 stackseg = VG_(am_find_nsegment)(addr); 386 if (0 && stackseg) 387 VG_(printf)("frame=%#lx seg=%#lx-%#lx\n", 388 addr, stackseg->start, stackseg->end); 389 } 390 391 if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) { 392 VG_(message)( 393 Vg_UserMsg, 394 "Can't extend stack to %#lx during signal delivery for thread %d:\n", 395 addr, tid); 396 if (stackseg == NULL) 397 VG_(message)(Vg_UserMsg, " no stack segment\n"); 398 else 399 VG_(message)(Vg_UserMsg, " too small or bad protection modes\n"); 400 401 /* set SIGSEGV to default handler */ 402 VG_(set_default_handler)(VKI_SIGSEGV); 403 VG_(synth_fault_mapping)(tid, addr); 404 405 /* The whole process should be about to die, since the default 406 action of SIGSEGV to kill the whole process. */ 407 return False; 408 } 409 410 /* For tracking memory events, indicate the entire frame has been 411 allocated. */ 412 VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB, 413 size + VG_STACK_REDZONE_SZB, tid ); 414 415 return True; 416 } 417 418 419 /* Build the Valgrind-specific part of a signal frame. */ 420 421 static void build_vg_sigframe(struct vg_sigframe *frame, 422 ThreadState *tst, 423 const vki_sigset_t *mask, 424 UInt flags, 425 Int sigNo) 426 { 427 frame->sigNo_private = sigNo; 428 frame->magicPI = 0x31415927; 429 frame->vex_shadow1 = tst->arch.vex_shadow1; 430 frame->vex_shadow2 = tst->arch.vex_shadow2; 431 /* HACK ALERT */ 432 frame->vex = tst->arch.vex; 433 /* end HACK ALERT */ 434 frame->mask = tst->sig_mask; 435 frame->handlerflags = flags; 436 frame->magicE = 0x27182818; 437 } 438 439 440 static Addr build_rt_sigframe(ThreadState *tst, 441 Addr rsp_top_of_frame, 442 const vki_siginfo_t *siginfo, 443 const struct vki_ucontext *siguc, 444 void *handler, UInt flags, 445 const vki_sigset_t *mask, 446 void *restorer) 447 { 448 struct rt_sigframe *frame; 449 Addr rsp = rsp_top_of_frame; 450 Int sigNo = siginfo->si_signo; 451 UWord trapno; 452 UWord err; 453 454 rsp -= sizeof(*frame); 455 rsp = VG_ROUNDDN(rsp, 16); 456 frame = (struct rt_sigframe *)rsp; 457 458 if (!extend(tst, rsp, sizeof(*frame))) 459 return rsp_top_of_frame; 460 461 /* retaddr, siginfo, uContext fields are to be written */ 462 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "rt signal handler frame", 463 rsp, offsetof(struct rt_sigframe, vg) ); 464 465 if (flags & VKI_SA_RESTORER) 466 frame->retaddr = (Addr)restorer; 467 else 468 frame->retaddr = (Addr)&VG_(amd64_linux_SUBST_FOR_rt_sigreturn); 469 470 if (siguc) { 471 trapno = siguc->uc_mcontext.trapno; 472 err = siguc->uc_mcontext.err; 473 } else { 474 trapno = 0; 475 err = 0; 476 } 477 478 VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t)); 479 480 /* SIGILL defines addr to be the faulting address */ 481 if (sigNo == VKI_SIGILL && siginfo->si_code > 0) 482 frame->sigInfo._sifields._sigfault._addr 483 = (void*)tst->arch.vex.guest_RIP; 484 485 synth_ucontext(tst->tid, siginfo, trapno, err, mask, 486 &frame->uContext, &frame->fpstate); 487 488 VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, 489 rsp, offsetof(struct rt_sigframe, vg) ); 490 491 build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo); 492 493 return rsp; 494 } 495 496 497 void VG_(sigframe_create)( ThreadId tid, 498 Addr rsp_top_of_frame, 499 const vki_siginfo_t *siginfo, 500 const struct vki_ucontext *siguc, 501 void *handler, 502 UInt flags, 503 const vki_sigset_t *mask, 504 void *restorer ) 505 { 506 Addr rsp; 507 struct rt_sigframe *frame; 508 ThreadState* tst = VG_(get_ThreadState)(tid); 509 510 rsp = build_rt_sigframe(tst, rsp_top_of_frame, siginfo, siguc, 511 handler, flags, mask, restorer); 512 frame = (struct rt_sigframe *)rsp; 513 514 /* Set the thread so it will next run the handler. */ 515 /* tst->m_rsp = rsp; also notify the tool we've updated RSP */ 516 VG_(set_SP)(tid, rsp); 517 VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr)); 518 519 //VG_(printf)("handler = %p\n", handler); 520 tst->arch.vex.guest_RIP = (Addr) handler; 521 tst->arch.vex.guest_RDI = (ULong) siginfo->si_signo; 522 tst->arch.vex.guest_RSI = (Addr) &frame->sigInfo; 523 tst->arch.vex.guest_RDX = (Addr) &frame->uContext; 524 /* This thread needs to be marked runnable, but we leave that the 525 caller to do. */ 526 527 if (0) 528 VG_(printf)("pushed signal frame; %%RSP now = %#lx, " 529 "next %%RIP = %#llx, status=%d\n", 530 rsp, tst->arch.vex.guest_RIP, tst->status); 531 } 532 533 534 /*------------------------------------------------------------*/ 535 /*--- Destroying signal frames ---*/ 536 /*------------------------------------------------------------*/ 537 538 /* Return False and don't do anything, just set the client to take a 539 segfault, if it looks like the frame is corrupted. */ 540 static 541 Bool restore_vg_sigframe ( ThreadState *tst, 542 struct vg_sigframe *frame, Int *sigNo ) 543 { 544 if (frame->magicPI != 0x31415927 || 545 frame->magicE != 0x27182818) { 546 VG_(message)(Vg_UserMsg, "Thread %d return signal frame " 547 "corrupted. Killing process.\n", 548 tst->tid); 549 VG_(set_default_handler)(VKI_SIGSEGV); 550 VG_(synth_fault)(tst->tid); 551 *sigNo = VKI_SIGSEGV; 552 return False; 553 } 554 tst->sig_mask = frame->mask; 555 tst->tmp_sig_mask = frame->mask; 556 tst->arch.vex_shadow1 = frame->vex_shadow1; 557 tst->arch.vex_shadow2 = frame->vex_shadow2; 558 /* HACK ALERT */ 559 tst->arch.vex = frame->vex; 560 /* end HACK ALERT */ 561 *sigNo = frame->sigNo_private; 562 return True; 563 } 564 565 static 566 void restore_sigcontext( ThreadState *tst, 567 struct vki_sigcontext *sc, 568 struct _vki_fpstate *fpstate ) 569 { 570 tst->arch.vex.guest_RAX = sc->rax; 571 tst->arch.vex.guest_RCX = sc->rcx; 572 tst->arch.vex.guest_RDX = sc->rdx; 573 tst->arch.vex.guest_RBX = sc->rbx; 574 tst->arch.vex.guest_RBP = sc->rbp; 575 tst->arch.vex.guest_RSP = sc->rsp; 576 tst->arch.vex.guest_RSI = sc->rsi; 577 tst->arch.vex.guest_RDI = sc->rdi; 578 tst->arch.vex.guest_R8 = sc->r8; 579 tst->arch.vex.guest_R9 = sc->r9; 580 tst->arch.vex.guest_R10 = sc->r10; 581 tst->arch.vex.guest_R11 = sc->r11; 582 tst->arch.vex.guest_R12 = sc->r12; 583 tst->arch.vex.guest_R13 = sc->r13; 584 tst->arch.vex.guest_R14 = sc->r14; 585 tst->arch.vex.guest_R15 = sc->r15; 586 //:: tst->arch.vex.guest_rflags = sc->rflags; 587 tst->arch.vex.guest_RIP = sc->rip; 588 589 //:: tst->arch.vex.guest_CS = sc->cs; 590 //:: tst->arch.vex.guest_FS = sc->fs; 591 //:: tst->arch.vex.guest_GS = sc->gs; 592 593 //:: restore_i387(&tst->arch, fpstate); 594 } 595 596 597 static 598 SizeT restore_rt_sigframe ( ThreadState *tst, 599 struct rt_sigframe *frame, Int *sigNo ) 600 { 601 if (restore_vg_sigframe(tst, &frame->vg, sigNo)) 602 restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate); 603 604 return sizeof(*frame); 605 } 606 607 608 void VG_(sigframe_destroy)( ThreadId tid, Bool isRT ) 609 { 610 Addr rsp; 611 ThreadState* tst; 612 SizeT size; 613 Int sigNo; 614 615 vg_assert(isRT); 616 617 tst = VG_(get_ThreadState)(tid); 618 619 /* Correctly reestablish the frame base address. */ 620 rsp = tst->arch.vex.guest_RSP; 621 622 size = restore_rt_sigframe(tst, (struct rt_sigframe *)rsp, &sigNo); 623 624 VG_TRACK( die_mem_stack_signal, rsp - VG_STACK_REDZONE_SZB, 625 size + VG_STACK_REDZONE_SZB ); 626 627 if (VG_(clo_trace_signals)) 628 VG_(message)( 629 Vg_DebugMsg, 630 "VG_(signal_return) (thread %d): isRT=%d valid magic; RIP=%#llx\n", 631 tid, isRT, tst->arch.vex.guest_RIP); 632 633 /* tell the tools */ 634 VG_TRACK( post_deliver_signal, tid, sigNo ); 635 } 636 637 #endif // defined(VGP_amd64_linux) 638 639 /*--------------------------------------------------------------------*/ 640 /*--- end ---*/ 641 /*--------------------------------------------------------------------*/ 642