2 /*--------------------------------------------------------------------*/
3 /*--- Create/destroy signal delivery frames. ---*/
4 /*--- sigframe-s390x-linux.c ---*/
5 /*--------------------------------------------------------------------*/
8 This file is part of Valgrind, a dynamic binary instrumentation
11 Copyright IBM Corp. 2010-2013
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 The GNU General Public License is contained in the file COPYING.
31 /* Contributed by Christian Borntraeger */
33 #include "pub_core_basics.h"
34 #include "pub_core_vki.h"
35 #include "pub_core_vkiscnums.h"
36 #include "pub_core_threadstate.h"
37 #include "pub_core_aspacemgr.h"
38 #include "pub_core_libcbase.h"
39 #include "pub_core_libcassert.h"
40 #include "pub_core_libcprint.h"
41 #include "pub_core_machine.h"
42 #include "pub_core_options.h"
43 #include "pub_core_sigframe.h"
44 #include "pub_core_signals.h"
45 #include "pub_core_tooliface.h"
46 #include "pub_core_trampoline.h"
47 #include "priv_sigframe.h"
49 #if defined(VGA_s390x)
51 /* This module creates and removes signal frames for signal deliveries
54 Note, this file contains kernel-specific knowledge in the form of
55 'struct sigframe' and 'struct rt_sigframe'.
57 Either a 'struct sigframe' or a 'struct rtsigframe' is pushed
58 onto the client's stack. This contains a subsidiary
59 vki_ucontext. That holds the vcpu's state across the signal,
60 so that the sighandler can mess with the vcpu state if it
64 #define SET_SIGNAL_GPR(zztst, zzn, zzval) \
65 do { zztst->arch.vex.guest_r##zzn = (unsigned long)(zzval); \
66 VG_TRACK( post_reg_write, Vg_CoreSignal, zztst->tid, \
67 offsetof(VexGuestS390XState,guest_r##zzn), \
71 /*------------------------------------------------------------*/
72 /*--- Signal frame layouts ---*/
73 /*------------------------------------------------------------*/
75 // A structure in which to save the application's registers
76 // during the execution of signal handlers.
78 // Linux has 2 signal frame structures: one for normal signal
79 // deliveries, and one for SA_SIGINFO deliveries (also known as RT
82 // In theory, so long as we get the arguments to the handler function
83 // right, it doesn't matter what the exact layout of the rest of the
84 // frame is. Unfortunately, things like gcc's exception unwinding
85 // make assumptions about the locations of various parts of the frame,
86 // so we need to duplicate it exactly.
88 /* Valgrind-specific parts of the signal frame */
91 /* Sanity check word. */
94 UInt handlerflags
; /* flags for signal handler */
97 /* Safely-saved version of sigNo, as described above. */
100 /* XXX This is wrong. Surely we should store the shadow values
101 into the shadow memory behind the actual values? */
102 VexGuestS390XState vex_shadow1
;
103 VexGuestS390XState vex_shadow2
;
106 VexGuestS390XState vex
;
109 /* saved signal mask to be restored when handler returns */
112 /* Sanity check word. Is the highest-addressed word; do not
117 #define S390_SYSCALL_SIZE 2
121 UChar callee_used_stack
[__VKI_SIGNAL_FRAMESIZE
];
122 struct vki_sigcontext sc
;
125 UChar retcode
[S390_SYSCALL_SIZE
];
127 struct vg_sigframe vg
;
132 UChar callee_used_stack
[__VKI_SIGNAL_FRAMESIZE
];
133 UChar retcode
[S390_SYSCALL_SIZE
];
134 struct vki_siginfo info
;
135 struct vki_ucontext uc
;
137 struct vg_sigframe vg
;
140 /*------------------------------------------------------------*/
141 /*--- Creating signal frames ---*/
142 /*------------------------------------------------------------*/
144 /* Saves all user-controlled register into a _vki_sigregs structure */
145 static void save_sigregs(ThreadState
*tst
, _vki_sigregs
*sigregs
)
147 sigregs
->regs
.gprs
[0] = tst
->arch
.vex
.guest_r0
;
148 sigregs
->regs
.gprs
[1] = tst
->arch
.vex
.guest_r1
;
149 sigregs
->regs
.gprs
[2] = tst
->arch
.vex
.guest_r2
;
150 sigregs
->regs
.gprs
[3] = tst
->arch
.vex
.guest_r3
;
151 sigregs
->regs
.gprs
[4] = tst
->arch
.vex
.guest_r4
;
152 sigregs
->regs
.gprs
[5] = tst
->arch
.vex
.guest_r5
;
153 sigregs
->regs
.gprs
[6] = tst
->arch
.vex
.guest_r6
;
154 sigregs
->regs
.gprs
[7] = tst
->arch
.vex
.guest_r7
;
155 sigregs
->regs
.gprs
[8] = tst
->arch
.vex
.guest_r8
;
156 sigregs
->regs
.gprs
[9] = tst
->arch
.vex
.guest_r9
;
157 sigregs
->regs
.gprs
[10] = tst
->arch
.vex
.guest_r10
;
158 sigregs
->regs
.gprs
[11] = tst
->arch
.vex
.guest_r11
;
159 sigregs
->regs
.gprs
[12] = tst
->arch
.vex
.guest_r12
;
160 sigregs
->regs
.gprs
[13] = tst
->arch
.vex
.guest_r13
;
161 sigregs
->regs
.gprs
[14] = tst
->arch
.vex
.guest_r14
;
162 sigregs
->regs
.gprs
[15] = tst
->arch
.vex
.guest_r15
;
164 sigregs
->regs
.acrs
[0] = tst
->arch
.vex
.guest_a0
;
165 sigregs
->regs
.acrs
[1] = tst
->arch
.vex
.guest_a1
;
166 sigregs
->regs
.acrs
[2] = tst
->arch
.vex
.guest_a2
;
167 sigregs
->regs
.acrs
[3] = tst
->arch
.vex
.guest_a3
;
168 sigregs
->regs
.acrs
[4] = tst
->arch
.vex
.guest_a4
;
169 sigregs
->regs
.acrs
[5] = tst
->arch
.vex
.guest_a5
;
170 sigregs
->regs
.acrs
[6] = tst
->arch
.vex
.guest_a6
;
171 sigregs
->regs
.acrs
[7] = tst
->arch
.vex
.guest_a7
;
172 sigregs
->regs
.acrs
[8] = tst
->arch
.vex
.guest_a8
;
173 sigregs
->regs
.acrs
[9] = tst
->arch
.vex
.guest_a9
;
174 sigregs
->regs
.acrs
[10] = tst
->arch
.vex
.guest_a10
;
175 sigregs
->regs
.acrs
[11] = tst
->arch
.vex
.guest_a11
;
176 sigregs
->regs
.acrs
[12] = tst
->arch
.vex
.guest_a12
;
177 sigregs
->regs
.acrs
[13] = tst
->arch
.vex
.guest_a13
;
178 sigregs
->regs
.acrs
[14] = tst
->arch
.vex
.guest_a14
;
179 sigregs
->regs
.acrs
[15] = tst
->arch
.vex
.guest_a15
;
181 sigregs
->fpregs
.fprs
[0] = tst
->arch
.vex
.guest_f0
;
182 sigregs
->fpregs
.fprs
[1] = tst
->arch
.vex
.guest_f1
;
183 sigregs
->fpregs
.fprs
[2] = tst
->arch
.vex
.guest_f2
;
184 sigregs
->fpregs
.fprs
[3] = tst
->arch
.vex
.guest_f3
;
185 sigregs
->fpregs
.fprs
[4] = tst
->arch
.vex
.guest_f4
;
186 sigregs
->fpregs
.fprs
[5] = tst
->arch
.vex
.guest_f5
;
187 sigregs
->fpregs
.fprs
[6] = tst
->arch
.vex
.guest_f6
;
188 sigregs
->fpregs
.fprs
[7] = tst
->arch
.vex
.guest_f7
;
189 sigregs
->fpregs
.fprs
[8] = tst
->arch
.vex
.guest_f8
;
190 sigregs
->fpregs
.fprs
[9] = tst
->arch
.vex
.guest_f9
;
191 sigregs
->fpregs
.fprs
[10] = tst
->arch
.vex
.guest_f10
;
192 sigregs
->fpregs
.fprs
[11] = tst
->arch
.vex
.guest_f11
;
193 sigregs
->fpregs
.fprs
[12] = tst
->arch
.vex
.guest_f12
;
194 sigregs
->fpregs
.fprs
[13] = tst
->arch
.vex
.guest_f13
;
195 sigregs
->fpregs
.fprs
[14] = tst
->arch
.vex
.guest_f14
;
196 sigregs
->fpregs
.fprs
[15] = tst
->arch
.vex
.guest_f15
;
197 sigregs
->fpregs
.fpc
= tst
->arch
.vex
.guest_fpc
;
199 sigregs
->regs
.psw
.addr
= tst
->arch
.vex
.guest_IA
;
200 /* save a sane dummy mask */
201 sigregs
->regs
.psw
.mask
= 0x0705000180000000UL
;
204 static void restore_sigregs(ThreadState
*tst
, _vki_sigregs
*sigregs
)
206 tst
->arch
.vex
.guest_r0
= sigregs
->regs
.gprs
[0];
207 tst
->arch
.vex
.guest_r1
= sigregs
->regs
.gprs
[1];
208 tst
->arch
.vex
.guest_r2
= sigregs
->regs
.gprs
[2];
209 tst
->arch
.vex
.guest_r3
= sigregs
->regs
.gprs
[3];
210 tst
->arch
.vex
.guest_r4
= sigregs
->regs
.gprs
[4];
211 tst
->arch
.vex
.guest_r5
= sigregs
->regs
.gprs
[5];
212 tst
->arch
.vex
.guest_r6
= sigregs
->regs
.gprs
[6];
213 tst
->arch
.vex
.guest_r7
= sigregs
->regs
.gprs
[7];
214 tst
->arch
.vex
.guest_r8
= sigregs
->regs
.gprs
[8];
215 tst
->arch
.vex
.guest_r9
= sigregs
->regs
.gprs
[9];
216 tst
->arch
.vex
.guest_r10
= sigregs
->regs
.gprs
[10];
217 tst
->arch
.vex
.guest_r11
= sigregs
->regs
.gprs
[11];
218 tst
->arch
.vex
.guest_r12
= sigregs
->regs
.gprs
[12];
219 tst
->arch
.vex
.guest_r13
= sigregs
->regs
.gprs
[13];
220 tst
->arch
.vex
.guest_r14
= sigregs
->regs
.gprs
[14];
221 tst
->arch
.vex
.guest_r15
= sigregs
->regs
.gprs
[15];
223 tst
->arch
.vex
.guest_a0
= sigregs
->regs
.acrs
[0];
224 tst
->arch
.vex
.guest_a1
= sigregs
->regs
.acrs
[1];
225 tst
->arch
.vex
.guest_a2
= sigregs
->regs
.acrs
[2];
226 tst
->arch
.vex
.guest_a3
= sigregs
->regs
.acrs
[3];
227 tst
->arch
.vex
.guest_a4
= sigregs
->regs
.acrs
[4];
228 tst
->arch
.vex
.guest_a5
= sigregs
->regs
.acrs
[5];
229 tst
->arch
.vex
.guest_a6
= sigregs
->regs
.acrs
[6];
230 tst
->arch
.vex
.guest_a7
= sigregs
->regs
.acrs
[7];
231 tst
->arch
.vex
.guest_a8
= sigregs
->regs
.acrs
[8];
232 tst
->arch
.vex
.guest_a9
= sigregs
->regs
.acrs
[9];
233 tst
->arch
.vex
.guest_a10
= sigregs
->regs
.acrs
[10];
234 tst
->arch
.vex
.guest_a11
= sigregs
->regs
.acrs
[11];
235 tst
->arch
.vex
.guest_a12
= sigregs
->regs
.acrs
[12];
236 tst
->arch
.vex
.guest_a13
= sigregs
->regs
.acrs
[13];
237 tst
->arch
.vex
.guest_a14
= sigregs
->regs
.acrs
[14];
238 tst
->arch
.vex
.guest_a15
= sigregs
->regs
.acrs
[15];
240 tst
->arch
.vex
.guest_f0
= sigregs
->fpregs
.fprs
[0];
241 tst
->arch
.vex
.guest_f1
= sigregs
->fpregs
.fprs
[1];
242 tst
->arch
.vex
.guest_f2
= sigregs
->fpregs
.fprs
[2];
243 tst
->arch
.vex
.guest_f3
= sigregs
->fpregs
.fprs
[3];
244 tst
->arch
.vex
.guest_f4
= sigregs
->fpregs
.fprs
[4];
245 tst
->arch
.vex
.guest_f5
= sigregs
->fpregs
.fprs
[5];
246 tst
->arch
.vex
.guest_f6
= sigregs
->fpregs
.fprs
[6];
247 tst
->arch
.vex
.guest_f7
= sigregs
->fpregs
.fprs
[7];
248 tst
->arch
.vex
.guest_f8
= sigregs
->fpregs
.fprs
[8];
249 tst
->arch
.vex
.guest_f9
= sigregs
->fpregs
.fprs
[9];
250 tst
->arch
.vex
.guest_f10
= sigregs
->fpregs
.fprs
[10];
251 tst
->arch
.vex
.guest_f11
= sigregs
->fpregs
.fprs
[11];
252 tst
->arch
.vex
.guest_f12
= sigregs
->fpregs
.fprs
[12];
253 tst
->arch
.vex
.guest_f13
= sigregs
->fpregs
.fprs
[13];
254 tst
->arch
.vex
.guest_f14
= sigregs
->fpregs
.fprs
[14];
255 tst
->arch
.vex
.guest_f15
= sigregs
->fpregs
.fprs
[15];
256 tst
->arch
.vex
.guest_fpc
= sigregs
->fpregs
.fpc
;
258 tst
->arch
.vex
.guest_IA
= sigregs
->regs
.psw
.addr
;
262 /* Build the Valgrind-specific part of a signal frame. */
264 static void build_vg_sigframe(struct vg_sigframe
*frame
,
269 frame
->sigNo_private
= sigNo
;
270 frame
->magicPI
= 0x31415927;
271 frame
->vex_shadow1
= tst
->arch
.vex_shadow1
;
272 frame
->vex_shadow2
= tst
->arch
.vex_shadow2
;
274 frame
->vex
= tst
->arch
.vex
;
276 frame
->mask
= tst
->sig_mask
;
277 frame
->handlerflags
= flags
;
278 frame
->magicE
= 0x27182818;
282 static Addr
build_sigframe(ThreadState
*tst
,
283 Addr sp_top_of_frame
,
284 const vki_siginfo_t
*siginfo
,
285 const struct vki_ucontext
*siguc
,
287 const vki_sigset_t
*mask
,
290 struct sigframe
*frame
;
291 Addr sp
= sp_top_of_frame
;
293 vg_assert((flags
& VKI_SA_SIGINFO
) == 0);
294 vg_assert((sizeof(*frame
) & 7) == 0);
295 vg_assert((sp
& 7) == 0);
297 sp
-= sizeof(*frame
);
298 frame
= (struct sigframe
*)sp
;
300 if (! ML_(sf_maybe_extend_stack
)(tst
, sp
, sizeof(*frame
), flags
))
301 return sp_top_of_frame
;
303 /* retcode, sigNo, sc, sregs fields are to be written */
304 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tst
->tid
, "signal handler frame",
305 sp
, offsetof(struct sigframe
, vg
) );
307 save_sigregs(tst
, &frame
->sregs
);
309 frame
->sigNo
= siginfo
->si_signo
;
310 frame
->sc
.sregs
= &frame
->sregs
;
311 VG_(memcpy
)(frame
->sc
.oldmask
, mask
->sig
, sizeof(frame
->sc
.oldmask
));
313 if (flags
& VKI_SA_RESTORER
) {
314 SET_SIGNAL_GPR(tst
, 14, restorer
);
316 frame
->retcode
[0] = 0x0a;
317 frame
->retcode
[1] = __NR_sigreturn
;
318 /* This normally should be &frame->recode. but since there
319 might be problems with non-exec stack and we must discard
320 the translation for the on-stack sigreturn we just use the
321 trampoline like x86,ppc. We still fill in the retcode, lets
322 just hope that nobody actually jumps here */
323 SET_SIGNAL_GPR(tst
, 14, (Addr
)&VG_(s390x_linux_SUBST_FOR_sigreturn
));
326 SET_SIGNAL_GPR(tst
, 2, siginfo
->si_signo
);
327 SET_SIGNAL_GPR(tst
, 3, &frame
->sc
);
328 /* fixs390: we dont fill in trapno and prot_addr in r4 and r5*/
330 /* Set up backchain. */
331 *((Addr
*) sp
) = sp_top_of_frame
;
333 VG_TRACK( post_mem_write
, Vg_CoreSignal
, tst
->tid
,
334 sp
, offsetof(struct sigframe
, vg
) );
336 build_vg_sigframe(&frame
->vg
, tst
, flags
, siginfo
->si_signo
);
341 static Addr
build_rt_sigframe(ThreadState
*tst
,
342 Addr sp_top_of_frame
,
343 const vki_siginfo_t
*siginfo
,
344 const struct vki_ucontext
*siguc
,
346 const vki_sigset_t
*mask
,
349 struct rt_sigframe
*frame
;
350 Addr sp
= sp_top_of_frame
;
351 Int sigNo
= siginfo
->si_signo
;
353 vg_assert((flags
& VKI_SA_SIGINFO
) != 0);
354 vg_assert((sizeof(*frame
) & 7) == 0);
355 vg_assert((sp
& 7) == 0);
357 sp
-= sizeof(*frame
);
358 frame
= (struct rt_sigframe
*)sp
;
360 if (! ML_(sf_maybe_extend_stack
)(tst
, sp
, sizeof(*frame
), flags
))
361 return sp_top_of_frame
;
363 /* retcode, sigNo, sc, sregs fields are to be written */
364 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tst
->tid
, "signal handler frame",
365 sp
, offsetof(struct rt_sigframe
, vg
) );
367 save_sigregs(tst
, &frame
->uc
.uc_mcontext
);
369 if (flags
& VKI_SA_RESTORER
) {
370 frame
->retcode
[0] = 0;
371 frame
->retcode
[1] = 0;
372 SET_SIGNAL_GPR(tst
, 14, restorer
);
374 frame
->retcode
[0] = 0x0a;
375 frame
->retcode
[1] = __NR_rt_sigreturn
;
376 /* This normally should be &frame->recode. but since there
377 might be problems with non-exec stack and we must discard
378 the translation for the on-stack sigreturn we just use the
379 trampoline like x86,ppc. We still fill in the retcode, lets
380 just hope that nobody actually jumps here */
381 SET_SIGNAL_GPR(tst
, 14, (Addr
)&VG_(s390x_linux_SUBST_FOR_rt_sigreturn
));
384 VG_(memcpy
)(&frame
->info
, siginfo
, sizeof(vki_siginfo_t
));
385 frame
->uc
.uc_flags
= 0;
386 frame
->uc
.uc_link
= 0;
387 frame
->uc
.uc_sigmask
= *mask
;
388 frame
->uc
.uc_stack
= tst
->altstack
;
390 SET_SIGNAL_GPR(tst
, 2, siginfo
->si_signo
);
391 SET_SIGNAL_GPR(tst
, 3, &frame
->info
);
392 SET_SIGNAL_GPR(tst
, 4, &frame
->uc
);
394 /* Set up backchain. */
395 *((Addr
*) sp
) = sp_top_of_frame
;
397 VG_TRACK( post_mem_write
, Vg_CoreSignal
, tst
->tid
,
398 sp
, offsetof(struct rt_sigframe
, vg
) );
400 build_vg_sigframe(&frame
->vg
, tst
, flags
, sigNo
);
405 void VG_(sigframe_create
)( ThreadId tid
,
407 Addr sp_top_of_frame
,
408 const vki_siginfo_t
*siginfo
,
409 const struct vki_ucontext
*siguc
,
412 const vki_sigset_t
*mask
,
416 ThreadState
* tst
= VG_(get_ThreadState
)(tid
);
418 if (flags
& VKI_SA_SIGINFO
)
419 sp
= build_rt_sigframe(tst
, sp_top_of_frame
, siginfo
, siguc
,
420 flags
, mask
, restorer
);
422 sp
= build_sigframe(tst
, sp_top_of_frame
, siginfo
, siguc
,
423 flags
, mask
, restorer
);
425 /* Set the thread so it will next run the handler. */
426 VG_(set_SP
)(tid
, sp
);
427 VG_TRACK( post_reg_write
, Vg_CoreSignal
, tid
, VG_O_STACK_PTR
, sizeof(Addr
));
429 tst
->arch
.vex
.guest_IA
= (Addr
) handler
;
430 /* We might have interrupted a repeating instruction that uses the guest
431 counter. Since our VEX requires that a new instruction will see a
432 guest counter == 0, we have to set it here. The old value will be
433 restored by restore_vg_sigframe. */
434 tst
->arch
.vex
.guest_counter
= 0;
435 /* This thread needs to be marked runnable, but we leave that the
440 /*------------------------------------------------------------*/
441 /*--- Destroying signal frames ---*/
442 /*------------------------------------------------------------*/
444 /* Return False and don't do anything, just set the client to take a
445 segfault, if it looks like the frame is corrupted. */
447 Bool
restore_vg_sigframe ( ThreadState
*tst
,
448 struct vg_sigframe
*frame
, Int
*sigNo
)
450 if (frame
->magicPI
!= 0x31415927 ||
451 frame
->magicE
!= 0x27182818) {
452 VG_(message
)(Vg_UserMsg
, "Thread %d return signal frame "
453 "corrupted. Killing process.\n",
455 VG_(set_default_handler
)(VKI_SIGSEGV
);
456 VG_(synth_fault
)(tst
->tid
);
457 *sigNo
= VKI_SIGSEGV
;
460 tst
->sig_mask
= frame
->mask
;
461 tst
->tmp_sig_mask
= frame
->mask
;
462 tst
->arch
.vex_shadow1
= frame
->vex_shadow1
;
463 tst
->arch
.vex_shadow2
= frame
->vex_shadow2
;
465 tst
->arch
.vex
= frame
->vex
;
467 *sigNo
= frame
->sigNo_private
;
472 SizeT
restore_sigframe ( ThreadState
*tst
,
473 struct sigframe
*frame
, Int
*sigNo
)
475 if (restore_vg_sigframe(tst
, &frame
->vg
, sigNo
))
476 restore_sigregs(tst
, frame
->sc
.sregs
);
478 return sizeof(*frame
);
482 SizeT
restore_rt_sigframe ( ThreadState
*tst
,
483 struct rt_sigframe
*frame
, Int
*sigNo
)
485 if (restore_vg_sigframe(tst
, &frame
->vg
, sigNo
)) {
486 restore_sigregs(tst
, &frame
->uc
.uc_mcontext
);
488 return sizeof(*frame
);
493 void VG_(sigframe_destroy
)( ThreadId tid
, Bool isRT
)
500 tst
= VG_(get_ThreadState
)(tid
);
502 /* Correctly reestablish the frame base address. */
503 sp
= tst
->arch
.vex
.guest_SP
;
506 size
= restore_sigframe(tst
, (struct sigframe
*)sp
, &sigNo
);
508 size
= restore_rt_sigframe(tst
, (struct rt_sigframe
*)sp
, &sigNo
);
510 /* same as for creation: we must announce the full memory (including
511 alignment), otherwise massif might fail on longjmp */
512 VG_TRACK( die_mem_stack_signal
, sp
- VG_STACK_REDZONE_SZB
,
513 size
+ VG_STACK_REDZONE_SZB
);
515 if (VG_(clo_trace_signals
))
518 "VG_(sigframe_destroy) (thread %d): isRT=%d valid magic; IP=%#llx\n",
519 tid
, isRT
, tst
->arch
.vex
.guest_IA
);
522 VG_TRACK( post_deliver_signal
, tid
, sigNo
);
525 #endif /* VGA_s390x */
527 /*--------------------------------------------------------------------*/
528 /*--- end sigframe-s390x-linux.c ---*/
529 /*--------------------------------------------------------------------*/