1
2/*--------------------------------------------------------------------*/
3/*--- Create/destroy signal delivery frames.                       ---*/
4/*---                                       sigframe-s390x-linux.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8   This file is part of Valgrind, a dynamic binary instrumentation
9   framework.
10
11   Copyright IBM Corp. 2010-2015
12
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.
17
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.
22
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.
27
28   The GNU General Public License is contained in the file COPYING.
29*/
30
31/* Contributed by Christian Borntraeger */
32
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"
48
49#if defined(VGA_s390x)
50
51/* This module creates and removes signal frames for signal deliveries
52   on s390x-linux.
53
54   Note, this file contains kernel-specific knowledge in the form of
55   'struct sigframe' and 'struct rt_sigframe'.
56
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.
62*/
63
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)
70
71/*------------------------------------------------------------*/
72/*--- Signal frame layouts                                 ---*/
73/*------------------------------------------------------------*/
74
75// A structure in which to save the application's registers
76// during the execution of signal handlers.
77
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).
81//
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.
87
88/* Valgrind-specific parts of the signal frame */
89struct vg_sigframe
90{
91   /* Sanity check word. */
92   UInt magicPI;
93
94   UInt handlerflags;	/* flags for signal handler */
95
96
97   /* Safely-saved version of sigNo, as described above. */
98   Int  sigNo_private;
99
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;
104
105   /* HACK ALERT */
106   VexGuestS390XState vex;
107   /* end HACK ALERT */
108
109   /* saved signal mask to be restored when handler returns */
110   vki_sigset_t	mask;
111
112   /* Sanity check word.  Is the highest-addressed word; do not
113      move!*/
114   UInt magicE;
115};
116
117#define S390_SYSCALL_SIZE 2
118
119struct sigframe
120{
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];
126
127   struct vg_sigframe vg;
128};
129
130struct rt_sigframe
131{
132   UChar callee_used_stack[__VKI_SIGNAL_FRAMESIZE];
133   UChar retcode[S390_SYSCALL_SIZE];
134   struct vki_siginfo info;
135   struct vki_ucontext uc;
136
137   struct vg_sigframe vg;
138};
139
140/*------------------------------------------------------------*/
141/*--- Creating signal frames                               ---*/
142/*------------------------------------------------------------*/
143
144/* Saves all user-controlled register into a _vki_sigregs structure */
145static void save_sigregs(ThreadState *tst, _vki_sigregs *sigregs)
146{
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;
163
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;
180
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;
198
199   sigregs->regs.psw.addr = tst->arch.vex.guest_IA;
200   /* save a sane dummy mask */
201   sigregs->regs.psw.mask = 0x0705000180000000UL;
202}
203
204static void restore_sigregs(ThreadState *tst, _vki_sigregs *sigregs)
205{
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];
222
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];
239
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;
257
258   tst->arch.vex.guest_IA = sigregs->regs.psw.addr;
259}
260
261
262/* Build the Valgrind-specific part of a signal frame. */
263
264static void build_vg_sigframe(struct vg_sigframe *frame,
265			      ThreadState *tst,
266			      UInt flags,
267			      Int sigNo)
268{
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;
273   /* HACK ALERT */
274   frame->vex           = tst->arch.vex;
275   /* end HACK ALERT */
276   frame->mask          = tst->sig_mask;
277   frame->handlerflags  = flags;
278   frame->magicE        = 0x27182818;
279}
280
281
282static Addr build_sigframe(ThreadState *tst,
283			   Addr sp_top_of_frame,
284			   const vki_siginfo_t *siginfo,
285			   const struct vki_ucontext *siguc,
286			   UInt flags,
287			   const vki_sigset_t *mask,
288			   void *restorer)
289{
290   struct sigframe *frame;
291   Addr sp = sp_top_of_frame;
292
293   vg_assert((flags & VKI_SA_SIGINFO) == 0);
294   vg_assert((sizeof(*frame) & 7) == 0);
295   vg_assert((sp & 7) == 0);
296
297   sp -= sizeof(*frame);
298   frame = (struct sigframe *)sp;
299
300   if (! ML_(sf_maybe_extend_stack)(tst, sp, sizeof(*frame), flags))
301      return sp_top_of_frame;
302
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) );
306
307   save_sigregs(tst, &frame->sregs);
308
309   frame->sigNo = siginfo->si_signo;
310   frame->sc.sregs = &frame->sregs;
311   VG_(memcpy)(frame->sc.oldmask, mask->sig, sizeof(frame->sc.oldmask));
312
313   if (flags & VKI_SA_RESTORER) {
314      SET_SIGNAL_GPR(tst, 14, restorer);
315   } else {
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));
324   }
325
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*/
329
330   /* Set up backchain. */
331   *((Addr *) sp) = sp_top_of_frame;
332
333   VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
334             sp, offsetof(struct sigframe, vg) );
335
336   build_vg_sigframe(&frame->vg, tst, flags, siginfo->si_signo);
337
338   return sp;
339}
340
341static Addr build_rt_sigframe(ThreadState *tst,
342			      Addr sp_top_of_frame,
343			      const vki_siginfo_t *siginfo,
344			      const struct vki_ucontext *siguc,
345			      UInt flags,
346			      const vki_sigset_t *mask,
347			      void *restorer)
348{
349   struct rt_sigframe *frame;
350   Addr sp = sp_top_of_frame;
351   Int sigNo = siginfo->si_signo;
352
353   vg_assert((flags & VKI_SA_SIGINFO) != 0);
354   vg_assert((sizeof(*frame) & 7) == 0);
355   vg_assert((sp & 7) == 0);
356
357   sp -= sizeof(*frame);
358   frame = (struct rt_sigframe *)sp;
359
360   if (! ML_(sf_maybe_extend_stack)(tst, sp, sizeof(*frame), flags))
361      return sp_top_of_frame;
362
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) );
366
367   save_sigregs(tst, &frame->uc.uc_mcontext);
368
369   if (flags & VKI_SA_RESTORER) {
370      frame->retcode[0] = 0;
371      frame->retcode[1] = 0;
372      SET_SIGNAL_GPR(tst, 14, restorer);
373   } else {
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));
382   }
383
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;
389
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);
393
394   /* Set up backchain. */
395   *((Addr *) sp) = sp_top_of_frame;
396
397   VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
398             sp, offsetof(struct rt_sigframe, vg) );
399
400   build_vg_sigframe(&frame->vg, tst, flags, sigNo);
401   return sp;
402}
403
404/* EXPORTED */
405void VG_(sigframe_create)( ThreadId tid,
406			   Bool on_altstack,
407			   Addr sp_top_of_frame,
408			   const vki_siginfo_t *siginfo,
409			   const struct vki_ucontext *siguc,
410			   void *handler,
411			   UInt flags,
412			   const vki_sigset_t *mask,
413			   void *restorer )
414{
415   Addr sp;
416   ThreadState* tst = VG_(get_ThreadState)(tid);
417
418   if (flags & VKI_SA_SIGINFO)
419      sp = build_rt_sigframe(tst, sp_top_of_frame, siginfo, siguc,
420			     flags, mask, restorer);
421   else
422      sp = build_sigframe(tst, sp_top_of_frame, siginfo, siguc,
423			  flags, mask, restorer);
424
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));
428
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
436      caller to do. */
437}
438
439
440/*------------------------------------------------------------*/
441/*--- Destroying signal frames                             ---*/
442/*------------------------------------------------------------*/
443
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. */
446static
447Bool restore_vg_sigframe ( ThreadState *tst,
448                           struct vg_sigframe *frame, Int *sigNo )
449{
450   if (frame->magicPI != 0x31415927 ||
451       frame->magicE  != 0x27182818) {
452      VG_(message)(Vg_UserMsg, "Thread %u return signal frame "
453			       "corrupted.  Killing process.\n",
454		   tst->tid);
455      VG_(set_default_handler)(VKI_SIGSEGV);
456      VG_(synth_fault)(tst->tid);
457      *sigNo = VKI_SIGSEGV;
458      return False;
459   }
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;
464   /* HACK ALERT */
465   tst->arch.vex         = frame->vex;
466   /* end HACK ALERT */
467   *sigNo                = frame->sigNo_private;
468   return True;
469}
470
471static
472SizeT restore_sigframe ( ThreadState *tst,
473                         struct sigframe *frame, Int *sigNo )
474{
475   if (restore_vg_sigframe(tst, &frame->vg, sigNo))
476      restore_sigregs(tst, frame->sc.sregs);
477
478   return sizeof(*frame);
479}
480
481static
482SizeT restore_rt_sigframe ( ThreadState *tst,
483                            struct rt_sigframe *frame, Int *sigNo )
484{
485   if (restore_vg_sigframe(tst, &frame->vg, sigNo)) {
486      restore_sigregs(tst, &frame->uc.uc_mcontext);
487   }
488   return sizeof(*frame);
489}
490
491
492/* EXPORTED */
493void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
494{
495   Addr          sp;
496   ThreadState*  tst;
497   SizeT         size;
498   Int           sigNo;
499
500   tst = VG_(get_ThreadState)(tid);
501
502   /* Correctly reestablish the frame base address. */
503   sp   = tst->arch.vex.guest_SP;
504
505   if (!isRT)
506      size = restore_sigframe(tst, (struct sigframe *)sp, &sigNo);
507   else
508      size = restore_rt_sigframe(tst, (struct rt_sigframe *)sp, &sigNo);
509
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 );
514
515   if (VG_(clo_trace_signals))
516      VG_(message)(
517         Vg_DebugMsg,
518         "VG_(sigframe_destroy) (thread %u): isRT=%d valid magic; IP=%#llx\n",
519         tid, isRT, tst->arch.vex.guest_IA);
520
521   /* tell the tools */
522   VG_TRACK( post_deliver_signal, tid, sigNo );
523}
524
525#endif /* VGA_s390x */
526
527/*--------------------------------------------------------------------*/
528/*--- end                                   sigframe-s390x-linux.c ---*/
529/*--------------------------------------------------------------------*/
530