-> 3.17.0 final.
[valgrind.git] / coregrind / m_sigframe / sigframe-ppc32-linux.c
blob5e6b7ef0e8f0faeee060d18a42fb56f19d7d7257
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-2017 Nicholas Nethercote
12 njn@valgrind.org
13 Copyright (C) 2004-2017 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, 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
52 on ppc32-linux.
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
62 really wants.
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.
71 This will be fixed.
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
84 // signals).
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 {
95 UInt magicPI;
96 UInt sigNo_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 {
103 UInt gap1[16];
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. */
111 struct rt_sigframe {
112 UInt gap1[20];
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), \
123 sizeof(UWord) ); \
124 } while (0)
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), \
130 sizeof(UWord) ); \
131 } while (0)
134 static
135 void stack_mcontext ( struct vki_mcontext *mc,
136 ThreadState* tst,
137 Bool use_rt_sigreturn,
138 UInt fault_addr )
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);
148 # undef DO
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
195 //:: {
196 //:: /* Sanity check word. */
197 //:: UInt magicPI;
198 //::
199 //:: UInt handlerflags; /* flags for signal handler */
200 //::
201 //::
202 //:: /* Safely-saved version of sigNo, as described above. */
203 //:: Int sigNo_private;
204 //::
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;
208 //::
209 //:: /* HACK ALERT */
210 //:: VexGuestPPC32State vex;
211 //:: /* end HACK ALERT */
212 //::
213 //:: /* saved signal mask to be restored when handler returns */
214 //:: vki_sigset_t mask;
215 //::
216 //:: /* Sanity check word. Is the highest-addressed word; do not
217 //:: move!*/
218 //:: UInt magicE;
219 //:: };
220 //::
221 //:: struct sigframe
222 //:: {
223 //:: /* Sig handler's return address */
224 //:: Addr retaddr;
225 //:: Int sigNo;
226 //::
227 //:: struct vki_sigcontext sigContext;
228 //:: //.. struct _vki_fpstate fpstate;
229 //::
230 //:: struct vg_sigframe vg;
231 //:: };
232 //::
233 //:: struct rt_sigframe
234 //:: {
235 //:: /* Sig handler's return address */
236 //:: Addr retaddr;
237 //:: Int sigNo;
238 //::
239 //:: /* ptr to siginfo_t. */
240 //:: Addr psigInfo;
241 //::
242 //:: /* ptr to ucontext */
243 //:: Addr puContext;
244 //:: /* pointed to by psigInfo */
245 //:: vki_siginfo_t sigInfo;
246 //::
247 //:: /* pointed to by puContext */
248 //:: struct vki_ucontext uContext;
249 //:: //.. struct _vki_fpstate fpstate;
250 //::
251 //:: struct vg_sigframe vg;
252 //:: };
255 //:: /*------------------------------------------------------------*/
256 //:: /*--- Signal operations ---*/
257 //:: /*------------------------------------------------------------*/
258 //::
259 //:: /*
260 //:: Great gobs of FP state conversion taken wholesale from
261 //:: linux/arch/i386/kernel/i387.c
262 //:: */
263 //::
264 //:: /*
265 //:: * FXSR floating point environment conversions.
266 //:: */
267 //:: #define X86_FXSR_MAGIC 0x0000
268 //::
269 //:: /*
270 //:: * FPU tag word conversions.
271 //:: */
272 //::
273 //:: static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
274 //:: {
275 //:: unsigned int tmp; /* to avoid 16 bit prefixes in the code */
276 //::
277 //:: /* Transform each pair of bits into 01 (valid) or 00 (empty) */
278 //:: tmp = ~twd;
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 */
284 //:: return tmp;
285 //:: }
286 //::
287 //:: static unsigned long twd_fxsr_to_i387( const struct i387_fxsave_struct *fxsave )
288 //:: {
289 //:: struct _vki_fpxreg *st = NULL;
290 //:: unsigned long twd = (unsigned long) fxsave->twd;
291 //:: unsigned long tag;
292 //:: unsigned long ret = 0xffff0000u;
293 //:: int i;
294 //::
295 //:: #define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
296 //::
297 //:: for ( i = 0 ; i < 8 ; i++ ) {
298 //:: if ( twd & 0x1 ) {
299 //:: st = (struct _vki_fpxreg *) FPREG_ADDR( fxsave, i );
300 //::
301 //:: switch ( st->exponent & 0x7fff ) {
302 //:: case 0x7fff:
303 //:: tag = 2; /* Special */
304 //:: break;
305 //:: case 0x0000:
306 //:: if ( !st->significand[0] &&
307 //:: !st->significand[1] &&
308 //:: !st->significand[2] &&
309 //:: !st->significand[3] ) {
310 //:: tag = 1; /* Zero */
311 //:: } else {
312 //:: tag = 2; /* Special */
313 //:: }
314 //:: break;
315 //:: default:
316 //:: if ( st->significand[3] & 0x8000 ) {
317 //:: tag = 0; /* Valid */
318 //:: } else {
319 //:: tag = 2; /* Special */
320 //:: }
321 //:: break;
322 //:: }
323 //:: } else {
324 //:: tag = 3; /* Empty */
325 //:: }
326 //:: ret |= (tag << (2 * i));
327 //:: twd = twd >> 1;
328 //:: }
329 //:: return ret;
330 //:: }
331 //::
332 //:: static void convert_fxsr_to_user( struct _vki_fpstate *buf,
333 //:: const struct i387_fxsave_struct *fxsave )
334 //:: {
335 //:: unsigned long env[7];
336 //:: struct _vki_fpreg *to;
337 //:: struct _vki_fpxreg *from;
338 //:: int i;
339 //::
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;
347 //::
348 //:: VG_(memcpy)(buf, env, 7 * sizeof(unsigned long));
349 //::
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;
355 //::
356 //:: t[0] = f[0];
357 //:: t[1] = f[1];
358 //:: to->exponent = from->exponent;
359 //:: }
360 //:: }
361 //::
362 //:: static void convert_fxsr_from_user( struct i387_fxsave_struct *fxsave,
363 //:: const struct _vki_fpstate *buf )
364 //:: {
365 //:: unsigned long env[7];
366 //:: struct _vki_fpxreg *to;
367 //:: const struct _vki_fpreg *from;
368 //:: int i;
369 //::
370 //:: VG_(memcpy)(env, buf, 7 * sizeof(long));
371 //::
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];
380 //::
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;
386 //::
387 //:: t[0] = f[0];
388 //:: t[1] = f[1];
389 //:: to->exponent = from->exponent;
390 //:: }
391 //:: }
392 //::
393 //:: static inline void save_i387_fsave( arch_thread_t *regs, struct _vki_fpstate *buf )
394 //:: {
395 //:: struct i387_fsave_struct *fs = &regs->m_sse.fsave;
396 //::
397 //:: fs->status = fs->swd;
398 //:: VG_(memcpy)(buf, fs, sizeof(*fs));
399 //:: }
400 //::
401 //:: static void save_i387_fxsave( arch_thread_t *regs, struct _vki_fpstate *buf )
402 //:: {
403 //:: const struct i387_fxsave_struct *fx = &regs->m_sse.fxsave;
404 //:: convert_fxsr_to_user( buf, fx );
405 //::
406 //:: buf->status = fx->swd;
407 //:: buf->magic = X86_FXSR_MAGIC;
408 //:: VG_(memcpy)(buf->_fxsr_env, fx, sizeof(struct i387_fxsave_struct));
409 //:: }
410 //::
411 //:: static void save_i387( arch_thread_t *regs, struct _vki_fpstate *buf )
412 //:: {
413 //:: if ( VG_(have_ssestate) )
414 //:: save_i387_fxsave( regs, buf );
415 //:: else
416 //:: save_i387_fsave( regs, buf );
417 //:: }
418 //::
419 //:: static inline void restore_i387_fsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
420 //:: {
421 //:: VG_(memcpy)( &regs->m_sse.fsave, buf, sizeof(struct i387_fsave_struct) );
422 //:: }
423 //::
424 //:: static void restore_i387_fxsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
425 //:: {
426 //:: VG_(memcpy)(&regs->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( &regs->m_sse.fxsave, buf );
431 //:: }
432 //::
433 //:: static void restore_i387( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
434 //:: {
435 //:: if ( VG_(have_ssestate) ) {
436 //:: restore_i387_fxsave( regs, buf );
437 //:: } else {
438 //:: restore_i387_fsave( regs, buf );
439 //:: }
440 //:: }
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.
452 //.. */
453 //.. static
454 //.. void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,
455 //.. const vki_sigset_t *set, struct vki_ucontext *uc)
456 //.. {
457 //.. ThreadState *tst = VG_(get_ThreadState)(tid);
458 //.. struct vki_sigcontext *sc = &uc->uc_mcontext;
459 //..
460 //.. VG_(memset)(uc, 0, sizeof(*uc));
461 //..
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;
467 //..
468 //.. // FIXME: save_i387(&tst->arch, fpstate);
469 //..
470 //.. # define SC2(reg,REG) sc->reg = tst->arch.vex.guest_##REG
471 //.. SC2(gs,GS);
472 //.. SC2(fs,FS);
473 //.. SC2(es,ES);
474 //.. SC2(ds,DS);
475 //..
476 //.. SC2(edi,EDI);
477 //.. SC2(esi,ESI);
478 //.. SC2(ebp,EBP);
479 //.. SC2(esp,ESP);
480 //.. SC2(ebx,EBX);
481 //.. SC2(edx,EDX);
482 //.. SC2(ecx,ECX);
483 //.. SC2(eax,EAX);
484 //..
485 //.. SC2(eip,EIP);
486 //.. SC2(cs,CS);
487 //.. sc->eflags = LibVEX_GuestX86_get_eflags(&tst->arch.vex);
488 //.. SC2(ss,SS);
489 //.. /* XXX esp_at_signal */
490 //.. /* XXX trapno */
491 //.. /* XXX err */
492 //.. # undef SC2
493 //..
494 //.. sc->cr2 = (UInt)si->_sifields._sigfault._addr;
495 //.. }
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. */
504 //..
505 //.. static void build_vg_sigframe(struct vg_sigframe *frame,
506 //.. ThreadState *tst,
507 //.. const vki_sigset_t *mask,
508 //.. UInt flags,
509 //.. Int sigNo)
510 //.. {
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;
520 //.. }
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,
528 //.. void *restorer)
529 //.. {
530 //.. struct sigframe *frame;
531 //.. Addr esp = esp_top_of_frame;
532 //.. Int sigNo = siginfo->si_signo;
533 //.. struct vki_ucontext uc;
534 //..
535 //.. vg_assert((flags & VKI_SA_SIGINFO) == 0);
536 //..
537 //.. esp -= sizeof(*frame);
538 //.. esp = ROUNDDN(esp, 16);
539 //.. frame = (struct sigframe *)esp;
540 //..
541 //.. if (!extend(tst, esp, sizeof(*frame)))
542 //.. return esp_top_of_frame;
543 //..
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) );
547 //..
548 //.. frame->sigNo = sigNo;
549 //..
550 //.. if (flags & VKI_SA_RESTORER)
551 //.. frame->retaddr = (Addr)restorer;
552 //.. else
553 //.. frame->retaddr
554 //.. = VG_(client_trampoline_code)+VG_(tramp_sigreturn_offset);
555 //..
556 //.. synth_ucontext(tst->tid, siginfo, mask, &uc, &frame->fpstate);
557 //..
558 //.. VG_(memcpy)(&frame->sigContext, &uc.uc_mcontext,
559 //.. sizeof(struct vki_sigcontext));
560 //.. frame->sigContext.oldmask = mask->sig[0];
561 //..
562 //.. VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
563 //.. esp, offsetof(struct sigframe, vg) );
564 //..
565 //.. build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
566 //..
567 //.. return esp;
568 //.. }
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,
576 //.. void *restorer)
577 //.. {
578 //.. struct rt_sigframe *frame;
579 //.. Addr esp = esp_top_of_frame;
580 //.. Int sigNo = siginfo->si_signo;
581 //..
582 //.. vg_assert((flags & VKI_SA_SIGINFO) != 0);
583 //..
584 //.. esp -= sizeof(*frame);
585 //.. esp = ROUNDDN(esp, 16);
586 //.. frame = (struct rt_sigframe *)esp;
587 //..
588 //.. if (!extend(tst, esp, sizeof(*frame)))
589 //.. return esp_top_of_frame;
590 //..
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) );
594 //..
595 //.. frame->sigNo = sigNo;
596 //..
597 //.. if (flags & VKI_SA_RESTORER)
598 //.. frame->retaddr = (Addr)restorer;
599 //.. else
600 //.. frame->retaddr
601 //.. = VG_(client_trampoline_code)+VG_(tramp_rt_sigreturn_offset);
602 //..
603 //.. frame->psigInfo = (Addr)&frame->sigInfo;
604 //.. frame->puContext = (Addr)&frame->uContext;
605 //.. VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
606 //..
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;
611 //..
612 //.. synth_ucontext(tst->tid, siginfo, mask, &frame->uContext, &frame->fpstate);
613 //..
614 //.. VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
615 //.. esp, offsetof(struct rt_sigframe, vg) );
616 //..
617 //.. build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
618 //..
619 //.. return esp;
620 //.. }
623 /* EXPORTED */
624 void VG_(sigframe_create)( ThreadId tid,
625 Bool on_altstack,
626 Addr sp_top_of_frame,
627 const vki_siginfo_t *siginfo,
628 const struct vki_ucontext *siguc,
629 void *handler,
630 UInt flags,
631 const vki_sigset_t *mask,
632 void *restorer )
634 struct vg_sig_private *priv;
635 Addr sp;
636 ThreadState *tst;
637 Int sigNo = siginfo->si_signo;
638 Addr faultaddr;
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);
645 } else {
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))
652 return;
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",
658 sp, sizeof(UWord) );
659 *(Addr *)sp = tst->arch.vex.guest_GPR1;
660 VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
661 sp, sizeof(UWord) );
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) );
679 ucp->uc_flags = 0;
680 ucp->uc_link = 0;
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",
686 (Addr)&ucp->uc_regs,
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,
691 (Addr)&ucp->uc_regs,
692 sizeof(ucp->uc_regs) + sizeof(ucp->uc_sigmask) );
694 stack_mcontext(&ucp->uc_mcontext, tst, True/*use_rt_sigreturn*/, faultaddr);
695 priv = &frame->priv;
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);
702 } else {
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) );
709 scp->signal = sigNo;
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);
717 priv = &frame->priv;
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;
731 //.. Addr esp;
732 //.. ThreadState* tst = VG_(get_ThreadState)(tid);
733 //..
734 //.. if (flags & VKI_SA_SIGINFO)
735 //.. esp = build_rt_sigframe(tst, esp_top_of_frame, siginfo,
736 //.. handler, flags, mask, restorer);
737 //.. else
738 //.. esp = build_sigframe(tst, esp_top_of_frame,
739 //.. siginfo, handler, flags, mask, restorer);
740 //..
741 //.. /* Set the thread so it will next run the handler. */
742 //.. /* tst->m_esp = esp; */
743 //.. SET_SIGNAL_ESP(tid, esp);
744 //..
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. */
750 if (0)
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. */
763 //.. static
764 //.. Bool restore_vg_sigframe ( ThreadState *tst,
765 //.. struct vg_sigframe *frame, Int *sigNo )
766 //.. {
767 //.. if (frame->magicPI != 0x31415927 ||
768 //.. frame->magicE != 0x27182818) {
769 //.. VG_(message)(Vg_UserMsg, "Thread %d return signal frame "
770 //.. "corrupted. Killing process.",
771 //.. tst->tid);
772 //.. VG_(set_default_handler)(VKI_SIGSEGV);
773 //.. VG_(synth_fault)(tst->tid);
774 //.. *sigNo = VKI_SIGSEGV;
775 //.. return False;
776 //.. }
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;
784 //.. return True;
785 //.. }
787 //.. static
788 //.. void restore_sigcontext( ThreadState *tst,
789 //.. struct vki_sigcontext *sc )
790 //.. //.. struct vki_sigcontext *sc, struct _vki_fpstate *fpstate )
791 //.. {
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;
802 //..
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;
809 //..
810 //.. //:: restore_i387(&tst->arch, fpstate);
811 //.. }
814 //.. static
815 //.. SizeT restore_sigframe ( ThreadState *tst,
816 //.. struct sigframe *frame, Int *sigNo )
817 //.. {
818 //.. if (restore_vg_sigframe(tst, &frame->vg, sigNo))
819 //.. restore_sigcontext(tst, &frame->sigContext, &frame->fpstate);
820 //.. return sizeof(*frame);
821 //.. }
823 //.. static
824 //.. SizeT restore_rt_sigframe ( ThreadState *tst,
825 //.. struct rt_sigframe *frame, Int *sigNo )
826 //.. {
827 //.. if (restore_vg_sigframe(tst, &frame->vg, sigNo))
828 //.. restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate);
829 //.. return sizeof(*frame);
830 //.. }
833 /* EXPORTED */
834 void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
836 ThreadState *tst;
837 struct vg_sig_private *priv;
838 Addr sp;
839 UInt frame_size;
840 struct vki_mcontext *mc;
841 Int sigNo;
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
855 field. */
857 if (has_siginfo) {
858 struct rt_sigframe *frame = (struct rt_sigframe *)sp;
859 frame_size = sizeof(*frame);
860 mc = &frame->ucontext.uc_mcontext;
861 priv = &frame->priv;
862 vg_assert(priv->magicPI == 0x31415927);
863 tst->sig_mask = frame->ucontext.uc_sigmask;
864 } else {
865 struct nonrt_sigframe *frame = (struct nonrt_sigframe *)sp;
866 frame_size = sizeof(*frame);
867 mc = &frame->mcontext;
868 priv = &frame->priv;
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);
882 # undef DO
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);
906 /* tell the tools */
907 VG_TRACK( post_deliver_signal, tid, sigNo );
909 //.. Addr esp;
910 //.. ThreadState* tst;
911 //.. SizeT size;
912 //.. Int sigNo;
913 //..
914 //.. tst = VG_(get_ThreadState)(tid);
915 //..
916 //.. /* Correctly reestablish the frame base address. */
917 //.. esp = tst->arch.vex.guest_ESP;
918 //..
919 //.. if (!isRT)
920 //.. size = restore_sigframe(tst, (struct sigframe *)esp, &sigNo);
921 //.. else
922 //.. size = restore_rt_sigframe(tst, (struct rt_sigframe *)esp, &sigNo);
923 //..
924 //.. VG_TRACK( die_mem_stack_signal, esp, size );
925 //..
926 //.. if (VG_(clo_trace_signals))
927 //.. VG_(message)(
928 //.. Vg_DebugMsg,
929 //.. "VG_(signal_return) (thread %u): isRT=%d valid magic; EIP=%p",
930 //.. tid, isRT, tst->arch.vex.guest_EIP);
931 //..
932 //.. /* tell the tools */
933 //.. VG_TRACK( post_deliver_signal, tid, sigNo );
936 #endif // defined(VGP_ppc32_linux)
938 /*--------------------------------------------------------------------*/
939 /*--- end ---*/
940 /*--------------------------------------------------------------------*/