• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@valgrind.org
13    Copyright (C) 2004-2013 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_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
stack_mcontext(struct vki_mcontext * mc,ThreadState * tst,Bool use_rt_sigreturn,UInt fault_addr)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 */
extend(ThreadState * tst,Addr addr,SizeT size)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 */
VG_(sigframe_create)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 */
VG_(sigframe_destroy)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