drd: Add a consistency check
[valgrind.git] / coregrind / m_sigframe / sigframe-s390x-linux.c
blob5210cebb0452cdd6fb5ede4b21dfe13b935f8356
2 /*--------------------------------------------------------------------*/
3 /*--- Create/destroy signal delivery frames. ---*/
4 /*--- sigframe-s390x-linux.c ---*/
5 /*--------------------------------------------------------------------*/
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
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
26 02111-1307, USA.
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_libcsetjmp.h" // to keep _threadstate.h happy
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"
49 #if defined(VGA_s390x)
51 /* This module creates and removes signal frames for signal deliveries
52 on s390x-linux.
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
61 really wants.
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), \
68 sizeof(UWord) ); \
69 } while (0)
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
80 // signals).
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 */
89 struct vg_sigframe
91 /* Sanity check word. */
92 UInt magicPI;
94 UInt handlerflags; /* flags for signal handler */
97 /* Safely-saved version of sigNo, as described above. */
98 Int sigNo_private;
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;
105 /* HACK ALERT */
106 VexGuestS390XState vex;
107 /* end HACK ALERT */
109 /* saved signal mask to be restored when handler returns */
110 vki_sigset_t mask;
112 /* Sanity check word. Is the highest-addressed word; do not
113 move!*/
114 UInt magicE;
117 #define S390_SYSCALL_SIZE 2
119 struct sigframe
121 UChar callee_used_stack[__VKI_SIGNAL_FRAMESIZE];
122 struct vki_sigcontext sc;
123 _vki_sigregs sregs;
124 Int sigNo;
125 UChar retcode[S390_SYSCALL_SIZE];
127 struct vg_sigframe vg;
130 struct rt_sigframe
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;
261 /* Extend the stack segment downwards if needed so as to ensure the
262 new signal frames are mapped to something. Return a Bool
263 indicating whether or not the operation was successful.
265 static Bool extend ( ThreadState *tst, Addr addr, SizeT size )
267 ThreadId tid = tst->tid;
268 NSegment const* stackseg = NULL;
270 if (VG_(extend_stack)(addr, tst->client_stack_szB)) {
271 stackseg = VG_(am_find_nsegment)(addr);
272 if (0 && stackseg)
273 VG_(printf)("frame=%#lx seg=%#lx-%#lx\n",
274 addr, stackseg->start, stackseg->end);
277 if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) {
278 VG_(message)(
279 Vg_UserMsg,
280 "Can't extend stack to %#lx during signal delivery for thread %d:\n",
281 addr, tid);
282 if (stackseg == NULL)
283 VG_(message)(Vg_UserMsg, " no stack segment\n");
284 else
285 VG_(message)(Vg_UserMsg, " too small or bad protection modes\n");
287 /* set SIGSEGV to default handler */
288 VG_(set_default_handler)(VKI_SIGSEGV);
289 VG_(synth_fault_mapping)(tid, addr);
291 /* The whole process should be about to die, since the default
292 action of SIGSEGV to kill the whole process. */
293 return False;
296 /* For tracking memory events, indicate the entire frame has been
297 allocated. */
298 VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB,
299 size + VG_STACK_REDZONE_SZB, tid );
301 return True;
305 /* Build the Valgrind-specific part of a signal frame. */
307 static void build_vg_sigframe(struct vg_sigframe *frame,
308 ThreadState *tst,
309 UInt flags,
310 Int sigNo)
312 frame->sigNo_private = sigNo;
313 frame->magicPI = 0x31415927;
314 frame->vex_shadow1 = tst->arch.vex_shadow1;
315 frame->vex_shadow2 = tst->arch.vex_shadow2;
316 /* HACK ALERT */
317 frame->vex = tst->arch.vex;
318 /* end HACK ALERT */
319 frame->mask = tst->sig_mask;
320 frame->handlerflags = flags;
321 frame->magicE = 0x27182818;
325 static Addr build_sigframe(ThreadState *tst,
326 Addr sp_top_of_frame,
327 const vki_siginfo_t *siginfo,
328 const struct vki_ucontext *siguc,
329 UInt flags,
330 const vki_sigset_t *mask,
331 void *restorer)
333 struct sigframe *frame;
334 Addr sp = sp_top_of_frame;
336 vg_assert((flags & VKI_SA_SIGINFO) == 0);
337 vg_assert((sizeof(*frame) & 7) == 0);
338 vg_assert((sp & 7) == 0);
340 sp -= sizeof(*frame);
341 frame = (struct sigframe *)sp;
343 if (!extend(tst, sp, sizeof(*frame)))
344 return sp_top_of_frame;
346 /* retcode, sigNo, sc, sregs fields are to be written */
347 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame",
348 sp, offsetof(struct sigframe, vg) );
350 save_sigregs(tst, &frame->sregs);
352 frame->sigNo = siginfo->si_signo;
353 frame->sc.sregs = &frame->sregs;
354 VG_(memcpy)(frame->sc.oldmask, mask->sig, sizeof(frame->sc.oldmask));
356 if (flags & VKI_SA_RESTORER) {
357 SET_SIGNAL_GPR(tst, 14, restorer);
358 } else {
359 frame->retcode[0] = 0x0a;
360 frame->retcode[1] = __NR_sigreturn;
361 /* This normally should be &frame->recode. but since there
362 might be problems with non-exec stack and we must discard
363 the translation for the on-stack sigreturn we just use the
364 trampoline like x86,ppc. We still fill in the retcode, lets
365 just hope that nobody actually jumps here */
366 SET_SIGNAL_GPR(tst, 14, (Addr)&VG_(s390x_linux_SUBST_FOR_sigreturn));
369 SET_SIGNAL_GPR(tst, 2, siginfo->si_signo);
370 SET_SIGNAL_GPR(tst, 3, &frame->sc);
371 /* fixs390: we dont fill in trapno and prot_addr in r4 and r5*/
373 /* Set up backchain. */
374 *((Addr *) sp) = sp_top_of_frame;
376 VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
377 sp, offsetof(struct sigframe, vg) );
379 build_vg_sigframe(&frame->vg, tst, flags, siginfo->si_signo);
381 return sp;
384 static Addr build_rt_sigframe(ThreadState *tst,
385 Addr sp_top_of_frame,
386 const vki_siginfo_t *siginfo,
387 const struct vki_ucontext *siguc,
388 UInt flags,
389 const vki_sigset_t *mask,
390 void *restorer)
392 struct rt_sigframe *frame;
393 Addr sp = sp_top_of_frame;
394 Int sigNo = siginfo->si_signo;
396 vg_assert((flags & VKI_SA_SIGINFO) != 0);
397 vg_assert((sizeof(*frame) & 7) == 0);
398 vg_assert((sp & 7) == 0);
400 sp -= sizeof(*frame);
401 frame = (struct rt_sigframe *)sp;
403 if (!extend(tst, sp, sizeof(*frame)))
404 return sp_top_of_frame;
406 /* retcode, sigNo, sc, sregs fields are to be written */
407 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame",
408 sp, offsetof(struct rt_sigframe, vg) );
410 save_sigregs(tst, &frame->uc.uc_mcontext);
412 if (flags & VKI_SA_RESTORER) {
413 frame->retcode[0] = 0;
414 frame->retcode[1] = 0;
415 SET_SIGNAL_GPR(tst, 14, restorer);
416 } else {
417 frame->retcode[0] = 0x0a;
418 frame->retcode[1] = __NR_rt_sigreturn;
419 /* This normally should be &frame->recode. but since there
420 might be problems with non-exec stack and we must discard
421 the translation for the on-stack sigreturn we just use the
422 trampoline like x86,ppc. We still fill in the retcode, lets
423 just hope that nobody actually jumps here */
424 SET_SIGNAL_GPR(tst, 14, (Addr)&VG_(s390x_linux_SUBST_FOR_rt_sigreturn));
427 VG_(memcpy)(&frame->info, siginfo, sizeof(vki_siginfo_t));
428 frame->uc.uc_flags = 0;
429 frame->uc.uc_link = 0;
430 frame->uc.uc_sigmask = *mask;
431 frame->uc.uc_stack = tst->altstack;
433 SET_SIGNAL_GPR(tst, 2, siginfo->si_signo);
434 SET_SIGNAL_GPR(tst, 3, &frame->info);
435 SET_SIGNAL_GPR(tst, 4, &frame->uc);
437 /* Set up backchain. */
438 *((Addr *) sp) = sp_top_of_frame;
440 VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
441 sp, offsetof(struct rt_sigframe, vg) );
443 build_vg_sigframe(&frame->vg, tst, flags, sigNo);
444 return sp;
447 /* EXPORTED */
448 void VG_(sigframe_create)( ThreadId tid,
449 Addr sp_top_of_frame,
450 const vki_siginfo_t *siginfo,
451 const struct vki_ucontext *siguc,
452 void *handler,
453 UInt flags,
454 const vki_sigset_t *mask,
455 void *restorer )
457 Addr sp;
458 ThreadState* tst = VG_(get_ThreadState)(tid);
460 if (flags & VKI_SA_SIGINFO)
461 sp = build_rt_sigframe(tst, sp_top_of_frame, siginfo, siguc,
462 flags, mask, restorer);
463 else
464 sp = build_sigframe(tst, sp_top_of_frame, siginfo, siguc,
465 flags, mask, restorer);
467 /* Set the thread so it will next run the handler. */
468 VG_(set_SP)(tid, sp);
469 VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr));
471 tst->arch.vex.guest_IA = (Addr) handler;
472 /* We might have interrupted a repeating instruction that uses the guest
473 counter. Since our VEX requires that a new instruction will see a
474 guest counter == 0, we have to set it here. The old value will be
475 restored by restore_vg_sigframe. */
476 tst->arch.vex.guest_counter = 0;
477 /* This thread needs to be marked runnable, but we leave that the
478 caller to do. */
482 /*------------------------------------------------------------*/
483 /*--- Destroying signal frames ---*/
484 /*------------------------------------------------------------*/
486 /* Return False and don't do anything, just set the client to take a
487 segfault, if it looks like the frame is corrupted. */
488 static
489 Bool restore_vg_sigframe ( ThreadState *tst,
490 struct vg_sigframe *frame, Int *sigNo )
492 if (frame->magicPI != 0x31415927 ||
493 frame->magicE != 0x27182818) {
494 VG_(message)(Vg_UserMsg, "Thread %d return signal frame "
495 "corrupted. Killing process.\n",
496 tst->tid);
497 VG_(set_default_handler)(VKI_SIGSEGV);
498 VG_(synth_fault)(tst->tid);
499 *sigNo = VKI_SIGSEGV;
500 return False;
502 tst->sig_mask = frame->mask;
503 tst->tmp_sig_mask = frame->mask;
504 tst->arch.vex_shadow1 = frame->vex_shadow1;
505 tst->arch.vex_shadow2 = frame->vex_shadow2;
506 /* HACK ALERT */
507 tst->arch.vex = frame->vex;
508 /* end HACK ALERT */
509 *sigNo = frame->sigNo_private;
510 return True;
513 static
514 SizeT restore_sigframe ( ThreadState *tst,
515 struct sigframe *frame, Int *sigNo )
517 if (restore_vg_sigframe(tst, &frame->vg, sigNo))
518 restore_sigregs(tst, frame->sc.sregs);
520 return sizeof(*frame);
523 static
524 SizeT restore_rt_sigframe ( ThreadState *tst,
525 struct rt_sigframe *frame, Int *sigNo )
527 if (restore_vg_sigframe(tst, &frame->vg, sigNo)) {
528 restore_sigregs(tst, &frame->uc.uc_mcontext);
530 return sizeof(*frame);
534 /* EXPORTED */
535 void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
537 Addr sp;
538 ThreadState* tst;
539 SizeT size;
540 Int sigNo;
542 tst = VG_(get_ThreadState)(tid);
544 /* Correctly reestablish the frame base address. */
545 sp = tst->arch.vex.guest_SP;
547 if (!isRT)
548 size = restore_sigframe(tst, (struct sigframe *)sp, &sigNo);
549 else
550 size = restore_rt_sigframe(tst, (struct rt_sigframe *)sp, &sigNo);
552 /* same as for creation: we must announce the full memory (including
553 alignment), otherwise massif might fail on longjmp */
554 VG_TRACK( die_mem_stack_signal, sp - VG_STACK_REDZONE_SZB,
555 size + VG_STACK_REDZONE_SZB );
557 if (VG_(clo_trace_signals))
558 VG_(message)(
559 Vg_DebugMsg,
560 "VG_(sigframe_destroy) (thread %d): isRT=%d valid magic; IP=%#llx\n",
561 tid, isRT, tst->arch.vex.guest_IA);
563 /* tell the tools */
564 VG_TRACK( post_deliver_signal, tid, sigNo );
567 #endif /* VGA_s390x */
569 /*--------------------------------------------------------------------*/
570 /*--- end sigframe-s390x-linux.c ---*/
571 /*--------------------------------------------------------------------*/