2 /*--------------------------------------------------------------------*/
3 /*--- Create/destroy signal delivery frames. ---*/
4 /*--- sigframe-ppc32-linux.c ---*/
5 /*--------------------------------------------------------------------*/
8 This file is part of Valgrind, a dynamic binary instrumentation
11 Copyright (C) 2000-2013 Nicholas Nethercote
13 Copyright (C) 2004-2013 Paul Mackerras
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.
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.
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
31 The GNU General Public License is contained in the file COPYING.
34 #if defined(VGP_ppc32_linux)
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"
53 /* This module creates and removes signal frames for signal deliveries
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?
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
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.
77 /*------------------------------------------------------------*/
78 /*--- Signal frame layouts ---*/
79 /*------------------------------------------------------------*/
81 // A structure in which to save the application's registers
82 // during the execution of signal handlers.
84 // Linux has 2 signal frame structures: one for normal signal
85 // deliveries, and one for SA_SIGINFO deliveries (also known as RT
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.
94 /* Structure containing bits of information that we want to save
95 on signal delivery. */
96 struct vg_sig_private
{
99 VexGuestPPC32State vex_shadow1
;
100 VexGuestPPC32State vex_shadow2
;
103 /* Structure put on stack for signal handlers with SA_SIGINFO clear. */
104 struct nonrt_sigframe
{
106 struct vki_sigcontext sigcontext
;
107 struct vki_mcontext mcontext
;
108 struct vg_sig_private priv
;
109 unsigned char abigap
[224]; // unused
112 /* Structure put on stack for signal handlers with SA_SIGINFO set. */
115 vki_siginfo_t siginfo
;
116 struct vki_ucontext ucontext
;
117 struct vg_sig_private priv
;
118 unsigned char abigap
[224]; // unused
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), \
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), \
137 void stack_mcontext ( struct vki_mcontext
*mc
,
139 Bool use_rt_sigreturn
,
142 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tst
->tid
, "signal frame mcontext",
143 (Addr
)mc
, sizeof(struct vki_pt_regs
) );
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);
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
) );
167 /* XXX should do FP and vector regs */
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" );
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
)
195 //:: /* Valgrind-specific parts of the signal frame */
196 //:: struct vg_sigframe
198 //:: /* Sanity check word. */
201 //:: UInt handlerflags; /* flags for signal handler */
204 //:: /* Safely-saved version of sigNo, as described above. */
205 //:: Int sigNo_private;
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;
211 //:: /* HACK ALERT */
212 //:: VexGuestPPC32State vex;
213 //:: /* end HACK ALERT */
215 //:: /* saved signal mask to be restored when handler returns */
216 //:: vki_sigset_t mask;
218 //:: /* Sanity check word. Is the highest-addressed word; do not
225 //:: /* Sig handler's return address */
229 //:: struct vki_sigcontext sigContext;
230 //:: //.. struct _vki_fpstate fpstate;
232 //:: struct vg_sigframe vg;
235 //:: struct rt_sigframe
237 //:: /* Sig handler's return address */
241 //:: /* ptr to siginfo_t. */
244 //:: /* ptr to ucontext */
246 //:: /* pointed to by psigInfo */
247 //:: vki_siginfo_t sigInfo;
249 //:: /* pointed to by puContext */
250 //:: struct vki_ucontext uContext;
251 //:: //.. struct _vki_fpstate fpstate;
253 //:: struct vg_sigframe vg;
257 //:: /*------------------------------------------------------------*/
258 //:: /*--- Signal operations ---*/
259 //:: /*------------------------------------------------------------*/
262 //:: Great gobs of FP state conversion taken wholesale from
263 //:: linux/arch/i386/kernel/i387.c
267 //:: * FXSR floating point environment conversions.
269 //:: #define X86_FXSR_MAGIC 0x0000
272 //:: * FPU tag word conversions.
275 //:: static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
277 //:: unsigned int tmp; /* to avoid 16 bit prefixes in the code */
279 //:: /* Transform each pair of bits into 01 (valid) or 00 (empty) */
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 */
289 //:: static unsigned long twd_fxsr_to_i387( const struct i387_fxsave_struct *fxsave )
291 //:: struct _vki_fpxreg *st = NULL;
292 //:: unsigned long twd = (unsigned long) fxsave->twd;
293 //:: unsigned long tag;
294 //:: unsigned long ret = 0xffff0000u;
297 //:: #define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
299 //:: for ( i = 0 ; i < 8 ; i++ ) {
300 //:: if ( twd & 0x1 ) {
301 //:: st = (struct _vki_fpxreg *) FPREG_ADDR( fxsave, i );
303 //:: switch ( st->exponent & 0x7fff ) {
305 //:: tag = 2; /* Special */
308 //:: if ( !st->significand[0] &&
309 //:: !st->significand[1] &&
310 //:: !st->significand[2] &&
311 //:: !st->significand[3] ) {
312 //:: tag = 1; /* Zero */
314 //:: tag = 2; /* Special */
318 //:: if ( st->significand[3] & 0x8000 ) {
319 //:: tag = 0; /* Valid */
321 //:: tag = 2; /* Special */
326 //:: tag = 3; /* Empty */
328 //:: ret |= (tag << (2 * i));
334 //:: static void convert_fxsr_to_user( struct _vki_fpstate *buf,
335 //:: const struct i387_fxsave_struct *fxsave )
337 //:: unsigned long env[7];
338 //:: struct _vki_fpreg *to;
339 //:: struct _vki_fpxreg *from;
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;
350 //:: VG_(memcpy)(buf, env, 7 * sizeof(unsigned long));
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;
360 //:: to->exponent = from->exponent;
364 //:: static void convert_fxsr_from_user( struct i387_fxsave_struct *fxsave,
365 //:: const struct _vki_fpstate *buf )
367 //:: unsigned long env[7];
368 //:: struct _vki_fpxreg *to;
369 //:: const struct _vki_fpreg *from;
372 //:: VG_(memcpy)(env, buf, 7 * sizeof(long));
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];
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;
391 //:: to->exponent = from->exponent;
395 //:: static inline void save_i387_fsave( arch_thread_t *regs, struct _vki_fpstate *buf )
397 //:: struct i387_fsave_struct *fs = ®s->m_sse.fsave;
399 //:: fs->status = fs->swd;
400 //:: VG_(memcpy)(buf, fs, sizeof(*fs));
403 //:: static void save_i387_fxsave( arch_thread_t *regs, struct _vki_fpstate *buf )
405 //:: const struct i387_fxsave_struct *fx = ®s->m_sse.fxsave;
406 //:: convert_fxsr_to_user( buf, fx );
408 //:: buf->status = fx->swd;
409 //:: buf->magic = X86_FXSR_MAGIC;
410 //:: VG_(memcpy)(buf->_fxsr_env, fx, sizeof(struct i387_fxsave_struct));
413 //:: static void save_i387( arch_thread_t *regs, struct _vki_fpstate *buf )
415 //:: if ( VG_(have_ssestate) )
416 //:: save_i387_fxsave( regs, buf );
418 //:: save_i387_fsave( regs, buf );
421 //:: static inline void restore_i387_fsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
423 //:: VG_(memcpy)( ®s->m_sse.fsave, buf, sizeof(struct i387_fsave_struct) );
426 //:: static void restore_i387_fxsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
428 //:: VG_(memcpy)(®s->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( ®s->m_sse.fxsave, buf );
435 //:: static void restore_i387( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
437 //:: if ( VG_(have_ssestate) ) {
438 //:: restore_i387_fxsave( regs, buf );
440 //:: restore_i387_fsave( regs, buf );
447 /*------------------------------------------------------------*/
448 /*--- Creating signal frames ---*/
449 /*------------------------------------------------------------*/
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.
456 //.. void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,
457 //.. const vki_sigset_t *set, struct vki_ucontext *uc)
459 //.. ThreadState *tst = VG_(get_ThreadState)(tid);
460 //.. struct vki_sigcontext *sc = &uc->uc_mcontext;
462 //.. VG_(memset)(uc, 0, sizeof(*uc));
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;
470 //.. // FIXME: save_i387(&tst->arch, fpstate);
472 //.. # define SC2(reg,REG) sc->reg = tst->arch.vex.guest_##REG
489 //.. sc->eflags = LibVEX_GuestX86_get_eflags(&tst->arch.vex);
491 //.. /* XXX esp_at_signal */
492 //.. /* XXX trapno */
496 //.. sc->cr2 = (UInt)si->_sifields._sigfault._addr;
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))
505 //.. /* Build the Valgrind-specific part of a signal frame. */
507 //.. static void build_vg_sigframe(struct vg_sigframe *frame,
508 //.. ThreadState *tst,
509 //.. const vki_sigset_t *mask,
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;
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,
532 //.. struct sigframe *frame;
533 //.. Addr esp = esp_top_of_frame;
534 //.. Int sigNo = siginfo->si_signo;
535 //.. struct vki_ucontext uc;
537 //.. vg_assert((flags & VKI_SA_SIGINFO) == 0);
539 //.. esp -= sizeof(*frame);
540 //.. esp = ROUNDDN(esp, 16);
541 //.. frame = (struct sigframe *)esp;
543 //.. if (!extend(tst, esp, sizeof(*frame)))
544 //.. return esp_top_of_frame;
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) );
550 //.. frame->sigNo = sigNo;
552 //.. if (flags & VKI_SA_RESTORER)
553 //.. frame->retaddr = (Addr)restorer;
556 //.. = VG_(client_trampoline_code)+VG_(tramp_sigreturn_offset);
558 //.. synth_ucontext(tst->tid, siginfo, mask, &uc, &frame->fpstate);
560 //.. VG_(memcpy)(&frame->sigContext, &uc.uc_mcontext,
561 //.. sizeof(struct vki_sigcontext));
562 //.. frame->sigContext.oldmask = mask->sig[0];
564 //.. VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
565 //.. esp, offsetof(struct sigframe, vg) );
567 //.. build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
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,
580 //.. struct rt_sigframe *frame;
581 //.. Addr esp = esp_top_of_frame;
582 //.. Int sigNo = siginfo->si_signo;
584 //.. vg_assert((flags & VKI_SA_SIGINFO) != 0);
586 //.. esp -= sizeof(*frame);
587 //.. esp = ROUNDDN(esp, 16);
588 //.. frame = (struct rt_sigframe *)esp;
590 //.. if (!extend(tst, esp, sizeof(*frame)))
591 //.. return esp_top_of_frame;
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) );
597 //.. frame->sigNo = sigNo;
599 //.. if (flags & VKI_SA_RESTORER)
600 //.. frame->retaddr = (Addr)restorer;
603 //.. = VG_(client_trampoline_code)+VG_(tramp_rt_sigreturn_offset);
605 //.. frame->psigInfo = (Addr)&frame->sigInfo;
606 //.. frame->puContext = (Addr)&frame->uContext;
607 //.. VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
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;
614 //.. synth_ucontext(tst->tid, siginfo, mask, &frame->uContext, &frame->fpstate);
616 //.. VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
617 //.. esp, offsetof(struct rt_sigframe, vg) );
619 //.. build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
626 void VG_(sigframe_create
)( ThreadId tid
,
628 Addr sp_top_of_frame
,
629 const vki_siginfo_t
*siginfo
,
630 const struct vki_ucontext
*siguc
,
633 const vki_sigset_t
*mask
,
636 struct vg_sig_private
*priv
;
639 Int sigNo
= siginfo
->si_signo
;
642 /* Stack must be 16-byte aligned */
643 sp_top_of_frame
&= ~0xf;
645 if (flags
& VKI_SA_SIGINFO
) {
646 sp
= sp_top_of_frame
- sizeof(struct rt_sigframe
);
648 sp
= sp_top_of_frame
- sizeof(struct nonrt_sigframe
);
651 tst
= VG_(get_ThreadState
)(tid
);
653 if (! ML_(sf_maybe_extend_stack
)(tst
, sp
, sp_top_of_frame
- sp
, flags
))
656 vg_assert(VG_IS_16_ALIGNED(sp
));
658 /* Set up the stack chain pointer */
659 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tid
, "signal handler frame",
661 *(Addr
*)sp
= tst
->arch
.vex
.guest_GPR1
;
662 VG_TRACK( post_mem_write
, Vg_CoreSignal
, tid
,
665 faultaddr
= (Addr
)siginfo
->_sifields
._sigfault
._addr
;
666 if (sigNo
== VKI_SIGILL
&& siginfo
->si_code
> 0)
667 faultaddr
= tst
->arch
.vex
.guest_CIA
;
669 if (flags
& VKI_SA_SIGINFO
) {
670 struct rt_sigframe
*frame
= (struct rt_sigframe
*) sp
;
671 struct vki_ucontext
*ucp
= &frame
->ucontext
;
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
) );
679 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tid
, "signal frame ucontext",
680 (Addr
)ucp
, offsetof(struct vki_ucontext
, uc_pad
) );
683 ucp
->uc_stack
= tst
->altstack
;
684 VG_TRACK( post_mem_write
, Vg_CoreSignal
, tid
, (Addr
)ucp
,
685 offsetof(struct vki_ucontext
, uc_pad
) );
687 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tid
, "signal frame ucontext",
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
,
694 sizeof(ucp
->uc_regs
) + sizeof(ucp
->uc_sigmask
) );
696 stack_mcontext(&ucp
->uc_mcontext
, tst
, True
/*use_rt_sigreturn*/, faultaddr
);
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
);
705 /* non-RT signal delivery */
706 struct nonrt_sigframe
*frame
= (struct nonrt_sigframe
*) sp
;
707 struct vki_sigcontext
*scp
= &frame
->sigcontext
;
709 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tid
, "signal frame sigcontext",
710 (Addr
)&scp
->_unused
[3], sizeof(*scp
) - 3 * sizeof(UInt
) );
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
) );
718 stack_mcontext(&frame
->mcontext
, tst
, False
/*!use_rt_sigreturn*/, faultaddr
);
721 SET_SIGNAL_GPR(tid
, 4, (Addr
) scp
);
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
;
729 SET_SIGNAL_GPR(tid
, 1, sp
);
730 SET_SIGNAL_GPR(tid
, 3, sigNo
);
731 tst
->arch
.vex
.guest_CIA
= (Addr
) handler
;
734 //.. ThreadState* tst = VG_(get_ThreadState)(tid);
736 //.. if (flags & VKI_SA_SIGINFO)
737 //.. esp = build_rt_sigframe(tst, esp_top_of_frame, siginfo,
738 //.. handler, flags, mask, restorer);
740 //.. esp = build_sigframe(tst, esp_top_of_frame,
741 //.. siginfo, handler, flags, mask, restorer);
743 //.. /* Set the thread so it will next run the handler. */
744 //.. /* tst->m_esp = esp; */
745 //.. SET_SIGNAL_ESP(tid, esp);
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. */
753 VG_(printf
)("pushed signal frame; %%R1 now = %#lx, "
754 "next %%CIA = %#x, status=%d\n",
755 sp
, tst
->arch
.vex
.guest_CIA
, tst
->status
);
759 /*------------------------------------------------------------*/
760 /*--- Destroying signal frames ---*/
761 /*------------------------------------------------------------*/
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. */
766 //.. Bool restore_vg_sigframe ( ThreadState *tst,
767 //.. struct vg_sigframe *frame, Int *sigNo )
769 //.. if (frame->magicPI != 0x31415927 ||
770 //.. frame->magicE != 0x27182818) {
771 //.. VG_(message)(Vg_UserMsg, "Thread %d return signal frame "
772 //.. "corrupted. Killing process.",
774 //.. VG_(set_default_handler)(VKI_SIGSEGV);
775 //.. VG_(synth_fault)(tst->tid);
776 //.. *sigNo = VKI_SIGSEGV;
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;
790 //.. void restore_sigcontext( ThreadState *tst,
791 //.. struct vki_sigcontext *sc )
792 //.. //.. struct vki_sigcontext *sc, struct _vki_fpstate *fpstate )
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;
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;
812 //.. //:: restore_i387(&tst->arch, fpstate);
817 //.. SizeT restore_sigframe ( ThreadState *tst,
818 //.. struct sigframe *frame, Int *sigNo )
820 //.. if (restore_vg_sigframe(tst, &frame->vg, sigNo))
821 //.. restore_sigcontext(tst, &frame->sigContext, &frame->fpstate);
822 //.. return sizeof(*frame);
826 //.. SizeT restore_rt_sigframe ( ThreadState *tst,
827 //.. struct rt_sigframe *frame, Int *sigNo )
829 //.. if (restore_vg_sigframe(tst, &frame->vg, sigNo))
830 //.. restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate);
831 //.. return sizeof(*frame);
836 void VG_(sigframe_destroy
)( ThreadId tid
, Bool isRT
)
839 struct vg_sig_private
*priv
;
842 struct vki_mcontext
*mc
;
844 Bool has_siginfo
= isRT
;
846 vg_assert(VG_(is_valid_tid
)(tid
));
847 tst
= VG_(get_ThreadState
)(tid
);
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
860 struct rt_sigframe
*frame
= (struct rt_sigframe
*)sp
;
861 frame_size
= sizeof(*frame
);
862 mc
= &frame
->ucontext
.uc_mcontext
;
864 vg_assert(priv
->magicPI
== 0x31415927);
865 tst
->sig_mask
= frame
->ucontext
.uc_sigmask
;
867 struct nonrt_sigframe
*frame
= (struct nonrt_sigframe
*)sp
;
868 frame_size
= sizeof(*frame
);
869 mc
= &frame
->mcontext
;
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];
875 tst
->tmp_sig_mask
= tst
->sig_mask
;
877 sigNo
= priv
->sigNo_private
;
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);
886 tst
->arch
.vex
.guest_CIA
= mc
->mc_gregs
[VKI_PT_NIP
];
888 // Umm ... ? (jrs 2005 July 8)
889 // tst->arch.m_orig_gpr3 = mc->mc_gregs[VKI_PT_ORIG_R3];
891 LibVEX_GuestPPC32_put_CR( mc
->mc_gregs
[VKI_PT_CCR
], &tst
->arch
.vex
);
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
);
897 tst
->arch
.vex_shadow1
= priv
->vex_shadow1
;
898 tst
->arch
.vex_shadow2
= priv
->vex_shadow2
;
900 VG_TRACK(die_mem_stack_signal
, sp
, frame_size
);
902 if (VG_(clo_trace_signals
))
903 VG_(message
)(Vg_DebugMsg
,
904 "vg_pop_signal_frame (thread %d): "
905 "isRT=%d valid magic; EIP=%#x\n",
906 tid
, has_siginfo
, tst
->arch
.vex
.guest_CIA
);
909 VG_TRACK( post_deliver_signal
, tid
, sigNo
);
912 //.. ThreadState* tst;
916 //.. tst = VG_(get_ThreadState)(tid);
918 //.. /* Correctly reestablish the frame base address. */
919 //.. esp = tst->arch.vex.guest_ESP;
922 //.. size = restore_sigframe(tst, (struct sigframe *)esp, &sigNo);
924 //.. size = restore_rt_sigframe(tst, (struct rt_sigframe *)esp, &sigNo);
926 //.. VG_TRACK( die_mem_stack_signal, esp, size );
928 //.. if (VG_(clo_trace_signals))
931 //.. "VG_(signal_return) (thread %d): isRT=%d valid magic; EIP=%p",
932 //.. tid, isRT, tst->arch.vex.guest_EIP);
934 //.. /* tell the tools */
935 //.. VG_TRACK( post_deliver_signal, tid, sigNo );
938 #endif // defined(VGP_ppc32_linux)
940 /*--------------------------------------------------------------------*/
942 /*--------------------------------------------------------------------*/