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-2017 Nicholas Nethercote
13 Copyright (C) 2004-2017 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, see <http://www.gnu.org/licenses/>.
29 The GNU General Public License is contained in the file COPYING.
32 #if defined(VGP_ppc32_linux)
34 #include "pub_core_basics.h"
35 #include "pub_core_vki.h"
36 #include "pub_core_vkiscnums.h"
37 #include "pub_core_threadstate.h"
38 #include "pub_core_aspacemgr.h"
39 #include "pub_core_libcbase.h"
40 #include "pub_core_libcassert.h"
41 #include "pub_core_libcprint.h"
42 #include "pub_core_machine.h"
43 #include "pub_core_options.h"
44 #include "pub_core_sigframe.h"
45 #include "pub_core_signals.h"
46 #include "pub_core_tooliface.h"
47 #include "pub_core_trampoline.h"
48 #include "pub_core_transtab.h" // VG_(discard_translations)
49 #include "priv_sigframe.h"
51 /* This module creates and removes signal frames for signal deliveries
54 Note, this file contains kernel-specific knowledge in the form of
55 'struct sigframe' and 'struct rt_sigframe'. How does that relate
56 to the vki kernel interface stuff?
58 Either a 'struct sigframe' or a 'struct rtsigframe' is pushed
59 onto the client's stack. This contains a subsidiary
60 vki_ucontext. That holds the vcpu's state across the signal,
61 so that the sighandler can mess with the vcpu state if it
64 FIXME: sigcontexting is basically broken for the moment. When
65 delivering a signal, the integer registers and %eflags are
66 correctly written into the sigcontext, however the FP and SSE state
67 is not. When returning from a signal, only the integer registers
68 are restored from the sigcontext; the rest of the CPU state is
69 restored to what it was before the signal.
75 /*------------------------------------------------------------*/
76 /*--- Signal frame layouts ---*/
77 /*------------------------------------------------------------*/
79 // A structure in which to save the application's registers
80 // during the execution of signal handlers.
82 // Linux has 2 signal frame structures: one for normal signal
83 // deliveries, and one for SA_SIGINFO deliveries (also known as RT
86 // In theory, so long as we get the arguments to the handler function
87 // right, it doesn't matter what the exact layout of the rest of the
88 // frame is. Unfortunately, things like gcc's exception unwinding
89 // make assumptions about the locations of various parts of the frame,
90 // so we need to duplicate it exactly.
92 /* Structure containing bits of information that we want to save
93 on signal delivery. */
94 struct vg_sig_private
{
97 VexGuestPPC32State vex_shadow1
;
98 VexGuestPPC32State vex_shadow2
;
101 /* Structure put on stack for signal handlers with SA_SIGINFO clear. */
102 struct nonrt_sigframe
{
104 struct vki_sigcontext sigcontext
;
105 struct vki_mcontext mcontext
;
106 struct vg_sig_private priv
;
107 unsigned char abigap
[224]; // unused
110 /* Structure put on stack for signal handlers with SA_SIGINFO set. */
113 vki_siginfo_t siginfo
;
114 struct vki_ucontext ucontext
;
115 struct vg_sig_private priv
;
116 unsigned char abigap
[224]; // unused
119 #define SET_SIGNAL_LR(zztst, zzval) \
120 do { tst->arch.vex.guest_LR = (zzval); \
121 VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, \
122 offsetof(VexGuestPPC32State,guest_LR), \
126 #define SET_SIGNAL_GPR(zztst, zzn, zzval) \
127 do { tst->arch.vex.guest_GPR##zzn = (zzval); \
128 VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, \
129 offsetof(VexGuestPPC32State,guest_GPR##zzn), \
135 void stack_mcontext ( struct vki_mcontext
*mc
,
137 Bool use_rt_sigreturn
,
140 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tst
->tid
, "signal frame mcontext",
141 (Addr
)mc
, sizeof(struct vki_pt_regs
) );
143 # define DO(gpr) mc->mc_gregs[VKI_PT_R0+gpr] = tst->arch.vex.guest_GPR##gpr
144 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
145 DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
146 DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
147 DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
150 mc
->mc_gregs
[VKI_PT_NIP
] = tst
->arch
.vex
.guest_CIA
;
151 mc
->mc_gregs
[VKI_PT_MSR
] = 0xf032; /* pretty arbitrary */
152 mc
->mc_gregs
[VKI_PT_ORIG_R3
] = tst
->arch
.vex
.guest_GPR3
;
153 mc
->mc_gregs
[VKI_PT_CTR
] = tst
->arch
.vex
.guest_CTR
;
154 mc
->mc_gregs
[VKI_PT_LNK
] = tst
->arch
.vex
.guest_LR
;
155 mc
->mc_gregs
[VKI_PT_XER
] = LibVEX_GuestPPC32_get_XER(&tst
->arch
.vex
);
156 mc
->mc_gregs
[VKI_PT_CCR
] = LibVEX_GuestPPC32_get_CR(&tst
->arch
.vex
);
157 mc
->mc_gregs
[VKI_PT_MQ
] = 0;
158 mc
->mc_gregs
[VKI_PT_TRAP
] = 0;
159 mc
->mc_gregs
[VKI_PT_DAR
] = fault_addr
;
160 mc
->mc_gregs
[VKI_PT_DSISR
] = 0;
161 mc
->mc_gregs
[VKI_PT_RESULT
] = 0;
162 VG_TRACK( post_mem_write
, Vg_CoreSignal
, tst
->tid
,
163 (Addr
)mc
, sizeof(struct vki_pt_regs
) );
165 /* XXX should do FP and vector regs */
167 /* set up signal return trampoline */
168 /* NB. 5 Sept 07. mc->mc_pad[0..1] used to contain a the code to
169 which the signal handler returns, and it just did sys_sigreturn
170 or sys_rt_sigreturn. But this doesn't work if the stack is
171 non-executable, and it isn't consistent with the x86-linux and
172 amd64-linux scheme for removing the stack frame. So instead be
173 consistent and use a stub in m_trampoline. Then it doesn't
174 matter whether or not the (guest) stack is executable. This
175 fixes #149519 and #145837. */
176 VG_TRACK(pre_mem_write
, Vg_CoreSignal
, tst
->tid
, "signal frame mcontext",
177 (Addr
)&mc
->mc_pad
, sizeof(mc
->mc_pad
));
178 mc
->mc_pad
[0] = 0; /* invalid */
179 mc
->mc_pad
[1] = 0; /* invalid */
180 VG_TRACK( post_mem_write
, Vg_CoreSignal
, tst
->tid
,
181 (Addr
)&mc
->mc_pad
, sizeof(mc
->mc_pad
) );
182 /* invalidate any translation of this area */
183 VG_(discard_translations
)( (Addr
)&mc
->mc_pad
,
184 sizeof(mc
->mc_pad
), "stack_mcontext" );
186 /* set the signal handler to return to the trampoline */
187 SET_SIGNAL_LR(tst
, (Addr
)(use_rt_sigreturn
188 ? (Addr
)&VG_(ppc32_linux_SUBST_FOR_rt_sigreturn
)
189 : (Addr
)&VG_(ppc32_linux_SUBST_FOR_sigreturn
)
193 //:: /* Valgrind-specific parts of the signal frame */
194 //:: struct vg_sigframe
196 //:: /* Sanity check word. */
199 //:: UInt handlerflags; /* flags for signal handler */
202 //:: /* Safely-saved version of sigNo, as described above. */
203 //:: Int sigNo_private;
205 //:: /* XXX This is wrong. Surely we should store the shadow values
206 //:: into the shadow memory behind the actual values? */
207 //:: VexGuestPPC32State vex_shadow;
209 //:: /* HACK ALERT */
210 //:: VexGuestPPC32State vex;
211 //:: /* end HACK ALERT */
213 //:: /* saved signal mask to be restored when handler returns */
214 //:: vki_sigset_t mask;
216 //:: /* Sanity check word. Is the highest-addressed word; do not
223 //:: /* Sig handler's return address */
227 //:: struct vki_sigcontext sigContext;
228 //:: //.. struct _vki_fpstate fpstate;
230 //:: struct vg_sigframe vg;
233 //:: struct rt_sigframe
235 //:: /* Sig handler's return address */
239 //:: /* ptr to siginfo_t. */
242 //:: /* ptr to ucontext */
244 //:: /* pointed to by psigInfo */
245 //:: vki_siginfo_t sigInfo;
247 //:: /* pointed to by puContext */
248 //:: struct vki_ucontext uContext;
249 //:: //.. struct _vki_fpstate fpstate;
251 //:: struct vg_sigframe vg;
255 //:: /*------------------------------------------------------------*/
256 //:: /*--- Signal operations ---*/
257 //:: /*------------------------------------------------------------*/
260 //:: Great gobs of FP state conversion taken wholesale from
261 //:: linux/arch/i386/kernel/i387.c
265 //:: * FXSR floating point environment conversions.
267 //:: #define X86_FXSR_MAGIC 0x0000
270 //:: * FPU tag word conversions.
273 //:: static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
275 //:: unsigned int tmp; /* to avoid 16 bit prefixes in the code */
277 //:: /* Transform each pair of bits into 01 (valid) or 00 (empty) */
279 //:: tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
280 //:: /* and move the valid bits to the lower byte. */
281 //:: tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
282 //:: tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
283 //:: tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
287 //:: static unsigned long twd_fxsr_to_i387( const struct i387_fxsave_struct *fxsave )
289 //:: struct _vki_fpxreg *st = NULL;
290 //:: unsigned long twd = (unsigned long) fxsave->twd;
291 //:: unsigned long tag;
292 //:: unsigned long ret = 0xffff0000u;
295 //:: #define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
297 //:: for ( i = 0 ; i < 8 ; i++ ) {
298 //:: if ( twd & 0x1 ) {
299 //:: st = (struct _vki_fpxreg *) FPREG_ADDR( fxsave, i );
301 //:: switch ( st->exponent & 0x7fff ) {
303 //:: tag = 2; /* Special */
306 //:: if ( !st->significand[0] &&
307 //:: !st->significand[1] &&
308 //:: !st->significand[2] &&
309 //:: !st->significand[3] ) {
310 //:: tag = 1; /* Zero */
312 //:: tag = 2; /* Special */
316 //:: if ( st->significand[3] & 0x8000 ) {
317 //:: tag = 0; /* Valid */
319 //:: tag = 2; /* Special */
324 //:: tag = 3; /* Empty */
326 //:: ret |= (tag << (2 * i));
332 //:: static void convert_fxsr_to_user( struct _vki_fpstate *buf,
333 //:: const struct i387_fxsave_struct *fxsave )
335 //:: unsigned long env[7];
336 //:: struct _vki_fpreg *to;
337 //:: struct _vki_fpxreg *from;
340 //:: env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul;
341 //:: env[1] = (unsigned long)fxsave->swd | 0xffff0000ul;
342 //:: env[2] = twd_fxsr_to_i387(fxsave);
343 //:: env[3] = fxsave->fip;
344 //:: env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
345 //:: env[5] = fxsave->foo;
346 //:: env[6] = fxsave->fos;
348 //:: VG_(memcpy)(buf, env, 7 * sizeof(unsigned long));
350 //:: to = &buf->_st[0];
351 //:: from = (struct _vki_fpxreg *) &fxsave->st_space[0];
352 //:: for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
353 //:: unsigned long __user *t = (unsigned long __user *)to;
354 //:: unsigned long *f = (unsigned long *)from;
358 //:: to->exponent = from->exponent;
362 //:: static void convert_fxsr_from_user( struct i387_fxsave_struct *fxsave,
363 //:: const struct _vki_fpstate *buf )
365 //:: unsigned long env[7];
366 //:: struct _vki_fpxreg *to;
367 //:: const struct _vki_fpreg *from;
370 //:: VG_(memcpy)(env, buf, 7 * sizeof(long));
372 //:: fxsave->cwd = (unsigned short)(env[0] & 0xffff);
373 //:: fxsave->swd = (unsigned short)(env[1] & 0xffff);
374 //:: fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
375 //:: fxsave->fip = env[3];
376 //:: fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16);
377 //:: fxsave->fcs = (env[4] & 0xffff);
378 //:: fxsave->foo = env[5];
379 //:: fxsave->fos = env[6];
381 //:: to = (struct _vki_fpxreg *) &fxsave->st_space[0];
382 //:: from = &buf->_st[0];
383 //:: for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
384 //:: unsigned long *t = (unsigned long *)to;
385 //:: unsigned long __user *f = (unsigned long __user *)from;
389 //:: to->exponent = from->exponent;
393 //:: static inline void save_i387_fsave( arch_thread_t *regs, struct _vki_fpstate *buf )
395 //:: struct i387_fsave_struct *fs = ®s->m_sse.fsave;
397 //:: fs->status = fs->swd;
398 //:: VG_(memcpy)(buf, fs, sizeof(*fs));
401 //:: static void save_i387_fxsave( arch_thread_t *regs, struct _vki_fpstate *buf )
403 //:: const struct i387_fxsave_struct *fx = ®s->m_sse.fxsave;
404 //:: convert_fxsr_to_user( buf, fx );
406 //:: buf->status = fx->swd;
407 //:: buf->magic = X86_FXSR_MAGIC;
408 //:: VG_(memcpy)(buf->_fxsr_env, fx, sizeof(struct i387_fxsave_struct));
411 //:: static void save_i387( arch_thread_t *regs, struct _vki_fpstate *buf )
413 //:: if ( VG_(have_ssestate) )
414 //:: save_i387_fxsave( regs, buf );
416 //:: save_i387_fsave( regs, buf );
419 //:: static inline void restore_i387_fsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
421 //:: VG_(memcpy)( ®s->m_sse.fsave, buf, sizeof(struct i387_fsave_struct) );
424 //:: static void restore_i387_fxsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
426 //:: VG_(memcpy)(®s->m_sse.fxsave, &buf->_fxsr_env[0],
427 //:: sizeof(struct i387_fxsave_struct) );
428 //:: /* mxcsr reserved bits must be masked to zero for security reasons */
429 //:: regs->m_sse.fxsave.mxcsr &= 0xffbf;
430 //:: convert_fxsr_from_user( ®s->m_sse.fxsave, buf );
433 //:: static void restore_i387( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
435 //:: if ( VG_(have_ssestate) ) {
436 //:: restore_i387_fxsave( regs, buf );
438 //:: restore_i387_fsave( regs, buf );
445 /*------------------------------------------------------------*/
446 /*--- Creating signal frames ---*/
447 /*------------------------------------------------------------*/
449 //.. /* Create a plausible-looking sigcontext from the thread's
450 //.. Vex guest state. NOTE: does not fill in the FP or SSE
451 //.. bits of sigcontext at the moment.
454 //.. void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,
455 //.. const vki_sigset_t *set, struct vki_ucontext *uc)
457 //.. ThreadState *tst = VG_(get_ThreadState)(tid);
458 //.. struct vki_sigcontext *sc = &uc->uc_mcontext;
460 //.. VG_(memset)(uc, 0, sizeof(*uc));
462 //.. uc->uc_flags = 0;
463 //.. uc->uc_link = 0;
464 //.. uc->uc_sigmask = *set;
465 //.. uc->uc_stack = tst->altstack;
466 //.. sc->fpstate = fpstate;
468 //.. // FIXME: save_i387(&tst->arch, fpstate);
470 //.. # define SC2(reg,REG) sc->reg = tst->arch.vex.guest_##REG
487 //.. sc->eflags = LibVEX_GuestX86_get_eflags(&tst->arch.vex);
489 //.. /* XXX esp_at_signal */
490 //.. /* XXX trapno */
494 //.. sc->cr2 = (UInt)si->_sifields._sigfault._addr;
497 //.. #define SET_SIGNAL_ESP(zztid, zzval) \
498 //.. SET_THREAD_REG(zztid, zzval, STACK_PTR, post_reg_write, \
499 //.. Vg_CoreSignal, zztid, VG_O_STACK_PTR, sizeof(Addr))
503 //.. /* Build the Valgrind-specific part of a signal frame. */
505 //.. static void build_vg_sigframe(struct vg_sigframe *frame,
506 //.. ThreadState *tst,
507 //.. const vki_sigset_t *mask,
511 //.. frame->sigNo_private = sigNo;
512 //.. frame->magicPI = 0x31415927;
513 //.. frame->vex_shadow = tst->arch.vex_shadow;
514 //.. /* HACK ALERT */
515 //.. frame->vex = tst->arch.vex;
516 //.. /* end HACK ALERT */
517 //.. frame->mask = tst->sig_mask;
518 //.. frame->handlerflags = flags;
519 //.. frame->magicE = 0x27182818;
523 //.. static Addr build_sigframe(ThreadState *tst,
524 //.. Addr esp_top_of_frame,
525 //.. const vki_siginfo_t *siginfo,
526 //.. void *handler, UInt flags,
527 //.. const vki_sigset_t *mask,
530 //.. struct sigframe *frame;
531 //.. Addr esp = esp_top_of_frame;
532 //.. Int sigNo = siginfo->si_signo;
533 //.. struct vki_ucontext uc;
535 //.. vg_assert((flags & VKI_SA_SIGINFO) == 0);
537 //.. esp -= sizeof(*frame);
538 //.. esp = ROUNDDN(esp, 16);
539 //.. frame = (struct sigframe *)esp;
541 //.. if (!extend(tst, esp, sizeof(*frame)))
542 //.. return esp_top_of_frame;
544 //.. /* retaddr, sigNo, siguContext fields are to be written */
545 //.. VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame",
546 //.. esp, offsetof(struct sigframe, vg) );
548 //.. frame->sigNo = sigNo;
550 //.. if (flags & VKI_SA_RESTORER)
551 //.. frame->retaddr = (Addr)restorer;
554 //.. = VG_(client_trampoline_code)+VG_(tramp_sigreturn_offset);
556 //.. synth_ucontext(tst->tid, siginfo, mask, &uc, &frame->fpstate);
558 //.. VG_(memcpy)(&frame->sigContext, &uc.uc_mcontext,
559 //.. sizeof(struct vki_sigcontext));
560 //.. frame->sigContext.oldmask = mask->sig[0];
562 //.. VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
563 //.. esp, offsetof(struct sigframe, vg) );
565 //.. build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
571 //.. static Addr build_rt_sigframe(ThreadState *tst,
572 //.. Addr esp_top_of_frame,
573 //.. const vki_siginfo_t *siginfo,
574 //.. void *handler, UInt flags,
575 //.. const vki_sigset_t *mask,
578 //.. struct rt_sigframe *frame;
579 //.. Addr esp = esp_top_of_frame;
580 //.. Int sigNo = siginfo->si_signo;
582 //.. vg_assert((flags & VKI_SA_SIGINFO) != 0);
584 //.. esp -= sizeof(*frame);
585 //.. esp = ROUNDDN(esp, 16);
586 //.. frame = (struct rt_sigframe *)esp;
588 //.. if (!extend(tst, esp, sizeof(*frame)))
589 //.. return esp_top_of_frame;
591 //.. /* retaddr, sigNo, pSiginfo, puContext fields are to be written */
592 //.. VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "rt signal handler frame",
593 //.. esp, offsetof(struct rt_sigframe, vg) );
595 //.. frame->sigNo = sigNo;
597 //.. if (flags & VKI_SA_RESTORER)
598 //.. frame->retaddr = (Addr)restorer;
601 //.. = VG_(client_trampoline_code)+VG_(tramp_rt_sigreturn_offset);
603 //.. frame->psigInfo = (Addr)&frame->sigInfo;
604 //.. frame->puContext = (Addr)&frame->uContext;
605 //.. VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
607 //.. /* SIGILL defines addr to be the faulting address */
608 //.. if (sigNo == VKI_SIGILL && siginfo->si_code > 0)
609 //.. frame->sigInfo._sifields._sigfault._addr
610 //.. = (void*)tst->arch.vex.guest_CIA;
612 //.. synth_ucontext(tst->tid, siginfo, mask, &frame->uContext, &frame->fpstate);
614 //.. VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
615 //.. esp, offsetof(struct rt_sigframe, vg) );
617 //.. build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
624 void VG_(sigframe_create
)( ThreadId tid
,
626 Addr sp_top_of_frame
,
627 const vki_siginfo_t
*siginfo
,
628 const struct vki_ucontext
*siguc
,
631 const vki_sigset_t
*mask
,
634 struct vg_sig_private
*priv
;
637 Int sigNo
= siginfo
->si_signo
;
640 /* Stack must be 16-byte aligned */
641 sp_top_of_frame
&= ~0xf;
643 if (flags
& VKI_SA_SIGINFO
) {
644 sp
= sp_top_of_frame
- sizeof(struct rt_sigframe
);
646 sp
= sp_top_of_frame
- sizeof(struct nonrt_sigframe
);
649 tst
= VG_(get_ThreadState
)(tid
);
651 if (! ML_(sf_maybe_extend_stack
)(tst
, sp
, sp_top_of_frame
- sp
, flags
))
654 vg_assert(VG_IS_16_ALIGNED(sp
));
656 /* Set up the stack chain pointer */
657 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tid
, "signal handler frame",
659 *(Addr
*)sp
= tst
->arch
.vex
.guest_GPR1
;
660 VG_TRACK( post_mem_write
, Vg_CoreSignal
, tid
,
663 faultaddr
= (Addr
)siginfo
->_sifields
._sigfault
._addr
;
664 if (sigNo
== VKI_SIGILL
&& siginfo
->si_code
> 0)
665 faultaddr
= tst
->arch
.vex
.guest_CIA
;
667 if (flags
& VKI_SA_SIGINFO
) {
668 struct rt_sigframe
*frame
= (struct rt_sigframe
*) sp
;
669 struct vki_ucontext
*ucp
= &frame
->ucontext
;
671 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tid
, "signal frame siginfo",
672 (Addr
)&frame
->siginfo
, sizeof(frame
->siginfo
) );
673 VG_(memcpy
)(&frame
->siginfo
, siginfo
, sizeof(*siginfo
));
674 VG_TRACK( post_mem_write
, Vg_CoreSignal
, tid
,
675 (Addr
)&frame
->siginfo
, sizeof(frame
->siginfo
) );
677 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tid
, "signal frame ucontext",
678 (Addr
)ucp
, offsetof(struct vki_ucontext
, uc_pad
) );
681 ucp
->uc_stack
= tst
->altstack
;
682 VG_TRACK( post_mem_write
, Vg_CoreSignal
, tid
, (Addr
)ucp
,
683 offsetof(struct vki_ucontext
, uc_pad
) );
685 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tid
, "signal frame ucontext",
687 sizeof(ucp
->uc_regs
) + sizeof(ucp
->uc_sigmask
) );
688 ucp
->uc_regs
= &ucp
->uc_mcontext
;
689 ucp
->uc_sigmask
= tst
->sig_mask
;
690 VG_TRACK( post_mem_write
, Vg_CoreSignal
, tid
,
692 sizeof(ucp
->uc_regs
) + sizeof(ucp
->uc_sigmask
) );
694 stack_mcontext(&ucp
->uc_mcontext
, tst
, True
/*use_rt_sigreturn*/, faultaddr
);
697 SET_SIGNAL_GPR(tid
, 4, (Addr
) &frame
->siginfo
);
698 SET_SIGNAL_GPR(tid
, 5, (Addr
) ucp
);
699 /* the kernel sets this, though it doesn't seem to be in the ABI */
700 SET_SIGNAL_GPR(tid
, 6, (Addr
) &frame
->siginfo
);
703 /* non-RT signal delivery */
704 struct nonrt_sigframe
*frame
= (struct nonrt_sigframe
*) sp
;
705 struct vki_sigcontext
*scp
= &frame
->sigcontext
;
707 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tid
, "signal frame sigcontext",
708 (Addr
)&scp
->_unused
[3], sizeof(*scp
) - 3 * sizeof(UInt
) );
710 scp
->handler
= (Addr
) handler
;
711 scp
->oldmask
= tst
->sig_mask
.sig
[0];
712 scp
->_unused
[3] = tst
->sig_mask
.sig
[1];
713 VG_TRACK( post_mem_write
, Vg_CoreSignal
, tid
,
714 (Addr
)&scp
->_unused
[3], sizeof(*scp
) - 3 * sizeof(UInt
) );
716 stack_mcontext(&frame
->mcontext
, tst
, False
/*!use_rt_sigreturn*/, faultaddr
);
719 SET_SIGNAL_GPR(tid
, 4, (Addr
) scp
);
722 priv
->magicPI
= 0x31415927;
723 priv
->sigNo_private
= sigNo
;
724 priv
->vex_shadow1
= tst
->arch
.vex_shadow1
;
725 priv
->vex_shadow2
= tst
->arch
.vex_shadow2
;
727 SET_SIGNAL_GPR(tid
, 1, sp
);
728 SET_SIGNAL_GPR(tid
, 3, sigNo
);
729 tst
->arch
.vex
.guest_CIA
= (Addr
) handler
;
732 //.. ThreadState* tst = VG_(get_ThreadState)(tid);
734 //.. if (flags & VKI_SA_SIGINFO)
735 //.. esp = build_rt_sigframe(tst, esp_top_of_frame, siginfo,
736 //.. handler, flags, mask, restorer);
738 //.. esp = build_sigframe(tst, esp_top_of_frame,
739 //.. siginfo, handler, flags, mask, restorer);
741 //.. /* Set the thread so it will next run the handler. */
742 //.. /* tst->m_esp = esp; */
743 //.. SET_SIGNAL_ESP(tid, esp);
745 //.. //VG_(printf)("handler = %p\n", handler);
746 //.. tst->arch.vex.guest_CIA = (Addr) handler;
747 //.. /* This thread needs to be marked runnable, but we leave that the
748 //.. caller to do. */
751 VG_(printf
)("pushed signal frame; %%R1 now = %#lx, "
752 "next %%CIA = %#x, status=%d\n",
753 sp
, tst
->arch
.vex
.guest_CIA
, (Int
)tst
->status
);
757 /*------------------------------------------------------------*/
758 /*--- Destroying signal frames ---*/
759 /*------------------------------------------------------------*/
761 //.. /* Return False and don't do anything, just set the client to take a
762 //.. segfault, if it looks like the frame is corrupted. */
764 //.. Bool restore_vg_sigframe ( ThreadState *tst,
765 //.. struct vg_sigframe *frame, Int *sigNo )
767 //.. if (frame->magicPI != 0x31415927 ||
768 //.. frame->magicE != 0x27182818) {
769 //.. VG_(message)(Vg_UserMsg, "Thread %d return signal frame "
770 //.. "corrupted. Killing process.",
772 //.. VG_(set_default_handler)(VKI_SIGSEGV);
773 //.. VG_(synth_fault)(tst->tid);
774 //.. *sigNo = VKI_SIGSEGV;
777 //.. tst->sig_mask = frame->mask;
778 //.. tst->tmp_sig_mask = frame->mask;
779 //.. tst->arch.vex_shadow = frame->vex_shadow;
780 //.. /* HACK ALERT */
781 //.. tst->arch.vex = frame->vex;
782 //.. /* end HACK ALERT */
783 //.. *sigNo = frame->sigNo_private;
788 //.. void restore_sigcontext( ThreadState *tst,
789 //.. struct vki_sigcontext *sc )
790 //.. //.. struct vki_sigcontext *sc, struct _vki_fpstate *fpstate )
792 //.. tst->arch.vex.guest_EAX = sc->eax;
793 //.. tst->arch.vex.guest_ECX = sc->ecx;
794 //.. tst->arch.vex.guest_EDX = sc->edx;
795 //.. tst->arch.vex.guest_EBX = sc->ebx;
796 //.. tst->arch.vex.guest_EBP = sc->ebp;
797 //.. tst->arch.vex.guest_ESP = sc->esp;
798 //.. tst->arch.vex.guest_ESI = sc->esi;
799 //.. tst->arch.vex.guest_EDI = sc->edi;
800 //.. //:: tst->arch.vex.guest_eflags = sc->eflags;
801 //.. //:: tst->arch.vex.guest_EIP = sc->eip;
803 //.. tst->arch.vex.guest_CS = sc->cs;
804 //.. tst->arch.vex.guest_SS = sc->ss;
805 //.. tst->arch.vex.guest_DS = sc->ds;
806 //.. tst->arch.vex.guest_ES = sc->es;
807 //.. tst->arch.vex.guest_FS = sc->fs;
808 //.. tst->arch.vex.guest_GS = sc->gs;
810 //.. //:: restore_i387(&tst->arch, fpstate);
815 //.. SizeT restore_sigframe ( ThreadState *tst,
816 //.. struct sigframe *frame, Int *sigNo )
818 //.. if (restore_vg_sigframe(tst, &frame->vg, sigNo))
819 //.. restore_sigcontext(tst, &frame->sigContext, &frame->fpstate);
820 //.. return sizeof(*frame);
824 //.. SizeT restore_rt_sigframe ( ThreadState *tst,
825 //.. struct rt_sigframe *frame, Int *sigNo )
827 //.. if (restore_vg_sigframe(tst, &frame->vg, sigNo))
828 //.. restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate);
829 //.. return sizeof(*frame);
834 void VG_(sigframe_destroy
)( ThreadId tid
, Bool isRT
)
837 struct vg_sig_private
*priv
;
840 struct vki_mcontext
*mc
;
842 Bool has_siginfo
= isRT
;
844 vg_assert(VG_(is_valid_tid
)(tid
));
845 tst
= VG_(get_ThreadState
)(tid
);
847 /* Check that the stack frame looks valid */
848 sp
= tst
->arch
.vex
.guest_GPR1
;
849 vg_assert(VG_IS_16_ALIGNED(sp
));
850 /* JRS 17 Nov 05: This code used to check that *sp -- which should
851 have been set by the stwu at the start of the handler -- points
852 to just above the frame (ie, the previous frame). However, that
853 isn't valid when delivering signals on alt stacks. So I removed
854 it. The frame is still sanity-checked using the priv->magicPI
858 struct rt_sigframe
*frame
= (struct rt_sigframe
*)sp
;
859 frame_size
= sizeof(*frame
);
860 mc
= &frame
->ucontext
.uc_mcontext
;
862 vg_assert(priv
->magicPI
== 0x31415927);
863 tst
->sig_mask
= frame
->ucontext
.uc_sigmask
;
865 struct nonrt_sigframe
*frame
= (struct nonrt_sigframe
*)sp
;
866 frame_size
= sizeof(*frame
);
867 mc
= &frame
->mcontext
;
869 vg_assert(priv
->magicPI
== 0x31415927);
870 tst
->sig_mask
.sig
[0] = frame
->sigcontext
.oldmask
;
871 tst
->sig_mask
.sig
[1] = frame
->sigcontext
._unused
[3];
873 tst
->tmp_sig_mask
= tst
->sig_mask
;
875 sigNo
= priv
->sigNo_private
;
877 # define DO(gpr) tst->arch.vex.guest_GPR##gpr = mc->mc_gregs[VKI_PT_R0+gpr]
878 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
879 DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
880 DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
881 DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
884 tst
->arch
.vex
.guest_CIA
= mc
->mc_gregs
[VKI_PT_NIP
];
886 // Umm ... ? (jrs 2005 July 8)
887 // tst->arch.m_orig_gpr3 = mc->mc_gregs[VKI_PT_ORIG_R3];
889 LibVEX_GuestPPC32_put_CR( mc
->mc_gregs
[VKI_PT_CCR
], &tst
->arch
.vex
);
891 tst
->arch
.vex
.guest_LR
= mc
->mc_gregs
[VKI_PT_LNK
];
892 tst
->arch
.vex
.guest_CTR
= mc
->mc_gregs
[VKI_PT_CTR
];
893 LibVEX_GuestPPC32_put_XER( mc
->mc_gregs
[VKI_PT_XER
], &tst
->arch
.vex
);
895 tst
->arch
.vex_shadow1
= priv
->vex_shadow1
;
896 tst
->arch
.vex_shadow2
= priv
->vex_shadow2
;
898 VG_TRACK(die_mem_stack_signal
, sp
, frame_size
);
900 if (VG_(clo_trace_signals
))
901 VG_(message
)(Vg_DebugMsg
,
902 "vg_pop_signal_frame (thread %u): "
903 "isRT=%d valid magic; EIP=%#x\n",
904 tid
, has_siginfo
, tst
->arch
.vex
.guest_CIA
);
907 VG_TRACK( post_deliver_signal
, tid
, sigNo
);
910 //.. ThreadState* tst;
914 //.. tst = VG_(get_ThreadState)(tid);
916 //.. /* Correctly reestablish the frame base address. */
917 //.. esp = tst->arch.vex.guest_ESP;
920 //.. size = restore_sigframe(tst, (struct sigframe *)esp, &sigNo);
922 //.. size = restore_rt_sigframe(tst, (struct rt_sigframe *)esp, &sigNo);
924 //.. VG_TRACK( die_mem_stack_signal, esp, size );
926 //.. if (VG_(clo_trace_signals))
929 //.. "VG_(signal_return) (thread %u): isRT=%d valid magic; EIP=%p",
930 //.. tid, isRT, tst->arch.vex.guest_EIP);
932 //.. /* tell the tools */
933 //.. VG_TRACK( post_deliver_signal, tid, sigNo );
936 #endif // defined(VGP_ppc32_linux)
938 /*--------------------------------------------------------------------*/
940 /*--------------------------------------------------------------------*/