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. */
97struct 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. */
105struct 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. */
114struct 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
137static
138void 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*/
509static 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 */
669void 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 */
878void 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