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