1 2/*--------------------------------------------------------------------*/ 3/*--- Create/destroy signal delivery frames. ---*/ 4/*--- sigframe-ppc32-linux.c ---*/ 5/*--------------------------------------------------------------------*/ 6 7/* 8 This file is part of Valgrind, a dynamic binary instrumentation 9 framework. 10 11 Copyright (C) 2000-2015 Nicholas Nethercote 12 njn@valgrind.org 13 Copyright (C) 2004-2015 Paul Mackerras 14 paulus@samba.org 15 16 This program is free software; you can redistribute it and/or 17 modify it under the terms of the GNU General Public License as 18 published by the Free Software Foundation; either version 2 of the 19 License, or (at your option) any later version. 20 21 This program is distributed in the hope that it will be useful, but 22 WITHOUT ANY WARRANTY; without even the implied warranty of 23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24 General Public License for more details. 25 26 You should have received a copy of the GNU General Public License 27 along with this program; if not, write to the Free Software 28 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 29 02111-1307, USA. 30 31 The GNU General Public License is contained in the file COPYING. 32*/ 33 34#if defined(VGP_ppc32_linux) 35 36#include "pub_core_basics.h" 37#include "pub_core_vki.h" 38#include "pub_core_vkiscnums.h" 39#include "pub_core_threadstate.h" 40#include "pub_core_aspacemgr.h" 41#include "pub_core_libcbase.h" 42#include "pub_core_libcassert.h" 43#include "pub_core_libcprint.h" 44#include "pub_core_machine.h" 45#include "pub_core_options.h" 46#include "pub_core_sigframe.h" 47#include "pub_core_signals.h" 48#include "pub_core_tooliface.h" 49#include "pub_core_trampoline.h" 50#include "pub_core_transtab.h" // VG_(discard_translations) 51#include "priv_sigframe.h" 52 53/* This module creates and removes signal frames for signal deliveries 54 on ppc32-linux. 55 56 Note, this file contains kernel-specific knowledge in the form of 57 'struct sigframe' and 'struct rt_sigframe'. How does that relate 58 to the vki kernel interface stuff? 59 60 Either a 'struct sigframe' or a 'struct rtsigframe' is pushed 61 onto the client's stack. This contains a subsidiary 62 vki_ucontext. That holds the vcpu's state across the signal, 63 so that the sighandler can mess with the vcpu state if it 64 really wants. 65 66 FIXME: sigcontexting is basically broken for the moment. When 67 delivering a signal, the integer registers and %eflags are 68 correctly written into the sigcontext, however the FP and SSE state 69 is not. When returning from a signal, only the integer registers 70 are restored from the sigcontext; the rest of the CPU state is 71 restored to what it was before the signal. 72 73 This will be fixed. 74*/ 75 76 77/*------------------------------------------------------------*/ 78/*--- Signal frame layouts ---*/ 79/*------------------------------------------------------------*/ 80 81// A structure in which to save the application's registers 82// during the execution of signal handlers. 83 84// Linux has 2 signal frame structures: one for normal signal 85// deliveries, and one for SA_SIGINFO deliveries (also known as RT 86// signals). 87// 88// In theory, so long as we get the arguments to the handler function 89// right, it doesn't matter what the exact layout of the rest of the 90// frame is. Unfortunately, things like gcc's exception unwinding 91// make assumptions about the locations of various parts of the frame, 92// so we need to duplicate it exactly. 93 94/* Structure containing bits of information that we want to save 95 on signal delivery. */ 96struct vg_sig_private { 97 UInt magicPI; 98 UInt sigNo_private; 99 VexGuestPPC32State vex_shadow1; 100 VexGuestPPC32State vex_shadow2; 101}; 102 103/* Structure put on stack for signal handlers with SA_SIGINFO clear. */ 104struct nonrt_sigframe { 105 UInt gap1[16]; 106 struct vki_sigcontext sigcontext; 107 struct vki_mcontext mcontext; 108 struct vg_sig_private priv; 109 unsigned char abigap[224]; // unused 110}; 111 112/* Structure put on stack for signal handlers with SA_SIGINFO set. */ 113struct rt_sigframe { 114 UInt gap1[20]; 115 vki_siginfo_t siginfo; 116 struct vki_ucontext ucontext; 117 struct vg_sig_private priv; 118 unsigned char abigap[224]; // unused 119}; 120 121#define SET_SIGNAL_LR(zztst, zzval) \ 122 do { tst->arch.vex.guest_LR = (zzval); \ 123 VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, \ 124 offsetof(VexGuestPPC32State,guest_LR), \ 125 sizeof(UWord) ); \ 126 } while (0) 127 128#define SET_SIGNAL_GPR(zztst, zzn, zzval) \ 129 do { tst->arch.vex.guest_GPR##zzn = (zzval); \ 130 VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, \ 131 offsetof(VexGuestPPC32State,guest_GPR##zzn), \ 132 sizeof(UWord) ); \ 133 } while (0) 134 135 136static 137void stack_mcontext ( struct vki_mcontext *mc, 138 ThreadState* tst, 139 Bool use_rt_sigreturn, 140 UInt fault_addr ) 141{ 142 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcontext", 143 (Addr)mc, sizeof(struct vki_pt_regs) ); 144 145# define DO(gpr) mc->mc_gregs[VKI_PT_R0+gpr] = tst->arch.vex.guest_GPR##gpr 146 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); 147 DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); 148 DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23); 149 DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31); 150# undef DO 151 152 mc->mc_gregs[VKI_PT_NIP] = tst->arch.vex.guest_CIA; 153 mc->mc_gregs[VKI_PT_MSR] = 0xf032; /* pretty arbitrary */ 154 mc->mc_gregs[VKI_PT_ORIG_R3] = tst->arch.vex.guest_GPR3; 155 mc->mc_gregs[VKI_PT_CTR] = tst->arch.vex.guest_CTR; 156 mc->mc_gregs[VKI_PT_LNK] = tst->arch.vex.guest_LR; 157 mc->mc_gregs[VKI_PT_XER] = LibVEX_GuestPPC32_get_XER(&tst->arch.vex); 158 mc->mc_gregs[VKI_PT_CCR] = LibVEX_GuestPPC32_get_CR(&tst->arch.vex); 159 mc->mc_gregs[VKI_PT_MQ] = 0; 160 mc->mc_gregs[VKI_PT_TRAP] = 0; 161 mc->mc_gregs[VKI_PT_DAR] = fault_addr; 162 mc->mc_gregs[VKI_PT_DSISR] = 0; 163 mc->mc_gregs[VKI_PT_RESULT] = 0; 164 VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, 165 (Addr)mc, sizeof(struct vki_pt_regs) ); 166 167 /* XXX should do FP and vector regs */ 168 169 /* set up signal return trampoline */ 170 /* NB. 5 Sept 07. mc->mc_pad[0..1] used to contain a the code to 171 which the signal handler returns, and it just did sys_sigreturn 172 or sys_rt_sigreturn. But this doesn't work if the stack is 173 non-executable, and it isn't consistent with the x86-linux and 174 amd64-linux scheme for removing the stack frame. So instead be 175 consistent and use a stub in m_trampoline. Then it doesn't 176 matter whether or not the (guest) stack is executable. This 177 fixes #149519 and #145837. */ 178 VG_TRACK(pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcontext", 179 (Addr)&mc->mc_pad, sizeof(mc->mc_pad)); 180 mc->mc_pad[0] = 0; /* invalid */ 181 mc->mc_pad[1] = 0; /* invalid */ 182 VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, 183 (Addr)&mc->mc_pad, sizeof(mc->mc_pad) ); 184 /* invalidate any translation of this area */ 185 VG_(discard_translations)( (Addr)&mc->mc_pad, 186 sizeof(mc->mc_pad), "stack_mcontext" ); 187 188 /* set the signal handler to return to the trampoline */ 189 SET_SIGNAL_LR(tst, (Addr)(use_rt_sigreturn 190 ? (Addr)&VG_(ppc32_linux_SUBST_FOR_rt_sigreturn) 191 : (Addr)&VG_(ppc32_linux_SUBST_FOR_sigreturn) 192 )); 193} 194 195//:: /* Valgrind-specific parts of the signal frame */ 196//:: struct vg_sigframe 197//:: { 198//:: /* Sanity check word. */ 199//:: UInt magicPI; 200//:: 201//:: UInt handlerflags; /* flags for signal handler */ 202//:: 203//:: 204//:: /* Safely-saved version of sigNo, as described above. */ 205//:: Int sigNo_private; 206//:: 207//:: /* XXX This is wrong. Surely we should store the shadow values 208//:: into the shadow memory behind the actual values? */ 209//:: VexGuestPPC32State vex_shadow; 210//:: 211//:: /* HACK ALERT */ 212//:: VexGuestPPC32State vex; 213//:: /* end HACK ALERT */ 214//:: 215//:: /* saved signal mask to be restored when handler returns */ 216//:: vki_sigset_t mask; 217//:: 218//:: /* Sanity check word. Is the highest-addressed word; do not 219//:: move!*/ 220//:: UInt magicE; 221//:: }; 222//:: 223//:: struct sigframe 224//:: { 225//:: /* Sig handler's return address */ 226//:: Addr retaddr; 227//:: Int sigNo; 228//:: 229//:: struct vki_sigcontext sigContext; 230//:: //.. struct _vki_fpstate fpstate; 231//:: 232//:: struct vg_sigframe vg; 233//:: }; 234//:: 235//:: struct rt_sigframe 236//:: { 237//:: /* Sig handler's return address */ 238//:: Addr retaddr; 239//:: Int sigNo; 240//:: 241//:: /* ptr to siginfo_t. */ 242//:: Addr psigInfo; 243//:: 244//:: /* ptr to ucontext */ 245//:: Addr puContext; 246//:: /* pointed to by psigInfo */ 247//:: vki_siginfo_t sigInfo; 248//:: 249//:: /* pointed to by puContext */ 250//:: struct vki_ucontext uContext; 251//:: //.. struct _vki_fpstate fpstate; 252//:: 253//:: struct vg_sigframe vg; 254//:: }; 255 256 257//:: /*------------------------------------------------------------*/ 258//:: /*--- Signal operations ---*/ 259//:: /*------------------------------------------------------------*/ 260//:: 261//:: /* 262//:: Great gobs of FP state conversion taken wholesale from 263//:: linux/arch/i386/kernel/i387.c 264//:: */ 265//:: 266//:: /* 267//:: * FXSR floating point environment conversions. 268//:: */ 269//:: #define X86_FXSR_MAGIC 0x0000 270//:: 271//:: /* 272//:: * FPU tag word conversions. 273//:: */ 274//:: 275//:: static inline unsigned short twd_i387_to_fxsr( unsigned short twd ) 276//:: { 277//:: unsigned int tmp; /* to avoid 16 bit prefixes in the code */ 278//:: 279//:: /* Transform each pair of bits into 01 (valid) or 00 (empty) */ 280//:: tmp = ~twd; 281//:: tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */ 282//:: /* and move the valid bits to the lower byte. */ 283//:: tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */ 284//:: tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */ 285//:: tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */ 286//:: return tmp; 287//:: } 288//:: 289//:: static unsigned long twd_fxsr_to_i387( const struct i387_fxsave_struct *fxsave ) 290//:: { 291//:: struct _vki_fpxreg *st = NULL; 292//:: unsigned long twd = (unsigned long) fxsave->twd; 293//:: unsigned long tag; 294//:: unsigned long ret = 0xffff0000u; 295//:: int i; 296//:: 297//:: #define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16); 298//:: 299//:: for ( i = 0 ; i < 8 ; i++ ) { 300//:: if ( twd & 0x1 ) { 301//:: st = (struct _vki_fpxreg *) FPREG_ADDR( fxsave, i ); 302//:: 303//:: switch ( st->exponent & 0x7fff ) { 304//:: case 0x7fff: 305//:: tag = 2; /* Special */ 306//:: break; 307//:: case 0x0000: 308//:: if ( !st->significand[0] && 309//:: !st->significand[1] && 310//:: !st->significand[2] && 311//:: !st->significand[3] ) { 312//:: tag = 1; /* Zero */ 313//:: } else { 314//:: tag = 2; /* Special */ 315//:: } 316//:: break; 317//:: default: 318//:: if ( st->significand[3] & 0x8000 ) { 319//:: tag = 0; /* Valid */ 320//:: } else { 321//:: tag = 2; /* Special */ 322//:: } 323//:: break; 324//:: } 325//:: } else { 326//:: tag = 3; /* Empty */ 327//:: } 328//:: ret |= (tag << (2 * i)); 329//:: twd = twd >> 1; 330//:: } 331//:: return ret; 332//:: } 333//:: 334//:: static void convert_fxsr_to_user( struct _vki_fpstate *buf, 335//:: const struct i387_fxsave_struct *fxsave ) 336//:: { 337//:: unsigned long env[7]; 338//:: struct _vki_fpreg *to; 339//:: struct _vki_fpxreg *from; 340//:: int i; 341//:: 342//:: env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul; 343//:: env[1] = (unsigned long)fxsave->swd | 0xffff0000ul; 344//:: env[2] = twd_fxsr_to_i387(fxsave); 345//:: env[3] = fxsave->fip; 346//:: env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16); 347//:: env[5] = fxsave->foo; 348//:: env[6] = fxsave->fos; 349//:: 350//:: VG_(memcpy)(buf, env, 7 * sizeof(unsigned long)); 351//:: 352//:: to = &buf->_st[0]; 353//:: from = (struct _vki_fpxreg *) &fxsave->st_space[0]; 354//:: for ( i = 0 ; i < 8 ; i++, to++, from++ ) { 355//:: unsigned long __user *t = (unsigned long __user *)to; 356//:: unsigned long *f = (unsigned long *)from; 357//:: 358//:: t[0] = f[0]; 359//:: t[1] = f[1]; 360//:: to->exponent = from->exponent; 361//:: } 362//:: } 363//:: 364//:: static void convert_fxsr_from_user( struct i387_fxsave_struct *fxsave, 365//:: const struct _vki_fpstate *buf ) 366//:: { 367//:: unsigned long env[7]; 368//:: struct _vki_fpxreg *to; 369//:: const struct _vki_fpreg *from; 370//:: int i; 371//:: 372//:: VG_(memcpy)(env, buf, 7 * sizeof(long)); 373//:: 374//:: fxsave->cwd = (unsigned short)(env[0] & 0xffff); 375//:: fxsave->swd = (unsigned short)(env[1] & 0xffff); 376//:: fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff)); 377//:: fxsave->fip = env[3]; 378//:: fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16); 379//:: fxsave->fcs = (env[4] & 0xffff); 380//:: fxsave->foo = env[5]; 381//:: fxsave->fos = env[6]; 382//:: 383//:: to = (struct _vki_fpxreg *) &fxsave->st_space[0]; 384//:: from = &buf->_st[0]; 385//:: for ( i = 0 ; i < 8 ; i++, to++, from++ ) { 386//:: unsigned long *t = (unsigned long *)to; 387//:: unsigned long __user *f = (unsigned long __user *)from; 388//:: 389//:: t[0] = f[0]; 390//:: t[1] = f[1]; 391//:: to->exponent = from->exponent; 392//:: } 393//:: } 394//:: 395//:: static inline void save_i387_fsave( arch_thread_t *regs, struct _vki_fpstate *buf ) 396//:: { 397//:: struct i387_fsave_struct *fs = ®s->m_sse.fsave; 398//:: 399//:: fs->status = fs->swd; 400//:: VG_(memcpy)(buf, fs, sizeof(*fs)); 401//:: } 402//:: 403//:: static void save_i387_fxsave( arch_thread_t *regs, struct _vki_fpstate *buf ) 404//:: { 405//:: const struct i387_fxsave_struct *fx = ®s->m_sse.fxsave; 406//:: convert_fxsr_to_user( buf, fx ); 407//:: 408//:: buf->status = fx->swd; 409//:: buf->magic = X86_FXSR_MAGIC; 410//:: VG_(memcpy)(buf->_fxsr_env, fx, sizeof(struct i387_fxsave_struct)); 411//:: } 412//:: 413//:: static void save_i387( arch_thread_t *regs, struct _vki_fpstate *buf ) 414//:: { 415//:: if ( VG_(have_ssestate) ) 416//:: save_i387_fxsave( regs, buf ); 417//:: else 418//:: save_i387_fsave( regs, buf ); 419//:: } 420//:: 421//:: static inline void restore_i387_fsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf ) 422//:: { 423//:: VG_(memcpy)( ®s->m_sse.fsave, buf, sizeof(struct i387_fsave_struct) ); 424//:: } 425//:: 426//:: static void restore_i387_fxsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf ) 427//:: { 428//:: VG_(memcpy)(®s->m_sse.fxsave, &buf->_fxsr_env[0], 429//:: sizeof(struct i387_fxsave_struct) ); 430//:: /* mxcsr reserved bits must be masked to zero for security reasons */ 431//:: regs->m_sse.fxsave.mxcsr &= 0xffbf; 432//:: convert_fxsr_from_user( ®s->m_sse.fxsave, buf ); 433//:: } 434//:: 435//:: static void restore_i387( arch_thread_t *regs, const struct _vki_fpstate __user *buf ) 436//:: { 437//:: if ( VG_(have_ssestate) ) { 438//:: restore_i387_fxsave( regs, buf ); 439//:: } else { 440//:: restore_i387_fsave( regs, buf ); 441//:: } 442//:: } 443 444 445 446 447/*------------------------------------------------------------*/ 448/*--- Creating signal frames ---*/ 449/*------------------------------------------------------------*/ 450 451//.. /* Create a plausible-looking sigcontext from the thread's 452//.. Vex guest state. NOTE: does not fill in the FP or SSE 453//.. bits of sigcontext at the moment. 454//.. */ 455//.. static 456//.. void synth_ucontext(ThreadId tid, const vki_siginfo_t *si, 457//.. const vki_sigset_t *set, struct vki_ucontext *uc) 458//.. { 459//.. ThreadState *tst = VG_(get_ThreadState)(tid); 460//.. struct vki_sigcontext *sc = &uc->uc_mcontext; 461//.. 462//.. VG_(memset)(uc, 0, sizeof(*uc)); 463//.. 464//.. uc->uc_flags = 0; 465//.. uc->uc_link = 0; 466//.. uc->uc_sigmask = *set; 467//.. uc->uc_stack = tst->altstack; 468//.. sc->fpstate = fpstate; 469//.. 470//.. // FIXME: save_i387(&tst->arch, fpstate); 471//.. 472//.. # define SC2(reg,REG) sc->reg = tst->arch.vex.guest_##REG 473//.. SC2(gs,GS); 474//.. SC2(fs,FS); 475//.. SC2(es,ES); 476//.. SC2(ds,DS); 477//.. 478//.. SC2(edi,EDI); 479//.. SC2(esi,ESI); 480//.. SC2(ebp,EBP); 481//.. SC2(esp,ESP); 482//.. SC2(ebx,EBX); 483//.. SC2(edx,EDX); 484//.. SC2(ecx,ECX); 485//.. SC2(eax,EAX); 486//.. 487//.. SC2(eip,EIP); 488//.. SC2(cs,CS); 489//.. sc->eflags = LibVEX_GuestX86_get_eflags(&tst->arch.vex); 490//.. SC2(ss,SS); 491//.. /* XXX esp_at_signal */ 492//.. /* XXX trapno */ 493//.. /* XXX err */ 494//.. # undef SC2 495//.. 496//.. sc->cr2 = (UInt)si->_sifields._sigfault._addr; 497//.. } 498/* 499//.. #define SET_SIGNAL_ESP(zztid, zzval) \ 500//.. SET_THREAD_REG(zztid, zzval, STACK_PTR, post_reg_write, \ 501//.. Vg_CoreSignal, zztid, VG_O_STACK_PTR, sizeof(Addr)) 502*/ 503 504 505//.. /* Build the Valgrind-specific part of a signal frame. */ 506//.. 507//.. static void build_vg_sigframe(struct vg_sigframe *frame, 508//.. ThreadState *tst, 509//.. const vki_sigset_t *mask, 510//.. UInt flags, 511//.. Int sigNo) 512//.. { 513//.. frame->sigNo_private = sigNo; 514//.. frame->magicPI = 0x31415927; 515//.. frame->vex_shadow = tst->arch.vex_shadow; 516//.. /* HACK ALERT */ 517//.. frame->vex = tst->arch.vex; 518//.. /* end HACK ALERT */ 519//.. frame->mask = tst->sig_mask; 520//.. frame->handlerflags = flags; 521//.. frame->magicE = 0x27182818; 522//.. } 523 524 525//.. static Addr build_sigframe(ThreadState *tst, 526//.. Addr esp_top_of_frame, 527//.. const vki_siginfo_t *siginfo, 528//.. void *handler, UInt flags, 529//.. const vki_sigset_t *mask, 530//.. void *restorer) 531//.. { 532//.. struct sigframe *frame; 533//.. Addr esp = esp_top_of_frame; 534//.. Int sigNo = siginfo->si_signo; 535//.. struct vki_ucontext uc; 536//.. 537//.. vg_assert((flags & VKI_SA_SIGINFO) == 0); 538//.. 539//.. esp -= sizeof(*frame); 540//.. esp = ROUNDDN(esp, 16); 541//.. frame = (struct sigframe *)esp; 542//.. 543//.. if (!extend(tst, esp, sizeof(*frame))) 544//.. return esp_top_of_frame; 545//.. 546//.. /* retaddr, sigNo, siguContext fields are to be written */ 547//.. VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame", 548//.. esp, offsetof(struct sigframe, vg) ); 549//.. 550//.. frame->sigNo = sigNo; 551//.. 552//.. if (flags & VKI_SA_RESTORER) 553//.. frame->retaddr = (Addr)restorer; 554//.. else 555//.. frame->retaddr 556//.. = VG_(client_trampoline_code)+VG_(tramp_sigreturn_offset); 557//.. 558//.. synth_ucontext(tst->tid, siginfo, mask, &uc, &frame->fpstate); 559//.. 560//.. VG_(memcpy)(&frame->sigContext, &uc.uc_mcontext, 561//.. sizeof(struct vki_sigcontext)); 562//.. frame->sigContext.oldmask = mask->sig[0]; 563//.. 564//.. VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, 565//.. esp, offsetof(struct sigframe, vg) ); 566//.. 567//.. build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo); 568//.. 569//.. return esp; 570//.. } 571 572 573//.. static Addr build_rt_sigframe(ThreadState *tst, 574//.. Addr esp_top_of_frame, 575//.. const vki_siginfo_t *siginfo, 576//.. void *handler, UInt flags, 577//.. const vki_sigset_t *mask, 578//.. void *restorer) 579//.. { 580//.. struct rt_sigframe *frame; 581//.. Addr esp = esp_top_of_frame; 582//.. Int sigNo = siginfo->si_signo; 583//.. 584//.. vg_assert((flags & VKI_SA_SIGINFO) != 0); 585//.. 586//.. esp -= sizeof(*frame); 587//.. esp = ROUNDDN(esp, 16); 588//.. frame = (struct rt_sigframe *)esp; 589//.. 590//.. if (!extend(tst, esp, sizeof(*frame))) 591//.. return esp_top_of_frame; 592//.. 593//.. /* retaddr, sigNo, pSiginfo, puContext fields are to be written */ 594//.. VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "rt signal handler frame", 595//.. esp, offsetof(struct rt_sigframe, vg) ); 596//.. 597//.. frame->sigNo = sigNo; 598//.. 599//.. if (flags & VKI_SA_RESTORER) 600//.. frame->retaddr = (Addr)restorer; 601//.. else 602//.. frame->retaddr 603//.. = VG_(client_trampoline_code)+VG_(tramp_rt_sigreturn_offset); 604//.. 605//.. frame->psigInfo = (Addr)&frame->sigInfo; 606//.. frame->puContext = (Addr)&frame->uContext; 607//.. VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t)); 608//.. 609//.. /* SIGILL defines addr to be the faulting address */ 610//.. if (sigNo == VKI_SIGILL && siginfo->si_code > 0) 611//.. frame->sigInfo._sifields._sigfault._addr 612//.. = (void*)tst->arch.vex.guest_CIA; 613//.. 614//.. synth_ucontext(tst->tid, siginfo, mask, &frame->uContext, &frame->fpstate); 615//.. 616//.. VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, 617//.. esp, offsetof(struct rt_sigframe, vg) ); 618//.. 619//.. build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo); 620//.. 621//.. return esp; 622//.. } 623 624 625/* EXPORTED */ 626void VG_(sigframe_create)( ThreadId tid, 627 Bool on_altstack, 628 Addr sp_top_of_frame, 629 const vki_siginfo_t *siginfo, 630 const struct vki_ucontext *siguc, 631 void *handler, 632 UInt flags, 633 const vki_sigset_t *mask, 634 void *restorer ) 635{ 636 struct vg_sig_private *priv; 637 Addr sp; 638 ThreadState *tst; 639 Int sigNo = siginfo->si_signo; 640 Addr faultaddr; 641 642 /* Stack must be 16-byte aligned */ 643 sp_top_of_frame &= ~0xf; 644 645 if (flags & VKI_SA_SIGINFO) { 646 sp = sp_top_of_frame - sizeof(struct rt_sigframe); 647 } else { 648 sp = sp_top_of_frame - sizeof(struct nonrt_sigframe); 649 } 650 651 tst = VG_(get_ThreadState)(tid); 652 653 if (! ML_(sf_maybe_extend_stack)(tst, sp, sp_top_of_frame - sp, flags)) 654 return; 655 656 vg_assert(VG_IS_16_ALIGNED(sp)); 657 658 /* Set up the stack chain pointer */ 659 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame", 660 sp, sizeof(UWord) ); 661 *(Addr *)sp = tst->arch.vex.guest_GPR1; 662 VG_TRACK( post_mem_write, Vg_CoreSignal, tid, 663 sp, sizeof(UWord) ); 664 665 faultaddr = (Addr)siginfo->_sifields._sigfault._addr; 666 if (sigNo == VKI_SIGILL && siginfo->si_code > 0) 667 faultaddr = tst->arch.vex.guest_CIA; 668 669 if (flags & VKI_SA_SIGINFO) { 670 struct rt_sigframe *frame = (struct rt_sigframe *) sp; 671 struct vki_ucontext *ucp = &frame->ucontext; 672 673 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame siginfo", 674 (Addr)&frame->siginfo, sizeof(frame->siginfo) ); 675 VG_(memcpy)(&frame->siginfo, siginfo, sizeof(*siginfo)); 676 VG_TRACK( post_mem_write, Vg_CoreSignal, tid, 677 (Addr)&frame->siginfo, sizeof(frame->siginfo) ); 678 679 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext", 680 (Addr)ucp, offsetof(struct vki_ucontext, uc_pad) ); 681 ucp->uc_flags = 0; 682 ucp->uc_link = 0; 683 ucp->uc_stack = tst->altstack; 684 VG_TRACK( post_mem_write, Vg_CoreSignal, tid, (Addr)ucp, 685 offsetof(struct vki_ucontext, uc_pad) ); 686 687 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext", 688 (Addr)&ucp->uc_regs, 689 sizeof(ucp->uc_regs) + sizeof(ucp->uc_sigmask) ); 690 ucp->uc_regs = &ucp->uc_mcontext; 691 ucp->uc_sigmask = tst->sig_mask; 692 VG_TRACK( post_mem_write, Vg_CoreSignal, tid, 693 (Addr)&ucp->uc_regs, 694 sizeof(ucp->uc_regs) + sizeof(ucp->uc_sigmask) ); 695 696 stack_mcontext(&ucp->uc_mcontext, tst, True/*use_rt_sigreturn*/, faultaddr); 697 priv = &frame->priv; 698 699 SET_SIGNAL_GPR(tid, 4, (Addr) &frame->siginfo); 700 SET_SIGNAL_GPR(tid, 5, (Addr) ucp); 701 /* the kernel sets this, though it doesn't seem to be in the ABI */ 702 SET_SIGNAL_GPR(tid, 6, (Addr) &frame->siginfo); 703 704 } else { 705 /* non-RT signal delivery */ 706 struct nonrt_sigframe *frame = (struct nonrt_sigframe *) sp; 707 struct vki_sigcontext *scp = &frame->sigcontext; 708 709 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame sigcontext", 710 (Addr)&scp->_unused[3], sizeof(*scp) - 3 * sizeof(UInt) ); 711 scp->signal = sigNo; 712 scp->handler = (Addr) handler; 713 scp->oldmask = tst->sig_mask.sig[0]; 714 scp->_unused[3] = tst->sig_mask.sig[1]; 715 VG_TRACK( post_mem_write, Vg_CoreSignal, tid, 716 (Addr)&scp->_unused[3], sizeof(*scp) - 3 * sizeof(UInt) ); 717 718 stack_mcontext(&frame->mcontext, tst, False/*!use_rt_sigreturn*/, faultaddr); 719 priv = &frame->priv; 720 721 SET_SIGNAL_GPR(tid, 4, (Addr) scp); 722 } 723 724 priv->magicPI = 0x31415927; 725 priv->sigNo_private = sigNo; 726 priv->vex_shadow1 = tst->arch.vex_shadow1; 727 priv->vex_shadow2 = tst->arch.vex_shadow2; 728 729 SET_SIGNAL_GPR(tid, 1, sp); 730 SET_SIGNAL_GPR(tid, 3, sigNo); 731 tst->arch.vex.guest_CIA = (Addr) handler; 732 733//.. Addr esp; 734//.. ThreadState* tst = VG_(get_ThreadState)(tid); 735//.. 736//.. if (flags & VKI_SA_SIGINFO) 737//.. esp = build_rt_sigframe(tst, esp_top_of_frame, siginfo, 738//.. handler, flags, mask, restorer); 739//.. else 740//.. esp = build_sigframe(tst, esp_top_of_frame, 741//.. siginfo, handler, flags, mask, restorer); 742//.. 743//.. /* Set the thread so it will next run the handler. */ 744//.. /* tst->m_esp = esp; */ 745//.. SET_SIGNAL_ESP(tid, esp); 746//.. 747//.. //VG_(printf)("handler = %p\n", handler); 748//.. tst->arch.vex.guest_CIA = (Addr) handler; 749//.. /* This thread needs to be marked runnable, but we leave that the 750//.. caller to do. */ 751 752 if (0) 753 VG_(printf)("pushed signal frame; %%R1 now = %#lx, " 754 "next %%CIA = %#x, status=%d\n", 755 sp, tst->arch.vex.guest_CIA, (Int)tst->status); 756} 757 758 759/*------------------------------------------------------------*/ 760/*--- Destroying signal frames ---*/ 761/*------------------------------------------------------------*/ 762 763//.. /* Return False and don't do anything, just set the client to take a 764//.. segfault, if it looks like the frame is corrupted. */ 765//.. static 766//.. Bool restore_vg_sigframe ( ThreadState *tst, 767//.. struct vg_sigframe *frame, Int *sigNo ) 768//.. { 769//.. if (frame->magicPI != 0x31415927 || 770//.. frame->magicE != 0x27182818) { 771//.. VG_(message)(Vg_UserMsg, "Thread %d return signal frame " 772//.. "corrupted. Killing process.", 773//.. tst->tid); 774//.. VG_(set_default_handler)(VKI_SIGSEGV); 775//.. VG_(synth_fault)(tst->tid); 776//.. *sigNo = VKI_SIGSEGV; 777//.. return False; 778//.. } 779//.. tst->sig_mask = frame->mask; 780//.. tst->tmp_sig_mask = frame->mask; 781//.. tst->arch.vex_shadow = frame->vex_shadow; 782//.. /* HACK ALERT */ 783//.. tst->arch.vex = frame->vex; 784//.. /* end HACK ALERT */ 785//.. *sigNo = frame->sigNo_private; 786//.. return True; 787//.. } 788 789//.. static 790//.. void restore_sigcontext( ThreadState *tst, 791//.. struct vki_sigcontext *sc ) 792//.. //.. struct vki_sigcontext *sc, struct _vki_fpstate *fpstate ) 793//.. { 794//.. tst->arch.vex.guest_EAX = sc->eax; 795//.. tst->arch.vex.guest_ECX = sc->ecx; 796//.. tst->arch.vex.guest_EDX = sc->edx; 797//.. tst->arch.vex.guest_EBX = sc->ebx; 798//.. tst->arch.vex.guest_EBP = sc->ebp; 799//.. tst->arch.vex.guest_ESP = sc->esp; 800//.. tst->arch.vex.guest_ESI = sc->esi; 801//.. tst->arch.vex.guest_EDI = sc->edi; 802//.. //:: tst->arch.vex.guest_eflags = sc->eflags; 803//.. //:: tst->arch.vex.guest_EIP = sc->eip; 804//.. 805//.. tst->arch.vex.guest_CS = sc->cs; 806//.. tst->arch.vex.guest_SS = sc->ss; 807//.. tst->arch.vex.guest_DS = sc->ds; 808//.. tst->arch.vex.guest_ES = sc->es; 809//.. tst->arch.vex.guest_FS = sc->fs; 810//.. tst->arch.vex.guest_GS = sc->gs; 811//.. 812//.. //:: restore_i387(&tst->arch, fpstate); 813//.. } 814 815 816//.. static 817//.. SizeT restore_sigframe ( ThreadState *tst, 818//.. struct sigframe *frame, Int *sigNo ) 819//.. { 820//.. if (restore_vg_sigframe(tst, &frame->vg, sigNo)) 821//.. restore_sigcontext(tst, &frame->sigContext, &frame->fpstate); 822//.. return sizeof(*frame); 823//.. } 824 825//.. static 826//.. SizeT restore_rt_sigframe ( ThreadState *tst, 827//.. struct rt_sigframe *frame, Int *sigNo ) 828//.. { 829//.. if (restore_vg_sigframe(tst, &frame->vg, sigNo)) 830//.. restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate); 831//.. return sizeof(*frame); 832//.. } 833 834 835/* EXPORTED */ 836void VG_(sigframe_destroy)( ThreadId tid, Bool isRT ) 837{ 838 ThreadState *tst; 839 struct vg_sig_private *priv; 840 Addr sp; 841 UInt frame_size; 842 struct vki_mcontext *mc; 843 Int sigNo; 844 Bool has_siginfo = isRT; 845 846 vg_assert(VG_(is_valid_tid)(tid)); 847 tst = VG_(get_ThreadState)(tid); 848 849 /* Check that the stack frame looks valid */ 850 sp = tst->arch.vex.guest_GPR1; 851 vg_assert(VG_IS_16_ALIGNED(sp)); 852 /* JRS 17 Nov 05: This code used to check that *sp -- which should 853 have been set by the stwu at the start of the handler -- points 854 to just above the frame (ie, the previous frame). However, that 855 isn't valid when delivering signals on alt stacks. So I removed 856 it. The frame is still sanity-checked using the priv->magicPI 857 field. */ 858 859 if (has_siginfo) { 860 struct rt_sigframe *frame = (struct rt_sigframe *)sp; 861 frame_size = sizeof(*frame); 862 mc = &frame->ucontext.uc_mcontext; 863 priv = &frame->priv; 864 vg_assert(priv->magicPI == 0x31415927); 865 tst->sig_mask = frame->ucontext.uc_sigmask; 866 } else { 867 struct nonrt_sigframe *frame = (struct nonrt_sigframe *)sp; 868 frame_size = sizeof(*frame); 869 mc = &frame->mcontext; 870 priv = &frame->priv; 871 vg_assert(priv->magicPI == 0x31415927); 872 tst->sig_mask.sig[0] = frame->sigcontext.oldmask; 873 tst->sig_mask.sig[1] = frame->sigcontext._unused[3]; 874 } 875 tst->tmp_sig_mask = tst->sig_mask; 876 877 sigNo = priv->sigNo_private; 878 879# define DO(gpr) tst->arch.vex.guest_GPR##gpr = mc->mc_gregs[VKI_PT_R0+gpr] 880 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7); 881 DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15); 882 DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23); 883 DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31); 884# undef DO 885 886 tst->arch.vex.guest_CIA = mc->mc_gregs[VKI_PT_NIP]; 887 888 // Umm ... ? (jrs 2005 July 8) 889 // tst->arch.m_orig_gpr3 = mc->mc_gregs[VKI_PT_ORIG_R3]; 890 891 LibVEX_GuestPPC32_put_CR( mc->mc_gregs[VKI_PT_CCR], &tst->arch.vex ); 892 893 tst->arch.vex.guest_LR = mc->mc_gregs[VKI_PT_LNK]; 894 tst->arch.vex.guest_CTR = mc->mc_gregs[VKI_PT_CTR]; 895 LibVEX_GuestPPC32_put_XER( mc->mc_gregs[VKI_PT_XER], &tst->arch.vex ); 896 897 tst->arch.vex_shadow1 = priv->vex_shadow1; 898 tst->arch.vex_shadow2 = priv->vex_shadow2; 899 900 VG_TRACK(die_mem_stack_signal, sp, frame_size); 901 902 if (VG_(clo_trace_signals)) 903 VG_(message)(Vg_DebugMsg, 904 "vg_pop_signal_frame (thread %u): " 905 "isRT=%d valid magic; EIP=%#x\n", 906 tid, has_siginfo, tst->arch.vex.guest_CIA); 907 908 /* tell the tools */ 909 VG_TRACK( post_deliver_signal, tid, sigNo ); 910 911//.. Addr esp; 912//.. ThreadState* tst; 913//.. SizeT size; 914//.. Int sigNo; 915//.. 916//.. tst = VG_(get_ThreadState)(tid); 917//.. 918//.. /* Correctly reestablish the frame base address. */ 919//.. esp = tst->arch.vex.guest_ESP; 920//.. 921//.. if (!isRT) 922//.. size = restore_sigframe(tst, (struct sigframe *)esp, &sigNo); 923//.. else 924//.. size = restore_rt_sigframe(tst, (struct rt_sigframe *)esp, &sigNo); 925//.. 926//.. VG_TRACK( die_mem_stack_signal, esp, size ); 927//.. 928//.. if (VG_(clo_trace_signals)) 929//.. VG_(message)( 930//.. Vg_DebugMsg, 931//.. "VG_(signal_return) (thread %u): isRT=%d valid magic; EIP=%p", 932//.. tid, isRT, tst->arch.vex.guest_EIP); 933//.. 934//.. /* tell the tools */ 935//.. VG_TRACK( post_deliver_signal, tid, sigNo ); 936} 937 938#endif // defined(VGP_ppc32_linux) 939 940/*--------------------------------------------------------------------*/ 941/*--- end ---*/ 942/*--------------------------------------------------------------------*/ 943