tests/vg_regtest: Always evaluate prerequisite expressions with sh
[valgrind.git] / coregrind / m_sigframe / sigframe-ppc32-linux.c
blob504480e705a80f382e797d975c0aee6407989610
2 /*--------------------------------------------------------------------*/
3 /*--- Create/destroy signal delivery frames. ---*/
4 /*--- sigframe-ppc32-linux.c ---*/
5 /*--------------------------------------------------------------------*/
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
11 Copyright (C) 2000-2013 Nicholas Nethercote
12 njn@valgrind.org
13 Copyright (C) 2004-2013 Paul Mackerras
14 paulus@samba.org
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
29 02111-1307, USA.
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
54 on ppc32-linux.
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
64 really wants.
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.
73 This will be fixed.
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
86 // signals).
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 {
97 UInt magicPI;
98 UInt sigNo_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 {
105 UInt gap1[16];
106 struct vki_sigcontext sigcontext;
107 struct vki_mcontext mcontext;
108 struct vg_sig_private priv;
109 unsigned char abigap[224]; // unused
112 /* Structure put on stack for signal handlers with SA_SIGINFO set. */
113 struct rt_sigframe {
114 UInt gap1[20];
115 vki_siginfo_t siginfo;
116 struct vki_ucontext ucontext;
117 struct vg_sig_private priv;
118 unsigned char abigap[224]; // unused
121 #define SET_SIGNAL_LR(zztst, zzval) \
122 do { tst->arch.vex.guest_LR = (zzval); \
123 VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, \
124 offsetof(VexGuestPPC32State,guest_LR), \
125 sizeof(UWord) ); \
126 } while (0)
128 #define SET_SIGNAL_GPR(zztst, zzn, zzval) \
129 do { tst->arch.vex.guest_GPR##zzn = (zzval); \
130 VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, \
131 offsetof(VexGuestPPC32State,guest_GPR##zzn), \
132 sizeof(UWord) ); \
133 } while (0)
136 static
137 void stack_mcontext ( struct vki_mcontext *mc,
138 ThreadState* tst,
139 Bool use_rt_sigreturn,
140 UInt fault_addr )
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);
150 # undef DO
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
197 //:: {
198 //:: /* Sanity check word. */
199 //:: UInt magicPI;
200 //::
201 //:: UInt handlerflags; /* flags for signal handler */
202 //::
203 //::
204 //:: /* Safely-saved version of sigNo, as described above. */
205 //:: Int sigNo_private;
206 //::
207 //:: /* XXX This is wrong. Surely we should store the shadow values
208 //:: into the shadow memory behind the actual values? */
209 //:: VexGuestPPC32State vex_shadow;
210 //::
211 //:: /* HACK ALERT */
212 //:: VexGuestPPC32State vex;
213 //:: /* end HACK ALERT */
214 //::
215 //:: /* saved signal mask to be restored when handler returns */
216 //:: vki_sigset_t mask;
217 //::
218 //:: /* Sanity check word. Is the highest-addressed word; do not
219 //:: move!*/
220 //:: UInt magicE;
221 //:: };
222 //::
223 //:: struct sigframe
224 //:: {
225 //:: /* Sig handler's return address */
226 //:: Addr retaddr;
227 //:: Int sigNo;
228 //::
229 //:: struct vki_sigcontext sigContext;
230 //:: //.. struct _vki_fpstate fpstate;
231 //::
232 //:: struct vg_sigframe vg;
233 //:: };
234 //::
235 //:: struct rt_sigframe
236 //:: {
237 //:: /* Sig handler's return address */
238 //:: Addr retaddr;
239 //:: Int sigNo;
240 //::
241 //:: /* ptr to siginfo_t. */
242 //:: Addr psigInfo;
243 //::
244 //:: /* ptr to ucontext */
245 //:: Addr puContext;
246 //:: /* pointed to by psigInfo */
247 //:: vki_siginfo_t sigInfo;
248 //::
249 //:: /* pointed to by puContext */
250 //:: struct vki_ucontext uContext;
251 //:: //.. struct _vki_fpstate fpstate;
252 //::
253 //:: struct vg_sigframe vg;
254 //:: };
257 //:: /*------------------------------------------------------------*/
258 //:: /*--- Signal operations ---*/
259 //:: /*------------------------------------------------------------*/
260 //::
261 //:: /*
262 //:: Great gobs of FP state conversion taken wholesale from
263 //:: linux/arch/i386/kernel/i387.c
264 //:: */
265 //::
266 //:: /*
267 //:: * FXSR floating point environment conversions.
268 //:: */
269 //:: #define X86_FXSR_MAGIC 0x0000
270 //::
271 //:: /*
272 //:: * FPU tag word conversions.
273 //:: */
274 //::
275 //:: static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
276 //:: {
277 //:: unsigned int tmp; /* to avoid 16 bit prefixes in the code */
278 //::
279 //:: /* Transform each pair of bits into 01 (valid) or 00 (empty) */
280 //:: tmp = ~twd;
281 //:: tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
282 //:: /* and move the valid bits to the lower byte. */
283 //:: tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
284 //:: tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
285 //:: tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
286 //:: return tmp;
287 //:: }
288 //::
289 //:: static unsigned long twd_fxsr_to_i387( const struct i387_fxsave_struct *fxsave )
290 //:: {
291 //:: struct _vki_fpxreg *st = NULL;
292 //:: unsigned long twd = (unsigned long) fxsave->twd;
293 //:: unsigned long tag;
294 //:: unsigned long ret = 0xffff0000u;
295 //:: int i;
296 //::
297 //:: #define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
298 //::
299 //:: for ( i = 0 ; i < 8 ; i++ ) {
300 //:: if ( twd & 0x1 ) {
301 //:: st = (struct _vki_fpxreg *) FPREG_ADDR( fxsave, i );
302 //::
303 //:: switch ( st->exponent & 0x7fff ) {
304 //:: case 0x7fff:
305 //:: tag = 2; /* Special */
306 //:: break;
307 //:: case 0x0000:
308 //:: if ( !st->significand[0] &&
309 //:: !st->significand[1] &&
310 //:: !st->significand[2] &&
311 //:: !st->significand[3] ) {
312 //:: tag = 1; /* Zero */
313 //:: } else {
314 //:: tag = 2; /* Special */
315 //:: }
316 //:: break;
317 //:: default:
318 //:: if ( st->significand[3] & 0x8000 ) {
319 //:: tag = 0; /* Valid */
320 //:: } else {
321 //:: tag = 2; /* Special */
322 //:: }
323 //:: break;
324 //:: }
325 //:: } else {
326 //:: tag = 3; /* Empty */
327 //:: }
328 //:: ret |= (tag << (2 * i));
329 //:: twd = twd >> 1;
330 //:: }
331 //:: return ret;
332 //:: }
333 //::
334 //:: static void convert_fxsr_to_user( struct _vki_fpstate *buf,
335 //:: const struct i387_fxsave_struct *fxsave )
336 //:: {
337 //:: unsigned long env[7];
338 //:: struct _vki_fpreg *to;
339 //:: struct _vki_fpxreg *from;
340 //:: int i;
341 //::
342 //:: env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul;
343 //:: env[1] = (unsigned long)fxsave->swd | 0xffff0000ul;
344 //:: env[2] = twd_fxsr_to_i387(fxsave);
345 //:: env[3] = fxsave->fip;
346 //:: env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
347 //:: env[5] = fxsave->foo;
348 //:: env[6] = fxsave->fos;
349 //::
350 //:: VG_(memcpy)(buf, env, 7 * sizeof(unsigned long));
351 //::
352 //:: to = &buf->_st[0];
353 //:: from = (struct _vki_fpxreg *) &fxsave->st_space[0];
354 //:: for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
355 //:: unsigned long __user *t = (unsigned long __user *)to;
356 //:: unsigned long *f = (unsigned long *)from;
357 //::
358 //:: t[0] = f[0];
359 //:: t[1] = f[1];
360 //:: to->exponent = from->exponent;
361 //:: }
362 //:: }
363 //::
364 //:: static void convert_fxsr_from_user( struct i387_fxsave_struct *fxsave,
365 //:: const struct _vki_fpstate *buf )
366 //:: {
367 //:: unsigned long env[7];
368 //:: struct _vki_fpxreg *to;
369 //:: const struct _vki_fpreg *from;
370 //:: int i;
371 //::
372 //:: VG_(memcpy)(env, buf, 7 * sizeof(long));
373 //::
374 //:: fxsave->cwd = (unsigned short)(env[0] & 0xffff);
375 //:: fxsave->swd = (unsigned short)(env[1] & 0xffff);
376 //:: fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
377 //:: fxsave->fip = env[3];
378 //:: fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16);
379 //:: fxsave->fcs = (env[4] & 0xffff);
380 //:: fxsave->foo = env[5];
381 //:: fxsave->fos = env[6];
382 //::
383 //:: to = (struct _vki_fpxreg *) &fxsave->st_space[0];
384 //:: from = &buf->_st[0];
385 //:: for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
386 //:: unsigned long *t = (unsigned long *)to;
387 //:: unsigned long __user *f = (unsigned long __user *)from;
388 //::
389 //:: t[0] = f[0];
390 //:: t[1] = f[1];
391 //:: to->exponent = from->exponent;
392 //:: }
393 //:: }
394 //::
395 //:: static inline void save_i387_fsave( arch_thread_t *regs, struct _vki_fpstate *buf )
396 //:: {
397 //:: struct i387_fsave_struct *fs = &regs->m_sse.fsave;
398 //::
399 //:: fs->status = fs->swd;
400 //:: VG_(memcpy)(buf, fs, sizeof(*fs));
401 //:: }
402 //::
403 //:: static void save_i387_fxsave( arch_thread_t *regs, struct _vki_fpstate *buf )
404 //:: {
405 //:: const struct i387_fxsave_struct *fx = &regs->m_sse.fxsave;
406 //:: convert_fxsr_to_user( buf, fx );
407 //::
408 //:: buf->status = fx->swd;
409 //:: buf->magic = X86_FXSR_MAGIC;
410 //:: VG_(memcpy)(buf->_fxsr_env, fx, sizeof(struct i387_fxsave_struct));
411 //:: }
412 //::
413 //:: static void save_i387( arch_thread_t *regs, struct _vki_fpstate *buf )
414 //:: {
415 //:: if ( VG_(have_ssestate) )
416 //:: save_i387_fxsave( regs, buf );
417 //:: else
418 //:: save_i387_fsave( regs, buf );
419 //:: }
420 //::
421 //:: static inline void restore_i387_fsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
422 //:: {
423 //:: VG_(memcpy)( &regs->m_sse.fsave, buf, sizeof(struct i387_fsave_struct) );
424 //:: }
425 //::
426 //:: static void restore_i387_fxsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
427 //:: {
428 //:: VG_(memcpy)(&regs->m_sse.fxsave, &buf->_fxsr_env[0],
429 //:: sizeof(struct i387_fxsave_struct) );
430 //:: /* mxcsr reserved bits must be masked to zero for security reasons */
431 //:: regs->m_sse.fxsave.mxcsr &= 0xffbf;
432 //:: convert_fxsr_from_user( &regs->m_sse.fxsave, buf );
433 //:: }
434 //::
435 //:: static void restore_i387( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
436 //:: {
437 //:: if ( VG_(have_ssestate) ) {
438 //:: restore_i387_fxsave( regs, buf );
439 //:: } else {
440 //:: restore_i387_fsave( regs, buf );
441 //:: }
442 //:: }
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.
454 //.. */
455 //.. static
456 //.. void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,
457 //.. const vki_sigset_t *set, struct vki_ucontext *uc)
458 //.. {
459 //.. ThreadState *tst = VG_(get_ThreadState)(tid);
460 //.. struct vki_sigcontext *sc = &uc->uc_mcontext;
461 //..
462 //.. VG_(memset)(uc, 0, sizeof(*uc));
463 //..
464 //.. uc->uc_flags = 0;
465 //.. uc->uc_link = 0;
466 //.. uc->uc_sigmask = *set;
467 //.. uc->uc_stack = tst->altstack;
468 //.. sc->fpstate = fpstate;
469 //..
470 //.. // FIXME: save_i387(&tst->arch, fpstate);
471 //..
472 //.. # define SC2(reg,REG) sc->reg = tst->arch.vex.guest_##REG
473 //.. SC2(gs,GS);
474 //.. SC2(fs,FS);
475 //.. SC2(es,ES);
476 //.. SC2(ds,DS);
477 //..
478 //.. SC2(edi,EDI);
479 //.. SC2(esi,ESI);
480 //.. SC2(ebp,EBP);
481 //.. SC2(esp,ESP);
482 //.. SC2(ebx,EBX);
483 //.. SC2(edx,EDX);
484 //.. SC2(ecx,ECX);
485 //.. SC2(eax,EAX);
486 //..
487 //.. SC2(eip,EIP);
488 //.. SC2(cs,CS);
489 //.. sc->eflags = LibVEX_GuestX86_get_eflags(&tst->arch.vex);
490 //.. SC2(ss,SS);
491 //.. /* XXX esp_at_signal */
492 //.. /* XXX trapno */
493 //.. /* XXX err */
494 //.. # undef SC2
495 //..
496 //.. sc->cr2 = (UInt)si->_sifields._sigfault._addr;
497 //.. }
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. */
506 //..
507 //.. static void build_vg_sigframe(struct vg_sigframe *frame,
508 //.. ThreadState *tst,
509 //.. const vki_sigset_t *mask,
510 //.. UInt flags,
511 //.. Int sigNo)
512 //.. {
513 //.. frame->sigNo_private = sigNo;
514 //.. frame->magicPI = 0x31415927;
515 //.. frame->vex_shadow = tst->arch.vex_shadow;
516 //.. /* HACK ALERT */
517 //.. frame->vex = tst->arch.vex;
518 //.. /* end HACK ALERT */
519 //.. frame->mask = tst->sig_mask;
520 //.. frame->handlerflags = flags;
521 //.. frame->magicE = 0x27182818;
522 //.. }
525 //.. static Addr build_sigframe(ThreadState *tst,
526 //.. Addr esp_top_of_frame,
527 //.. const vki_siginfo_t *siginfo,
528 //.. void *handler, UInt flags,
529 //.. const vki_sigset_t *mask,
530 //.. void *restorer)
531 //.. {
532 //.. struct sigframe *frame;
533 //.. Addr esp = esp_top_of_frame;
534 //.. Int sigNo = siginfo->si_signo;
535 //.. struct vki_ucontext uc;
536 //..
537 //.. vg_assert((flags & VKI_SA_SIGINFO) == 0);
538 //..
539 //.. esp -= sizeof(*frame);
540 //.. esp = ROUNDDN(esp, 16);
541 //.. frame = (struct sigframe *)esp;
542 //..
543 //.. if (!extend(tst, esp, sizeof(*frame)))
544 //.. return esp_top_of_frame;
545 //..
546 //.. /* retaddr, sigNo, siguContext fields are to be written */
547 //.. VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame",
548 //.. esp, offsetof(struct sigframe, vg) );
549 //..
550 //.. frame->sigNo = sigNo;
551 //..
552 //.. if (flags & VKI_SA_RESTORER)
553 //.. frame->retaddr = (Addr)restorer;
554 //.. else
555 //.. frame->retaddr
556 //.. = VG_(client_trampoline_code)+VG_(tramp_sigreturn_offset);
557 //..
558 //.. synth_ucontext(tst->tid, siginfo, mask, &uc, &frame->fpstate);
559 //..
560 //.. VG_(memcpy)(&frame->sigContext, &uc.uc_mcontext,
561 //.. sizeof(struct vki_sigcontext));
562 //.. frame->sigContext.oldmask = mask->sig[0];
563 //..
564 //.. VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
565 //.. esp, offsetof(struct sigframe, vg) );
566 //..
567 //.. build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
568 //..
569 //.. return esp;
570 //.. }
573 //.. static Addr build_rt_sigframe(ThreadState *tst,
574 //.. Addr esp_top_of_frame,
575 //.. const vki_siginfo_t *siginfo,
576 //.. void *handler, UInt flags,
577 //.. const vki_sigset_t *mask,
578 //.. void *restorer)
579 //.. {
580 //.. struct rt_sigframe *frame;
581 //.. Addr esp = esp_top_of_frame;
582 //.. Int sigNo = siginfo->si_signo;
583 //..
584 //.. vg_assert((flags & VKI_SA_SIGINFO) != 0);
585 //..
586 //.. esp -= sizeof(*frame);
587 //.. esp = ROUNDDN(esp, 16);
588 //.. frame = (struct rt_sigframe *)esp;
589 //..
590 //.. if (!extend(tst, esp, sizeof(*frame)))
591 //.. return esp_top_of_frame;
592 //..
593 //.. /* retaddr, sigNo, pSiginfo, puContext fields are to be written */
594 //.. VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "rt signal handler frame",
595 //.. esp, offsetof(struct rt_sigframe, vg) );
596 //..
597 //.. frame->sigNo = sigNo;
598 //..
599 //.. if (flags & VKI_SA_RESTORER)
600 //.. frame->retaddr = (Addr)restorer;
601 //.. else
602 //.. frame->retaddr
603 //.. = VG_(client_trampoline_code)+VG_(tramp_rt_sigreturn_offset);
604 //..
605 //.. frame->psigInfo = (Addr)&frame->sigInfo;
606 //.. frame->puContext = (Addr)&frame->uContext;
607 //.. VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
608 //..
609 //.. /* SIGILL defines addr to be the faulting address */
610 //.. if (sigNo == VKI_SIGILL && siginfo->si_code > 0)
611 //.. frame->sigInfo._sifields._sigfault._addr
612 //.. = (void*)tst->arch.vex.guest_CIA;
613 //..
614 //.. synth_ucontext(tst->tid, siginfo, mask, &frame->uContext, &frame->fpstate);
615 //..
616 //.. VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
617 //.. esp, offsetof(struct rt_sigframe, vg) );
618 //..
619 //.. build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
620 //..
621 //.. return esp;
622 //.. }
625 /* EXPORTED */
626 void VG_(sigframe_create)( ThreadId tid,
627 Bool on_altstack,
628 Addr sp_top_of_frame,
629 const vki_siginfo_t *siginfo,
630 const struct vki_ucontext *siguc,
631 void *handler,
632 UInt flags,
633 const vki_sigset_t *mask,
634 void *restorer )
636 struct vg_sig_private *priv;
637 Addr sp;
638 ThreadState *tst;
639 Int sigNo = siginfo->si_signo;
640 Addr faultaddr;
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);
647 } else {
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))
654 return;
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",
660 sp, sizeof(UWord) );
661 *(Addr *)sp = tst->arch.vex.guest_GPR1;
662 VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
663 sp, sizeof(UWord) );
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) );
681 ucp->uc_flags = 0;
682 ucp->uc_link = 0;
683 ucp->uc_stack = tst->altstack;
684 VG_TRACK( post_mem_write, Vg_CoreSignal, tid, (Addr)ucp,
685 offsetof(struct vki_ucontext, uc_pad) );
687 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext",
688 (Addr)&ucp->uc_regs,
689 sizeof(ucp->uc_regs) + sizeof(ucp->uc_sigmask) );
690 ucp->uc_regs = &ucp->uc_mcontext;
691 ucp->uc_sigmask = tst->sig_mask;
692 VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
693 (Addr)&ucp->uc_regs,
694 sizeof(ucp->uc_regs) + sizeof(ucp->uc_sigmask) );
696 stack_mcontext(&ucp->uc_mcontext, tst, True/*use_rt_sigreturn*/, faultaddr);
697 priv = &frame->priv;
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);
704 } else {
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) );
711 scp->signal = sigNo;
712 scp->handler = (Addr) handler;
713 scp->oldmask = tst->sig_mask.sig[0];
714 scp->_unused[3] = tst->sig_mask.sig[1];
715 VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
716 (Addr)&scp->_unused[3], sizeof(*scp) - 3 * sizeof(UInt) );
718 stack_mcontext(&frame->mcontext, tst, False/*!use_rt_sigreturn*/, faultaddr);
719 priv = &frame->priv;
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;
733 //.. Addr esp;
734 //.. ThreadState* tst = VG_(get_ThreadState)(tid);
735 //..
736 //.. if (flags & VKI_SA_SIGINFO)
737 //.. esp = build_rt_sigframe(tst, esp_top_of_frame, siginfo,
738 //.. handler, flags, mask, restorer);
739 //.. else
740 //.. esp = build_sigframe(tst, esp_top_of_frame,
741 //.. siginfo, handler, flags, mask, restorer);
742 //..
743 //.. /* Set the thread so it will next run the handler. */
744 //.. /* tst->m_esp = esp; */
745 //.. SET_SIGNAL_ESP(tid, esp);
746 //..
747 //.. //VG_(printf)("handler = %p\n", handler);
748 //.. tst->arch.vex.guest_CIA = (Addr) handler;
749 //.. /* This thread needs to be marked runnable, but we leave that the
750 //.. caller to do. */
752 if (0)
753 VG_(printf)("pushed signal frame; %%R1 now = %#lx, "
754 "next %%CIA = %#x, status=%d\n",
755 sp, tst->arch.vex.guest_CIA, 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. */
765 //.. static
766 //.. Bool restore_vg_sigframe ( ThreadState *tst,
767 //.. struct vg_sigframe *frame, Int *sigNo )
768 //.. {
769 //.. if (frame->magicPI != 0x31415927 ||
770 //.. frame->magicE != 0x27182818) {
771 //.. VG_(message)(Vg_UserMsg, "Thread %d return signal frame "
772 //.. "corrupted. Killing process.",
773 //.. tst->tid);
774 //.. VG_(set_default_handler)(VKI_SIGSEGV);
775 //.. VG_(synth_fault)(tst->tid);
776 //.. *sigNo = VKI_SIGSEGV;
777 //.. return False;
778 //.. }
779 //.. tst->sig_mask = frame->mask;
780 //.. tst->tmp_sig_mask = frame->mask;
781 //.. tst->arch.vex_shadow = frame->vex_shadow;
782 //.. /* HACK ALERT */
783 //.. tst->arch.vex = frame->vex;
784 //.. /* end HACK ALERT */
785 //.. *sigNo = frame->sigNo_private;
786 //.. return True;
787 //.. }
789 //.. static
790 //.. void restore_sigcontext( ThreadState *tst,
791 //.. struct vki_sigcontext *sc )
792 //.. //.. struct vki_sigcontext *sc, struct _vki_fpstate *fpstate )
793 //.. {
794 //.. tst->arch.vex.guest_EAX = sc->eax;
795 //.. tst->arch.vex.guest_ECX = sc->ecx;
796 //.. tst->arch.vex.guest_EDX = sc->edx;
797 //.. tst->arch.vex.guest_EBX = sc->ebx;
798 //.. tst->arch.vex.guest_EBP = sc->ebp;
799 //.. tst->arch.vex.guest_ESP = sc->esp;
800 //.. tst->arch.vex.guest_ESI = sc->esi;
801 //.. tst->arch.vex.guest_EDI = sc->edi;
802 //.. //:: tst->arch.vex.guest_eflags = sc->eflags;
803 //.. //:: tst->arch.vex.guest_EIP = sc->eip;
804 //..
805 //.. tst->arch.vex.guest_CS = sc->cs;
806 //.. tst->arch.vex.guest_SS = sc->ss;
807 //.. tst->arch.vex.guest_DS = sc->ds;
808 //.. tst->arch.vex.guest_ES = sc->es;
809 //.. tst->arch.vex.guest_FS = sc->fs;
810 //.. tst->arch.vex.guest_GS = sc->gs;
811 //..
812 //.. //:: restore_i387(&tst->arch, fpstate);
813 //.. }
816 //.. static
817 //.. SizeT restore_sigframe ( ThreadState *tst,
818 //.. struct sigframe *frame, Int *sigNo )
819 //.. {
820 //.. if (restore_vg_sigframe(tst, &frame->vg, sigNo))
821 //.. restore_sigcontext(tst, &frame->sigContext, &frame->fpstate);
822 //.. return sizeof(*frame);
823 //.. }
825 //.. static
826 //.. SizeT restore_rt_sigframe ( ThreadState *tst,
827 //.. struct rt_sigframe *frame, Int *sigNo )
828 //.. {
829 //.. if (restore_vg_sigframe(tst, &frame->vg, sigNo))
830 //.. restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate);
831 //.. return sizeof(*frame);
832 //.. }
835 /* EXPORTED */
836 void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
838 ThreadState *tst;
839 struct vg_sig_private *priv;
840 Addr sp;
841 UInt frame_size;
842 struct vki_mcontext *mc;
843 Int sigNo;
844 Bool has_siginfo = isRT;
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
857 field. */
859 if (has_siginfo) {
860 struct rt_sigframe *frame = (struct rt_sigframe *)sp;
861 frame_size = sizeof(*frame);
862 mc = &frame->ucontext.uc_mcontext;
863 priv = &frame->priv;
864 vg_assert(priv->magicPI == 0x31415927);
865 tst->sig_mask = frame->ucontext.uc_sigmask;
866 } else {
867 struct nonrt_sigframe *frame = (struct nonrt_sigframe *)sp;
868 frame_size = sizeof(*frame);
869 mc = &frame->mcontext;
870 priv = &frame->priv;
871 vg_assert(priv->magicPI == 0x31415927);
872 tst->sig_mask.sig[0] = frame->sigcontext.oldmask;
873 tst->sig_mask.sig[1] = frame->sigcontext._unused[3];
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);
884 # undef DO
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);
908 /* tell the tools */
909 VG_TRACK( post_deliver_signal, tid, sigNo );
911 //.. Addr esp;
912 //.. ThreadState* tst;
913 //.. SizeT size;
914 //.. Int sigNo;
915 //..
916 //.. tst = VG_(get_ThreadState)(tid);
917 //..
918 //.. /* Correctly reestablish the frame base address. */
919 //.. esp = tst->arch.vex.guest_ESP;
920 //..
921 //.. if (!isRT)
922 //.. size = restore_sigframe(tst, (struct sigframe *)esp, &sigNo);
923 //.. else
924 //.. size = restore_rt_sigframe(tst, (struct rt_sigframe *)esp, &sigNo);
925 //..
926 //.. VG_TRACK( die_mem_stack_signal, esp, size );
927 //..
928 //.. if (VG_(clo_trace_signals))
929 //.. VG_(message)(
930 //.. Vg_DebugMsg,
931 //.. "VG_(signal_return) (thread %d): isRT=%d valid magic; EIP=%p",
932 //.. tid, isRT, tst->arch.vex.guest_EIP);
933 //..
934 //.. /* tell the tools */
935 //.. VG_TRACK( post_deliver_signal, tid, sigNo );
938 #endif // defined(VGP_ppc32_linux)
940 /*--------------------------------------------------------------------*/
941 /*--- end ---*/
942 /*--------------------------------------------------------------------*/