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-2017 Nicholas Nethercote
     12       njn (at) valgrind.org
     13    Copyright (C) 2004-2017 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_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. */
     96 struct 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. */
    104 struct 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. */
    113 struct 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 
    136 static
    137 void 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 = &regs->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 = &regs->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)( &regs->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)(&regs->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( &regs->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 */
    626 void 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 */
    836 void 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