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-2017 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_threadstate.h" 37#include "pub_core_aspacemgr.h" 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 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/* Build the Valgrind-specific part of a signal frame. */ 376 377static void build_vg_sigframe(struct vg_sigframe *frame, 378 ThreadState *tst, 379 const vki_sigset_t *mask, 380 UInt flags, 381 Int sigNo) 382{ 383 frame->sigNo_private = sigNo; 384 frame->magicPI = 0x31415927; 385 frame->vex_shadow1 = tst->arch.vex_shadow1; 386 frame->vex_shadow2 = tst->arch.vex_shadow2; 387 /* HACK ALERT */ 388 frame->vex = tst->arch.vex; 389 /* end HACK ALERT */ 390 frame->mask = tst->sig_mask; 391 frame->handlerflags = flags; 392 frame->magicE = 0x27182818; 393} 394 395 396static Addr build_rt_sigframe(ThreadState *tst, 397 Addr rsp_top_of_frame, 398 const vki_siginfo_t *siginfo, 399 const struct vki_ucontext *siguc, 400 void *handler, UInt flags, 401 const vki_sigset_t *mask, 402 void *restorer) 403{ 404 struct rt_sigframe *frame; 405 Addr rsp = rsp_top_of_frame; 406 Int sigNo = siginfo->si_signo; 407 UWord trapno; 408 UWord err; 409 410 rsp -= sizeof(*frame); 411 rsp = VG_ROUNDDN(rsp, 16) - 8; 412 frame = (struct rt_sigframe *)rsp; 413 414 if (! ML_(sf_maybe_extend_stack)(tst, rsp, sizeof(*frame), flags)) 415 return rsp_top_of_frame; 416 417 /* retaddr, siginfo, uContext fields are to be written */ 418 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "rt signal handler frame", 419 rsp, offsetof(struct rt_sigframe, vg) ); 420 421 if (flags & VKI_SA_RESTORER) 422 frame->retaddr = (Addr)restorer; 423 else 424 frame->retaddr = (Addr)&VG_(amd64_linux_SUBST_FOR_rt_sigreturn); 425 426 if (siguc) { 427 trapno = siguc->uc_mcontext.trapno; 428 err = siguc->uc_mcontext.err; 429 } else { 430 trapno = 0; 431 err = 0; 432 } 433 434 VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t)); 435 436 /* SIGILL defines addr to be the faulting address */ 437 if (sigNo == VKI_SIGILL && siginfo->si_code > 0) 438 frame->sigInfo._sifields._sigfault._addr 439 = (void*)tst->arch.vex.guest_RIP; 440 441 synth_ucontext(tst->tid, siginfo, trapno, err, mask, 442 &frame->uContext, &frame->fpstate); 443 444 VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, 445 rsp, offsetof(struct rt_sigframe, vg) ); 446 447 build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo); 448 449 return rsp; 450} 451 452 453void VG_(sigframe_create)( ThreadId tid, 454 Bool on_altstack, 455 Addr rsp_top_of_frame, 456 const vki_siginfo_t *siginfo, 457 const struct vki_ucontext *siguc, 458 void *handler, 459 UInt flags, 460 const vki_sigset_t *mask, 461 void *restorer ) 462{ 463 Addr rsp; 464 struct rt_sigframe *frame; 465 ThreadState* tst = VG_(get_ThreadState)(tid); 466 467 rsp = build_rt_sigframe(tst, rsp_top_of_frame, siginfo, siguc, 468 handler, flags, mask, restorer); 469 frame = (struct rt_sigframe *)rsp; 470 471 /* Set the thread so it will next run the handler. */ 472 /* tst->m_rsp = rsp; also notify the tool we've updated RSP */ 473 VG_(set_SP)(tid, rsp); 474 VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr)); 475 476 //VG_(printf)("handler = %p\n", handler); 477 tst->arch.vex.guest_RIP = (Addr) handler; 478 tst->arch.vex.guest_RDI = (ULong) siginfo->si_signo; 479 tst->arch.vex.guest_RSI = (Addr) &frame->sigInfo; 480 tst->arch.vex.guest_RDX = (Addr) &frame->uContext; 481 /* And tell the tool that these registers have been written. */ 482 VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, 483 offsetof(VexGuestAMD64State,guest_RIP), sizeof(UWord) ); 484 VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, 485 offsetof(VexGuestAMD64State,guest_RDI), sizeof(UWord) ); 486 VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, 487 offsetof(VexGuestAMD64State,guest_RSI), sizeof(UWord) ); 488 VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, 489 offsetof(VexGuestAMD64State,guest_RDX), sizeof(UWord) ); 490 491 /* This thread needs to be marked runnable, but we leave that the 492 caller to do. */ 493 494 if (0) 495 VG_(printf)("pushed signal frame; %%RSP now = %#lx, " 496 "next %%RIP = %#llx, status=%d\n", 497 rsp, tst->arch.vex.guest_RIP, (Int)tst->status); 498} 499 500 501/*------------------------------------------------------------*/ 502/*--- Destroying signal frames ---*/ 503/*------------------------------------------------------------*/ 504 505/* Return False and don't do anything, just set the client to take a 506 segfault, if it looks like the frame is corrupted. */ 507static 508Bool restore_vg_sigframe ( ThreadState *tst, 509 struct vg_sigframe *frame, Int *sigNo ) 510{ 511 if (frame->magicPI != 0x31415927 || 512 frame->magicE != 0x27182818) { 513 VG_(message)(Vg_UserMsg, "Thread %u return signal frame " 514 "corrupted. Killing process.\n", 515 tst->tid); 516 VG_(set_default_handler)(VKI_SIGSEGV); 517 VG_(synth_fault)(tst->tid); 518 *sigNo = VKI_SIGSEGV; 519 return False; 520 } 521 tst->sig_mask = frame->mask; 522 tst->tmp_sig_mask = frame->mask; 523 tst->arch.vex_shadow1 = frame->vex_shadow1; 524 tst->arch.vex_shadow2 = frame->vex_shadow2; 525 /* HACK ALERT */ 526 tst->arch.vex = frame->vex; 527 /* end HACK ALERT */ 528 *sigNo = frame->sigNo_private; 529 return True; 530} 531 532static 533void restore_sigcontext( ThreadState *tst, 534 struct vki_sigcontext *sc, 535 struct _vki_fpstate *fpstate ) 536{ 537 tst->arch.vex.guest_RAX = sc->rax; 538 tst->arch.vex.guest_RCX = sc->rcx; 539 tst->arch.vex.guest_RDX = sc->rdx; 540 tst->arch.vex.guest_RBX = sc->rbx; 541 tst->arch.vex.guest_RBP = sc->rbp; 542 tst->arch.vex.guest_RSP = sc->rsp; 543 tst->arch.vex.guest_RSI = sc->rsi; 544 tst->arch.vex.guest_RDI = sc->rdi; 545 tst->arch.vex.guest_R8 = sc->r8; 546 tst->arch.vex.guest_R9 = sc->r9; 547 tst->arch.vex.guest_R10 = sc->r10; 548 tst->arch.vex.guest_R11 = sc->r11; 549 tst->arch.vex.guest_R12 = sc->r12; 550 tst->arch.vex.guest_R13 = sc->r13; 551 tst->arch.vex.guest_R14 = sc->r14; 552 tst->arch.vex.guest_R15 = sc->r15; 553//:: tst->arch.vex.guest_rflags = sc->rflags; 554 tst->arch.vex.guest_RIP = sc->rip; 555 556//:: tst->arch.vex.guest_CS = sc->cs; 557//:: tst->arch.vex.guest_FS = sc->fs; 558//:: tst->arch.vex.guest_GS = sc->gs; 559 560//:: restore_i387(&tst->arch, fpstate); 561} 562 563 564static 565SizeT restore_rt_sigframe ( ThreadState *tst, 566 struct rt_sigframe *frame, Int *sigNo ) 567{ 568 if (restore_vg_sigframe(tst, &frame->vg, sigNo)) 569 restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate); 570 571 return sizeof(*frame); 572} 573 574 575void VG_(sigframe_destroy)( ThreadId tid, Bool isRT ) 576{ 577 Addr rsp; 578 ThreadState* tst; 579 SizeT size; 580 Int sigNo; 581 582 vg_assert(isRT); 583 584 tst = VG_(get_ThreadState)(tid); 585 586 /* Correctly reestablish the frame base address. */ 587 rsp = tst->arch.vex.guest_RSP; 588 589 size = restore_rt_sigframe(tst, (struct rt_sigframe *)rsp, &sigNo); 590 591 VG_TRACK( die_mem_stack_signal, rsp - VG_STACK_REDZONE_SZB, 592 size + VG_STACK_REDZONE_SZB ); 593 594 if (VG_(clo_trace_signals)) 595 VG_(message)( 596 Vg_DebugMsg, 597 "VG_(signal_return) (thread %u): isRT=%d valid magic; RIP=%#llx\n", 598 tid, isRT, tst->arch.vex.guest_RIP); 599 600 /* tell the tools */ 601 VG_TRACK( post_deliver_signal, tid, sigNo ); 602} 603 604#endif // defined(VGP_amd64_linux) 605 606/*--------------------------------------------------------------------*/ 607/*--- end ---*/ 608/*--------------------------------------------------------------------*/ 609