1
2 /*--------------------------------------------------------------------*/
3 /*--- Create/destroy signal delivery frames. ---*/
4 /*--- sigframe-ppc32-linux.c ---*/
5 /*--------------------------------------------------------------------*/
6
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
11 Copyright (C) 2000-2013 Nicholas Nethercote
12 njn@valgrind.org
13 Copyright (C) 2004-2013 Paul Mackerras
14 paulus@samba.org
15
16 This program is free software; you can redistribute it and/or
17 modify it under the terms of the GNU General Public License as
18 published by the Free Software Foundation; either version 2 of the
19 License, or (at your option) any later version.
20
21 This program is distributed in the hope that it will be useful, but
22 WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 General Public License for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
29 02111-1307, USA.
30
31 The GNU General Public License is contained in the file COPYING.
32 */
33
34 #if defined(VGP_ppc32_linux)
35
36 #include "pub_core_basics.h"
37 #include "pub_core_vki.h"
38 #include "pub_core_vkiscnums.h"
39 #include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy
40 #include "pub_core_threadstate.h"
41 #include "pub_core_aspacemgr.h"
42 #include "pub_core_libcbase.h"
43 #include "pub_core_libcassert.h"
44 #include "pub_core_libcprint.h"
45 #include "pub_core_machine.h"
46 #include "pub_core_options.h"
47 #include "pub_core_sigframe.h"
48 #include "pub_core_signals.h"
49 #include "pub_core_tooliface.h"
50 #include "pub_core_trampoline.h"
51 #include "pub_core_transtab.h" // VG_(discard_translations)
52
53
54 /* This module creates and removes signal frames for signal deliveries
55 on ppc32-linux.
56
57 Note, this file contains kernel-specific knowledge in the form of
58 'struct sigframe' and 'struct rt_sigframe'. How does that relate
59 to the vki kernel interface stuff?
60
61 Either a 'struct sigframe' or a 'struct rtsigframe' is pushed
62 onto the client's stack. This contains a subsidiary
63 vki_ucontext. That holds the vcpu's state across the signal,
64 so that the sighandler can mess with the vcpu state if it
65 really wants.
66
67 FIXME: sigcontexting is basically broken for the moment. When
68 delivering a signal, the integer registers and %eflags are
69 correctly written into the sigcontext, however the FP and SSE state
70 is not. When returning from a signal, only the integer registers
71 are restored from the sigcontext; the rest of the CPU state is
72 restored to what it was before the signal.
73
74 This will be fixed.
75 */
76
77
78 /*------------------------------------------------------------*/
79 /*--- Signal frame layouts ---*/
80 /*------------------------------------------------------------*/
81
82 // A structure in which to save the application's registers
83 // during the execution of signal handlers.
84
85 // Linux has 2 signal frame structures: one for normal signal
86 // deliveries, and one for SA_SIGINFO deliveries (also known as RT
87 // signals).
88 //
89 // In theory, so long as we get the arguments to the handler function
90 // right, it doesn't matter what the exact layout of the rest of the
91 // frame is. Unfortunately, things like gcc's exception unwinding
92 // make assumptions about the locations of various parts of the frame,
93 // so we need to duplicate it exactly.
94
95 /* Structure containing bits of information that we want to save
96 on signal delivery. */
97 struct vg_sig_private {
98 UInt magicPI;
99 UInt sigNo_private;
100 VexGuestPPC32State vex_shadow1;
101 VexGuestPPC32State vex_shadow2;
102 };
103
104 /* Structure put on stack for signal handlers with SA_SIGINFO clear. */
105 struct nonrt_sigframe {
106 UInt gap1[16];
107 struct vki_sigcontext sigcontext;
108 struct vki_mcontext mcontext;
109 struct vg_sig_private priv;
110 unsigned char abigap[224];
111 };
112
113 /* Structure put on stack for signal handlers with SA_SIGINFO set. */
114 struct rt_sigframe {
115 UInt gap1[20];
116 vki_siginfo_t siginfo;
117 struct vki_ucontext ucontext;
118 struct vg_sig_private priv;
119 unsigned char abigap[224];
120 };
121
122 #define SET_SIGNAL_LR(zztst, zzval) \
123 do { tst->arch.vex.guest_LR = (zzval); \
124 VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, \
125 offsetof(VexGuestPPC32State,guest_LR), \
126 sizeof(UWord) ); \
127 } while (0)
128
129 #define SET_SIGNAL_GPR(zztst, zzn, zzval) \
130 do { tst->arch.vex.guest_GPR##zzn = (zzval); \
131 VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid, \
132 offsetof(VexGuestPPC32State,guest_GPR##zzn), \
133 sizeof(UWord) ); \
134 } while (0)
135
136
137 static
stack_mcontext(struct vki_mcontext * mc,ThreadState * tst,Bool use_rt_sigreturn,UInt fault_addr)138 void stack_mcontext ( struct vki_mcontext *mc,
139 ThreadState* tst,
140 Bool use_rt_sigreturn,
141 UInt fault_addr )
142 {
143 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcontext",
144 (Addr)mc, sizeof(struct vki_pt_regs) );
145
146 # define DO(gpr) mc->mc_gregs[VKI_PT_R0+gpr] = tst->arch.vex.guest_GPR##gpr
147 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
148 DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
149 DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
150 DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
151 # undef DO
152
153 mc->mc_gregs[VKI_PT_NIP] = tst->arch.vex.guest_CIA;
154 mc->mc_gregs[VKI_PT_MSR] = 0xf032; /* pretty arbitrary */
155 mc->mc_gregs[VKI_PT_ORIG_R3] = tst->arch.vex.guest_GPR3;
156 mc->mc_gregs[VKI_PT_CTR] = tst->arch.vex.guest_CTR;
157 mc->mc_gregs[VKI_PT_LNK] = tst->arch.vex.guest_LR;
158 mc->mc_gregs[VKI_PT_XER] = LibVEX_GuestPPC32_get_XER(&tst->arch.vex);
159 mc->mc_gregs[VKI_PT_CCR] = LibVEX_GuestPPC32_get_CR(&tst->arch.vex);
160 mc->mc_gregs[VKI_PT_MQ] = 0;
161 mc->mc_gregs[VKI_PT_TRAP] = 0;
162 mc->mc_gregs[VKI_PT_DAR] = fault_addr;
163 mc->mc_gregs[VKI_PT_DSISR] = 0;
164 mc->mc_gregs[VKI_PT_RESULT] = 0;
165 VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
166 (Addr)mc, sizeof(struct vki_pt_regs) );
167
168 /* XXX should do FP and vector regs */
169
170 /* set up signal return trampoline */
171 /* NB. 5 Sept 07. mc->mc_pad[0..1] used to contain a the code to
172 which the signal handler returns, and it just did sys_sigreturn
173 or sys_rt_sigreturn. But this doesn't work if the stack is
174 non-executable, and it isn't consistent with the x86-linux and
175 amd64-linux scheme for removing the stack frame. So instead be
176 consistent and use a stub in m_trampoline. Then it doesn't
177 matter whether or not the (guest) stack is executable. This
178 fixes #149519 and #145837. */
179 VG_TRACK(pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcontext",
180 (Addr)&mc->mc_pad, sizeof(mc->mc_pad));
181 mc->mc_pad[0] = 0; /* invalid */
182 mc->mc_pad[1] = 0; /* invalid */
183 VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
184 (Addr)&mc->mc_pad, sizeof(mc->mc_pad) );
185 /* invalidate any translation of this area */
186 VG_(discard_translations)( (Addr64)(Addr)&mc->mc_pad,
187 sizeof(mc->mc_pad), "stack_mcontext" );
188
189 /* set the signal handler to return to the trampoline */
190 SET_SIGNAL_LR(tst, (Addr)(use_rt_sigreturn
191 ? (Addr)&VG_(ppc32_linux_SUBST_FOR_rt_sigreturn)
192 : (Addr)&VG_(ppc32_linux_SUBST_FOR_sigreturn)
193 ));
194 }
195
196 //:: /* Valgrind-specific parts of the signal frame */
197 //:: struct vg_sigframe
198 //:: {
199 //:: /* Sanity check word. */
200 //:: UInt magicPI;
201 //::
202 //:: UInt handlerflags; /* flags for signal handler */
203 //::
204 //::
205 //:: /* Safely-saved version of sigNo, as described above. */
206 //:: Int sigNo_private;
207 //::
208 //:: /* XXX This is wrong. Surely we should store the shadow values
209 //:: into the shadow memory behind the actual values? */
210 //:: VexGuestPPC32State vex_shadow;
211 //::
212 //:: /* HACK ALERT */
213 //:: VexGuestPPC32State vex;
214 //:: /* end HACK ALERT */
215 //::
216 //:: /* saved signal mask to be restored when handler returns */
217 //:: vki_sigset_t mask;
218 //::
219 //:: /* Sanity check word. Is the highest-addressed word; do not
220 //:: move!*/
221 //:: UInt magicE;
222 //:: };
223 //::
224 //:: struct sigframe
225 //:: {
226 //:: /* Sig handler's return address */
227 //:: Addr retaddr;
228 //:: Int sigNo;
229 //::
230 //:: struct vki_sigcontext sigContext;
231 //:: //.. struct _vki_fpstate fpstate;
232 //::
233 //:: struct vg_sigframe vg;
234 //:: };
235 //::
236 //:: struct rt_sigframe
237 //:: {
238 //:: /* Sig handler's return address */
239 //:: Addr retaddr;
240 //:: Int sigNo;
241 //::
242 //:: /* ptr to siginfo_t. */
243 //:: Addr psigInfo;
244 //::
245 //:: /* ptr to ucontext */
246 //:: Addr puContext;
247 //:: /* pointed to by psigInfo */
248 //:: vki_siginfo_t sigInfo;
249 //::
250 //:: /* pointed to by puContext */
251 //:: struct vki_ucontext uContext;
252 //:: //.. struct _vki_fpstate fpstate;
253 //::
254 //:: struct vg_sigframe vg;
255 //:: };
256
257
258 //:: /*------------------------------------------------------------*/
259 //:: /*--- Signal operations ---*/
260 //:: /*------------------------------------------------------------*/
261 //::
262 //:: /*
263 //:: Great gobs of FP state conversion taken wholesale from
264 //:: linux/arch/i386/kernel/i387.c
265 //:: */
266 //::
267 //:: /*
268 //:: * FXSR floating point environment conversions.
269 //:: */
270 //:: #define X86_FXSR_MAGIC 0x0000
271 //::
272 //:: /*
273 //:: * FPU tag word conversions.
274 //:: */
275 //::
276 //:: static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
277 //:: {
278 //:: unsigned int tmp; /* to avoid 16 bit prefixes in the code */
279 //::
280 //:: /* Transform each pair of bits into 01 (valid) or 00 (empty) */
281 //:: tmp = ~twd;
282 //:: tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
283 //:: /* and move the valid bits to the lower byte. */
284 //:: tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
285 //:: tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
286 //:: tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
287 //:: return tmp;
288 //:: }
289 //::
290 //:: static unsigned long twd_fxsr_to_i387( const struct i387_fxsave_struct *fxsave )
291 //:: {
292 //:: struct _vki_fpxreg *st = NULL;
293 //:: unsigned long twd = (unsigned long) fxsave->twd;
294 //:: unsigned long tag;
295 //:: unsigned long ret = 0xffff0000u;
296 //:: int i;
297 //::
298 //:: #define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
299 //::
300 //:: for ( i = 0 ; i < 8 ; i++ ) {
301 //:: if ( twd & 0x1 ) {
302 //:: st = (struct _vki_fpxreg *) FPREG_ADDR( fxsave, i );
303 //::
304 //:: switch ( st->exponent & 0x7fff ) {
305 //:: case 0x7fff:
306 //:: tag = 2; /* Special */
307 //:: break;
308 //:: case 0x0000:
309 //:: if ( !st->significand[0] &&
310 //:: !st->significand[1] &&
311 //:: !st->significand[2] &&
312 //:: !st->significand[3] ) {
313 //:: tag = 1; /* Zero */
314 //:: } else {
315 //:: tag = 2; /* Special */
316 //:: }
317 //:: break;
318 //:: default:
319 //:: if ( st->significand[3] & 0x8000 ) {
320 //:: tag = 0; /* Valid */
321 //:: } else {
322 //:: tag = 2; /* Special */
323 //:: }
324 //:: break;
325 //:: }
326 //:: } else {
327 //:: tag = 3; /* Empty */
328 //:: }
329 //:: ret |= (tag << (2 * i));
330 //:: twd = twd >> 1;
331 //:: }
332 //:: return ret;
333 //:: }
334 //::
335 //:: static void convert_fxsr_to_user( struct _vki_fpstate *buf,
336 //:: const struct i387_fxsave_struct *fxsave )
337 //:: {
338 //:: unsigned long env[7];
339 //:: struct _vki_fpreg *to;
340 //:: struct _vki_fpxreg *from;
341 //:: int i;
342 //::
343 //:: env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul;
344 //:: env[1] = (unsigned long)fxsave->swd | 0xffff0000ul;
345 //:: env[2] = twd_fxsr_to_i387(fxsave);
346 //:: env[3] = fxsave->fip;
347 //:: env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
348 //:: env[5] = fxsave->foo;
349 //:: env[6] = fxsave->fos;
350 //::
351 //:: VG_(memcpy)(buf, env, 7 * sizeof(unsigned long));
352 //::
353 //:: to = &buf->_st[0];
354 //:: from = (struct _vki_fpxreg *) &fxsave->st_space[0];
355 //:: for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
356 //:: unsigned long __user *t = (unsigned long __user *)to;
357 //:: unsigned long *f = (unsigned long *)from;
358 //::
359 //:: t[0] = f[0];
360 //:: t[1] = f[1];
361 //:: to->exponent = from->exponent;
362 //:: }
363 //:: }
364 //::
365 //:: static void convert_fxsr_from_user( struct i387_fxsave_struct *fxsave,
366 //:: const struct _vki_fpstate *buf )
367 //:: {
368 //:: unsigned long env[7];
369 //:: struct _vki_fpxreg *to;
370 //:: const struct _vki_fpreg *from;
371 //:: int i;
372 //::
373 //:: VG_(memcpy)(env, buf, 7 * sizeof(long));
374 //::
375 //:: fxsave->cwd = (unsigned short)(env[0] & 0xffff);
376 //:: fxsave->swd = (unsigned short)(env[1] & 0xffff);
377 //:: fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
378 //:: fxsave->fip = env[3];
379 //:: fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16);
380 //:: fxsave->fcs = (env[4] & 0xffff);
381 //:: fxsave->foo = env[5];
382 //:: fxsave->fos = env[6];
383 //::
384 //:: to = (struct _vki_fpxreg *) &fxsave->st_space[0];
385 //:: from = &buf->_st[0];
386 //:: for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
387 //:: unsigned long *t = (unsigned long *)to;
388 //:: unsigned long __user *f = (unsigned long __user *)from;
389 //::
390 //:: t[0] = f[0];
391 //:: t[1] = f[1];
392 //:: to->exponent = from->exponent;
393 //:: }
394 //:: }
395 //::
396 //:: static inline void save_i387_fsave( arch_thread_t *regs, struct _vki_fpstate *buf )
397 //:: {
398 //:: struct i387_fsave_struct *fs = ®s->m_sse.fsave;
399 //::
400 //:: fs->status = fs->swd;
401 //:: VG_(memcpy)(buf, fs, sizeof(*fs));
402 //:: }
403 //::
404 //:: static void save_i387_fxsave( arch_thread_t *regs, struct _vki_fpstate *buf )
405 //:: {
406 //:: const struct i387_fxsave_struct *fx = ®s->m_sse.fxsave;
407 //:: convert_fxsr_to_user( buf, fx );
408 //::
409 //:: buf->status = fx->swd;
410 //:: buf->magic = X86_FXSR_MAGIC;
411 //:: VG_(memcpy)(buf->_fxsr_env, fx, sizeof(struct i387_fxsave_struct));
412 //:: }
413 //::
414 //:: static void save_i387( arch_thread_t *regs, struct _vki_fpstate *buf )
415 //:: {
416 //:: if ( VG_(have_ssestate) )
417 //:: save_i387_fxsave( regs, buf );
418 //:: else
419 //:: save_i387_fsave( regs, buf );
420 //:: }
421 //::
422 //:: static inline void restore_i387_fsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
423 //:: {
424 //:: VG_(memcpy)( ®s->m_sse.fsave, buf, sizeof(struct i387_fsave_struct) );
425 //:: }
426 //::
427 //:: static void restore_i387_fxsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
428 //:: {
429 //:: VG_(memcpy)(®s->m_sse.fxsave, &buf->_fxsr_env[0],
430 //:: sizeof(struct i387_fxsave_struct) );
431 //:: /* mxcsr reserved bits must be masked to zero for security reasons */
432 //:: regs->m_sse.fxsave.mxcsr &= 0xffbf;
433 //:: convert_fxsr_from_user( ®s->m_sse.fxsave, buf );
434 //:: }
435 //::
436 //:: static void restore_i387( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
437 //:: {
438 //:: if ( VG_(have_ssestate) ) {
439 //:: restore_i387_fxsave( regs, buf );
440 //:: } else {
441 //:: restore_i387_fsave( regs, buf );
442 //:: }
443 //:: }
444
445
446
447
448 /*------------------------------------------------------------*/
449 /*--- Creating signal frames ---*/
450 /*------------------------------------------------------------*/
451
452 //.. /* Create a plausible-looking sigcontext from the thread's
453 //.. Vex guest state. NOTE: does not fill in the FP or SSE
454 //.. bits of sigcontext at the moment.
455 //.. */
456 //.. static
457 //.. void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,
458 //.. const vki_sigset_t *set, struct vki_ucontext *uc)
459 //.. {
460 //.. ThreadState *tst = VG_(get_ThreadState)(tid);
461 //.. struct vki_sigcontext *sc = &uc->uc_mcontext;
462 //..
463 //.. VG_(memset)(uc, 0, sizeof(*uc));
464 //..
465 //.. uc->uc_flags = 0;
466 //.. uc->uc_link = 0;
467 //.. uc->uc_sigmask = *set;
468 //.. uc->uc_stack = tst->altstack;
469 //.. sc->fpstate = fpstate;
470 //..
471 //.. // FIXME: save_i387(&tst->arch, fpstate);
472 //..
473 //.. # define SC2(reg,REG) sc->reg = tst->arch.vex.guest_##REG
474 //.. SC2(gs,GS);
475 //.. SC2(fs,FS);
476 //.. SC2(es,ES);
477 //.. SC2(ds,DS);
478 //..
479 //.. SC2(edi,EDI);
480 //.. SC2(esi,ESI);
481 //.. SC2(ebp,EBP);
482 //.. SC2(esp,ESP);
483 //.. SC2(ebx,EBX);
484 //.. SC2(edx,EDX);
485 //.. SC2(ecx,ECX);
486 //.. SC2(eax,EAX);
487 //..
488 //.. SC2(eip,EIP);
489 //.. SC2(cs,CS);
490 //.. sc->eflags = LibVEX_GuestX86_get_eflags(&tst->arch.vex);
491 //.. SC2(ss,SS);
492 //.. /* XXX esp_at_signal */
493 //.. /* XXX trapno */
494 //.. /* XXX err */
495 //.. # undef SC2
496 //..
497 //.. sc->cr2 = (UInt)si->_sifields._sigfault._addr;
498 //.. }
499 /*
500 //.. #define SET_SIGNAL_ESP(zztid, zzval) \
501 //.. SET_THREAD_REG(zztid, zzval, STACK_PTR, post_reg_write, \
502 //.. Vg_CoreSignal, zztid, VG_O_STACK_PTR, sizeof(Addr))
503 */
504
505 /* Extend the stack segment downwards if needed so as to ensure the
506 new signal frames are mapped to something. Return a Bool
507 indicating whether or not the operation was successful.
508 */
extend(ThreadState * tst,Addr addr,SizeT size)509 static Bool extend ( ThreadState *tst, Addr addr, SizeT size )
510 {
511 ThreadId tid = tst->tid;
512 NSegment const* stackseg = NULL;
513
514 if (VG_(extend_stack)(addr, tst->client_stack_szB)) {
515 stackseg = VG_(am_find_nsegment)(addr);
516 if (0 && stackseg)
517 VG_(printf)("frame=%#lx seg=%#lx-%#lx\n",
518 addr, stackseg->start, stackseg->end);
519 }
520
521 if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) {
522 VG_(message)(
523 Vg_UserMsg,
524 "Can't extend stack to %#lx during signal delivery for thread %d:\n",
525 addr, tid);
526 if (stackseg == NULL)
527 VG_(message)(Vg_UserMsg, " no stack segment\n");
528 else
529 VG_(message)(Vg_UserMsg, " too small or bad protection modes\n");
530
531 /* set SIGSEGV to default handler */
532 VG_(set_default_handler)(VKI_SIGSEGV);
533 VG_(synth_fault_mapping)(tid, addr);
534
535 /* The whole process should be about to die, since the default
536 action of SIGSEGV to kill the whole process. */
537 return False;
538 }
539
540 /* For tracking memory events, indicate the entire frame has been
541 allocated. */
542 VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB,
543 size + VG_STACK_REDZONE_SZB, tid );
544
545 return True;
546 }
547
548 //.. /* Build the Valgrind-specific part of a signal frame. */
549 //..
550 //.. static void build_vg_sigframe(struct vg_sigframe *frame,
551 //.. ThreadState *tst,
552 //.. const vki_sigset_t *mask,
553 //.. UInt flags,
554 //.. Int sigNo)
555 //.. {
556 //.. frame->sigNo_private = sigNo;
557 //.. frame->magicPI = 0x31415927;
558 //.. frame->vex_shadow = tst->arch.vex_shadow;
559 //.. /* HACK ALERT */
560 //.. frame->vex = tst->arch.vex;
561 //.. /* end HACK ALERT */
562 //.. frame->mask = tst->sig_mask;
563 //.. frame->handlerflags = flags;
564 //.. frame->magicE = 0x27182818;
565 //.. }
566
567
568 //.. static Addr build_sigframe(ThreadState *tst,
569 //.. Addr esp_top_of_frame,
570 //.. const vki_siginfo_t *siginfo,
571 //.. void *handler, UInt flags,
572 //.. const vki_sigset_t *mask,
573 //.. void *restorer)
574 //.. {
575 //.. struct sigframe *frame;
576 //.. Addr esp = esp_top_of_frame;
577 //.. Int sigNo = siginfo->si_signo;
578 //.. struct vki_ucontext uc;
579 //..
580 //.. vg_assert((flags & VKI_SA_SIGINFO) == 0);
581 //..
582 //.. esp -= sizeof(*frame);
583 //.. esp = ROUNDDN(esp, 16);
584 //.. frame = (struct sigframe *)esp;
585 //..
586 //.. if (!extend(tst, esp, sizeof(*frame)))
587 //.. return esp_top_of_frame;
588 //..
589 //.. /* retaddr, sigNo, siguContext fields are to be written */
590 //.. VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame",
591 //.. esp, offsetof(struct sigframe, vg) );
592 //..
593 //.. frame->sigNo = sigNo;
594 //..
595 //.. if (flags & VKI_SA_RESTORER)
596 //.. frame->retaddr = (Addr)restorer;
597 //.. else
598 //.. frame->retaddr
599 //.. = VG_(client_trampoline_code)+VG_(tramp_sigreturn_offset);
600 //..
601 //.. synth_ucontext(tst->tid, siginfo, mask, &uc, &frame->fpstate);
602 //..
603 //.. VG_(memcpy)(&frame->sigContext, &uc.uc_mcontext,
604 //.. sizeof(struct vki_sigcontext));
605 //.. frame->sigContext.oldmask = mask->sig[0];
606 //..
607 //.. VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
608 //.. esp, offsetof(struct sigframe, vg) );
609 //..
610 //.. build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
611 //..
612 //.. return esp;
613 //.. }
614
615
616 //.. static Addr build_rt_sigframe(ThreadState *tst,
617 //.. Addr esp_top_of_frame,
618 //.. const vki_siginfo_t *siginfo,
619 //.. void *handler, UInt flags,
620 //.. const vki_sigset_t *mask,
621 //.. void *restorer)
622 //.. {
623 //.. struct rt_sigframe *frame;
624 //.. Addr esp = esp_top_of_frame;
625 //.. Int sigNo = siginfo->si_signo;
626 //..
627 //.. vg_assert((flags & VKI_SA_SIGINFO) != 0);
628 //..
629 //.. esp -= sizeof(*frame);
630 //.. esp = ROUNDDN(esp, 16);
631 //.. frame = (struct rt_sigframe *)esp;
632 //..
633 //.. if (!extend(tst, esp, sizeof(*frame)))
634 //.. return esp_top_of_frame;
635 //..
636 //.. /* retaddr, sigNo, pSiginfo, puContext fields are to be written */
637 //.. VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "rt signal handler frame",
638 //.. esp, offsetof(struct rt_sigframe, vg) );
639 //..
640 //.. frame->sigNo = sigNo;
641 //..
642 //.. if (flags & VKI_SA_RESTORER)
643 //.. frame->retaddr = (Addr)restorer;
644 //.. else
645 //.. frame->retaddr
646 //.. = VG_(client_trampoline_code)+VG_(tramp_rt_sigreturn_offset);
647 //..
648 //.. frame->psigInfo = (Addr)&frame->sigInfo;
649 //.. frame->puContext = (Addr)&frame->uContext;
650 //.. VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
651 //..
652 //.. /* SIGILL defines addr to be the faulting address */
653 //.. if (sigNo == VKI_SIGILL && siginfo->si_code > 0)
654 //.. frame->sigInfo._sifields._sigfault._addr
655 //.. = (void*)tst->arch.vex.guest_CIA;
656 //..
657 //.. synth_ucontext(tst->tid, siginfo, mask, &frame->uContext, &frame->fpstate);
658 //..
659 //.. VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
660 //.. esp, offsetof(struct rt_sigframe, vg) );
661 //..
662 //.. build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
663 //..
664 //.. return esp;
665 //.. }
666
667
668 /* EXPORTED */
VG_(sigframe_create)669 void VG_(sigframe_create)( ThreadId tid,
670 Addr sp_top_of_frame,
671 const vki_siginfo_t *siginfo,
672 const struct vki_ucontext *siguc,
673 void *handler,
674 UInt flags,
675 const vki_sigset_t *mask,
676 void *restorer )
677 {
678 struct vg_sig_private *priv;
679 Addr sp;
680 ThreadState *tst;
681 Int sigNo = siginfo->si_signo;
682 Addr faultaddr;
683
684 /* Stack must be 16-byte aligned */
685 sp_top_of_frame &= ~0xf;
686
687 if (flags & VKI_SA_SIGINFO) {
688 sp = sp_top_of_frame - sizeof(struct rt_sigframe);
689 } else {
690 sp = sp_top_of_frame - sizeof(struct nonrt_sigframe);
691 }
692
693 tst = VG_(get_ThreadState)(tid);
694
695 if (!extend(tst, sp, sp_top_of_frame - sp))
696 return;
697
698 vg_assert(VG_IS_16_ALIGNED(sp));
699
700 /* Set up the stack chain pointer */
701 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame",
702 sp, sizeof(UWord) );
703 *(Addr *)sp = tst->arch.vex.guest_GPR1;
704 VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
705 sp, sizeof(UWord) );
706
707 faultaddr = (Addr)siginfo->_sifields._sigfault._addr;
708 if (sigNo == VKI_SIGILL && siginfo->si_code > 0)
709 faultaddr = tst->arch.vex.guest_CIA;
710
711 if (flags & VKI_SA_SIGINFO) {
712 struct rt_sigframe *frame = (struct rt_sigframe *) sp;
713 struct vki_ucontext *ucp = &frame->ucontext;
714
715 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame siginfo",
716 (Addr)&frame->siginfo, sizeof(frame->siginfo) );
717 VG_(memcpy)(&frame->siginfo, siginfo, sizeof(*siginfo));
718 VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
719 (Addr)&frame->siginfo, sizeof(frame->siginfo) );
720
721 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext",
722 (Addr)ucp, offsetof(struct vki_ucontext, uc_pad) );
723 ucp->uc_flags = 0;
724 ucp->uc_link = 0;
725 ucp->uc_stack = tst->altstack;
726 VG_TRACK( post_mem_write, Vg_CoreSignal, tid, (Addr)ucp,
727 offsetof(struct vki_ucontext, uc_pad) );
728
729 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext",
730 (Addr)&ucp->uc_regs,
731 sizeof(ucp->uc_regs) + sizeof(ucp->uc_sigmask) );
732 ucp->uc_regs = &ucp->uc_mcontext;
733 ucp->uc_sigmask = tst->sig_mask;
734 VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
735 (Addr)&ucp->uc_regs,
736 sizeof(ucp->uc_regs) + sizeof(ucp->uc_sigmask) );
737
738 stack_mcontext(&ucp->uc_mcontext, tst, True/*use_rt_sigreturn*/, faultaddr);
739 priv = &frame->priv;
740
741 SET_SIGNAL_GPR(tid, 4, (Addr) &frame->siginfo);
742 SET_SIGNAL_GPR(tid, 5, (Addr) ucp);
743 /* the kernel sets this, though it doesn't seem to be in the ABI */
744 SET_SIGNAL_GPR(tid, 6, (Addr) &frame->siginfo);
745
746 } else {
747 /* non-RT signal delivery */
748 struct nonrt_sigframe *frame = (struct nonrt_sigframe *) sp;
749 struct vki_sigcontext *scp = &frame->sigcontext;
750
751 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame sigcontext",
752 (Addr)&scp->_unused[3], sizeof(*scp) - 3 * sizeof(UInt) );
753 scp->signal = sigNo;
754 scp->handler = (Addr) handler;
755 scp->oldmask = tst->sig_mask.sig[0];
756 scp->_unused[3] = tst->sig_mask.sig[1];
757 VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
758 (Addr)&scp->_unused[3], sizeof(*scp) - 3 * sizeof(UInt) );
759
760 stack_mcontext(&frame->mcontext, tst, False/*!use_rt_sigreturn*/, faultaddr);
761 priv = &frame->priv;
762
763 SET_SIGNAL_GPR(tid, 4, (Addr) scp);
764 }
765
766 priv->magicPI = 0x31415927;
767 priv->sigNo_private = sigNo;
768 priv->vex_shadow1 = tst->arch.vex_shadow1;
769 priv->vex_shadow2 = tst->arch.vex_shadow2;
770
771 SET_SIGNAL_GPR(tid, 1, sp);
772 SET_SIGNAL_GPR(tid, 3, sigNo);
773 tst->arch.vex.guest_CIA = (Addr) handler;
774
775 //.. Addr esp;
776 //.. ThreadState* tst = VG_(get_ThreadState)(tid);
777 //..
778 //.. if (flags & VKI_SA_SIGINFO)
779 //.. esp = build_rt_sigframe(tst, esp_top_of_frame, siginfo,
780 //.. handler, flags, mask, restorer);
781 //.. else
782 //.. esp = build_sigframe(tst, esp_top_of_frame,
783 //.. siginfo, handler, flags, mask, restorer);
784 //..
785 //.. /* Set the thread so it will next run the handler. */
786 //.. /* tst->m_esp = esp; */
787 //.. SET_SIGNAL_ESP(tid, esp);
788 //..
789 //.. //VG_(printf)("handler = %p\n", handler);
790 //.. tst->arch.vex.guest_CIA = (Addr) handler;
791 //.. /* This thread needs to be marked runnable, but we leave that the
792 //.. caller to do. */
793
794 if (0)
795 VG_(printf)("pushed signal frame; %%R1 now = %#lx, "
796 "next %%CIA = %#x, status=%d\n",
797 sp, tst->arch.vex.guest_CIA, tst->status);
798 }
799
800
801 /*------------------------------------------------------------*/
802 /*--- Destroying signal frames ---*/
803 /*------------------------------------------------------------*/
804
805 //.. /* Return False and don't do anything, just set the client to take a
806 //.. segfault, if it looks like the frame is corrupted. */
807 //.. static
808 //.. Bool restore_vg_sigframe ( ThreadState *tst,
809 //.. struct vg_sigframe *frame, Int *sigNo )
810 //.. {
811 //.. if (frame->magicPI != 0x31415927 ||
812 //.. frame->magicE != 0x27182818) {
813 //.. VG_(message)(Vg_UserMsg, "Thread %d return signal frame "
814 //.. "corrupted. Killing process.",
815 //.. tst->tid);
816 //.. VG_(set_default_handler)(VKI_SIGSEGV);
817 //.. VG_(synth_fault)(tst->tid);
818 //.. *sigNo = VKI_SIGSEGV;
819 //.. return False;
820 //.. }
821 //.. tst->sig_mask = frame->mask;
822 //.. tst->tmp_sig_mask = frame->mask;
823 //.. tst->arch.vex_shadow = frame->vex_shadow;
824 //.. /* HACK ALERT */
825 //.. tst->arch.vex = frame->vex;
826 //.. /* end HACK ALERT */
827 //.. *sigNo = frame->sigNo_private;
828 //.. return True;
829 //.. }
830
831 //.. static
832 //.. void restore_sigcontext( ThreadState *tst,
833 //.. struct vki_sigcontext *sc )
834 //.. //.. struct vki_sigcontext *sc, struct _vki_fpstate *fpstate )
835 //.. {
836 //.. tst->arch.vex.guest_EAX = sc->eax;
837 //.. tst->arch.vex.guest_ECX = sc->ecx;
838 //.. tst->arch.vex.guest_EDX = sc->edx;
839 //.. tst->arch.vex.guest_EBX = sc->ebx;
840 //.. tst->arch.vex.guest_EBP = sc->ebp;
841 //.. tst->arch.vex.guest_ESP = sc->esp;
842 //.. tst->arch.vex.guest_ESI = sc->esi;
843 //.. tst->arch.vex.guest_EDI = sc->edi;
844 //.. //:: tst->arch.vex.guest_eflags = sc->eflags;
845 //.. //:: tst->arch.vex.guest_EIP = sc->eip;
846 //..
847 //.. tst->arch.vex.guest_CS = sc->cs;
848 //.. tst->arch.vex.guest_SS = sc->ss;
849 //.. tst->arch.vex.guest_DS = sc->ds;
850 //.. tst->arch.vex.guest_ES = sc->es;
851 //.. tst->arch.vex.guest_FS = sc->fs;
852 //.. tst->arch.vex.guest_GS = sc->gs;
853 //..
854 //.. //:: restore_i387(&tst->arch, fpstate);
855 //.. }
856
857
858 //.. static
859 //.. SizeT restore_sigframe ( ThreadState *tst,
860 //.. struct sigframe *frame, Int *sigNo )
861 //.. {
862 //.. if (restore_vg_sigframe(tst, &frame->vg, sigNo))
863 //.. restore_sigcontext(tst, &frame->sigContext, &frame->fpstate);
864 //.. return sizeof(*frame);
865 //.. }
866
867 //.. static
868 //.. SizeT restore_rt_sigframe ( ThreadState *tst,
869 //.. struct rt_sigframe *frame, Int *sigNo )
870 //.. {
871 //.. if (restore_vg_sigframe(tst, &frame->vg, sigNo))
872 //.. restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate);
873 //.. return sizeof(*frame);
874 //.. }
875
876
877 /* EXPORTED */
VG_(sigframe_destroy)878 void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
879 {
880 ThreadState *tst;
881 struct vg_sig_private *priv;
882 Addr sp;
883 UInt frame_size;
884 struct vki_mcontext *mc;
885 Int sigNo;
886 Bool has_siginfo = isRT;
887
888 vg_assert(VG_(is_valid_tid)(tid));
889 tst = VG_(get_ThreadState)(tid);
890
891 /* Check that the stack frame looks valid */
892 sp = tst->arch.vex.guest_GPR1;
893 vg_assert(VG_IS_16_ALIGNED(sp));
894 /* JRS 17 Nov 05: This code used to check that *sp -- which should
895 have been set by the stwu at the start of the handler -- points
896 to just above the frame (ie, the previous frame). However, that
897 isn't valid when delivering signals on alt stacks. So I removed
898 it. The frame is still sanity-checked using the priv->magicPI
899 field. */
900
901 if (has_siginfo) {
902 struct rt_sigframe *frame = (struct rt_sigframe *)sp;
903 frame_size = sizeof(*frame);
904 mc = &frame->ucontext.uc_mcontext;
905 priv = &frame->priv;
906 vg_assert(priv->magicPI == 0x31415927);
907 tst->sig_mask = frame->ucontext.uc_sigmask;
908 } else {
909 struct nonrt_sigframe *frame = (struct nonrt_sigframe *)sp;
910 frame_size = sizeof(*frame);
911 mc = &frame->mcontext;
912 priv = &frame->priv;
913 vg_assert(priv->magicPI == 0x31415927);
914 tst->sig_mask.sig[0] = frame->sigcontext.oldmask;
915 tst->sig_mask.sig[1] = frame->sigcontext._unused[3];
916 }
917 tst->tmp_sig_mask = tst->sig_mask;
918
919 sigNo = priv->sigNo_private;
920
921 # define DO(gpr) tst->arch.vex.guest_GPR##gpr = mc->mc_gregs[VKI_PT_R0+gpr]
922 DO(0); DO(1); DO(2); DO(3); DO(4); DO(5); DO(6); DO(7);
923 DO(8); DO(9); DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
924 DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
925 DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
926 # undef DO
927
928 tst->arch.vex.guest_CIA = mc->mc_gregs[VKI_PT_NIP];
929
930 // Umm ... ? (jrs 2005 July 8)
931 // tst->arch.m_orig_gpr3 = mc->mc_gregs[VKI_PT_ORIG_R3];
932
933 LibVEX_GuestPPC32_put_CR( mc->mc_gregs[VKI_PT_CCR], &tst->arch.vex );
934
935 tst->arch.vex.guest_LR = mc->mc_gregs[VKI_PT_LNK];
936 tst->arch.vex.guest_CTR = mc->mc_gregs[VKI_PT_CTR];
937 LibVEX_GuestPPC32_put_XER( mc->mc_gregs[VKI_PT_XER], &tst->arch.vex );
938
939 tst->arch.vex_shadow1 = priv->vex_shadow1;
940 tst->arch.vex_shadow2 = priv->vex_shadow2;
941
942 VG_TRACK(die_mem_stack_signal, sp, frame_size);
943
944 if (VG_(clo_trace_signals))
945 VG_(message)(Vg_DebugMsg,
946 "vg_pop_signal_frame (thread %d): "
947 "isRT=%d valid magic; EIP=%#x\n",
948 tid, has_siginfo, tst->arch.vex.guest_CIA);
949
950 /* tell the tools */
951 VG_TRACK( post_deliver_signal, tid, sigNo );
952
953 //.. Addr esp;
954 //.. ThreadState* tst;
955 //.. SizeT size;
956 //.. Int sigNo;
957 //..
958 //.. tst = VG_(get_ThreadState)(tid);
959 //..
960 //.. /* Correctly reestablish the frame base address. */
961 //.. esp = tst->arch.vex.guest_ESP;
962 //..
963 //.. if (!isRT)
964 //.. size = restore_sigframe(tst, (struct sigframe *)esp, &sigNo);
965 //.. else
966 //.. size = restore_rt_sigframe(tst, (struct rt_sigframe *)esp, &sigNo);
967 //..
968 //.. VG_TRACK( die_mem_stack_signal, esp, size );
969 //..
970 //.. if (VG_(clo_trace_signals))
971 //.. VG_(message)(
972 //.. Vg_DebugMsg,
973 //.. "VG_(signal_return) (thread %d): isRT=%d valid magic; EIP=%p",
974 //.. tid, isRT, tst->arch.vex.guest_EIP);
975 //..
976 //.. /* tell the tools */
977 //.. VG_TRACK( post_deliver_signal, tid, sigNo );
978 }
979
980 #endif // defined(VGP_ppc32_linux)
981
982 /*--------------------------------------------------------------------*/
983 /*--- end ---*/
984 /*--------------------------------------------------------------------*/
985