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@valgrind.org
13    Copyright (C) 2004-2017 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. */
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
stack_mcontext(struct vki_mcontext * mc,ThreadState * tst,Bool use_rt_sigreturn,UInt fault_addr)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 */
VG_(sigframe_create)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 */
VG_(sigframe_destroy)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