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-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_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 */ 86struct 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 114struct 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*/ 326static 327void 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*/ 379static 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 421static 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 440static 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) - 8; 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 497void 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 /* And tell the tool that these registers have been written. */ 525 VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, 526 offsetof(VexGuestAMD64State,guest_RIP), sizeof(UWord) ); 527 VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, 528 offsetof(VexGuestAMD64State,guest_RDI), sizeof(UWord) ); 529 VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, 530 offsetof(VexGuestAMD64State,guest_RSI), sizeof(UWord) ); 531 VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, 532 offsetof(VexGuestAMD64State,guest_RDX), sizeof(UWord) ); 533 534 /* This thread needs to be marked runnable, but we leave that the 535 caller to do. */ 536 537 if (0) 538 VG_(printf)("pushed signal frame; %%RSP now = %#lx, " 539 "next %%RIP = %#llx, status=%d\n", 540 rsp, tst->arch.vex.guest_RIP, tst->status); 541} 542 543 544/*------------------------------------------------------------*/ 545/*--- Destroying signal frames ---*/ 546/*------------------------------------------------------------*/ 547 548/* Return False and don't do anything, just set the client to take a 549 segfault, if it looks like the frame is corrupted. */ 550static 551Bool restore_vg_sigframe ( ThreadState *tst, 552 struct vg_sigframe *frame, Int *sigNo ) 553{ 554 if (frame->magicPI != 0x31415927 || 555 frame->magicE != 0x27182818) { 556 VG_(message)(Vg_UserMsg, "Thread %d return signal frame " 557 "corrupted. Killing process.\n", 558 tst->tid); 559 VG_(set_default_handler)(VKI_SIGSEGV); 560 VG_(synth_fault)(tst->tid); 561 *sigNo = VKI_SIGSEGV; 562 return False; 563 } 564 tst->sig_mask = frame->mask; 565 tst->tmp_sig_mask = frame->mask; 566 tst->arch.vex_shadow1 = frame->vex_shadow1; 567 tst->arch.vex_shadow2 = frame->vex_shadow2; 568 /* HACK ALERT */ 569 tst->arch.vex = frame->vex; 570 /* end HACK ALERT */ 571 *sigNo = frame->sigNo_private; 572 return True; 573} 574 575static 576void restore_sigcontext( ThreadState *tst, 577 struct vki_sigcontext *sc, 578 struct _vki_fpstate *fpstate ) 579{ 580 tst->arch.vex.guest_RAX = sc->rax; 581 tst->arch.vex.guest_RCX = sc->rcx; 582 tst->arch.vex.guest_RDX = sc->rdx; 583 tst->arch.vex.guest_RBX = sc->rbx; 584 tst->arch.vex.guest_RBP = sc->rbp; 585 tst->arch.vex.guest_RSP = sc->rsp; 586 tst->arch.vex.guest_RSI = sc->rsi; 587 tst->arch.vex.guest_RDI = sc->rdi; 588 tst->arch.vex.guest_R8 = sc->r8; 589 tst->arch.vex.guest_R9 = sc->r9; 590 tst->arch.vex.guest_R10 = sc->r10; 591 tst->arch.vex.guest_R11 = sc->r11; 592 tst->arch.vex.guest_R12 = sc->r12; 593 tst->arch.vex.guest_R13 = sc->r13; 594 tst->arch.vex.guest_R14 = sc->r14; 595 tst->arch.vex.guest_R15 = sc->r15; 596//:: tst->arch.vex.guest_rflags = sc->rflags; 597 tst->arch.vex.guest_RIP = sc->rip; 598 599//:: tst->arch.vex.guest_CS = sc->cs; 600//:: tst->arch.vex.guest_FS = sc->fs; 601//:: tst->arch.vex.guest_GS = sc->gs; 602 603//:: restore_i387(&tst->arch, fpstate); 604} 605 606 607static 608SizeT restore_rt_sigframe ( ThreadState *tst, 609 struct rt_sigframe *frame, Int *sigNo ) 610{ 611 if (restore_vg_sigframe(tst, &frame->vg, sigNo)) 612 restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate); 613 614 return sizeof(*frame); 615} 616 617 618void VG_(sigframe_destroy)( ThreadId tid, Bool isRT ) 619{ 620 Addr rsp; 621 ThreadState* tst; 622 SizeT size; 623 Int sigNo; 624 625 vg_assert(isRT); 626 627 tst = VG_(get_ThreadState)(tid); 628 629 /* Correctly reestablish the frame base address. */ 630 rsp = tst->arch.vex.guest_RSP; 631 632 size = restore_rt_sigframe(tst, (struct rt_sigframe *)rsp, &sigNo); 633 634 VG_TRACK( die_mem_stack_signal, rsp - VG_STACK_REDZONE_SZB, 635 size + VG_STACK_REDZONE_SZB ); 636 637 if (VG_(clo_trace_signals)) 638 VG_(message)( 639 Vg_DebugMsg, 640 "VG_(signal_return) (thread %d): isRT=%d valid magic; RIP=%#llx\n", 641 tid, isRT, tst->arch.vex.guest_RIP); 642 643 /* tell the tools */ 644 VG_TRACK( post_deliver_signal, tid, sigNo ); 645} 646 647#endif // defined(VGP_amd64_linux) 648 649/*--------------------------------------------------------------------*/ 650/*--- end ---*/ 651/*--------------------------------------------------------------------*/ 652