1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--------------------------------------------------------------------*/
3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- Create/destroy signal delivery frames.                       ---*/
4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*---                                       sigframe-s390x-linux.c ---*/
5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--------------------------------------------------------------------*/
6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*
8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   This file is part of Valgrind, a dynamic binary instrumentation
9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   framework.
10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Copyright IBM Corp. 2010-2011
12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   This program is free software; you can redistribute it and/or
14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   modify it under the terms of the GNU General Public License as
15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   published by the Free Software Foundation; either version 2 of the
16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   License, or (at your option) any later version.
17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   This program is distributed in the hope that it will be useful, but
19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   WITHOUT ANY WARRANTY; without even the implied warranty of
20b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   General Public License for more details.
22b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
23b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   You should have received a copy of the GNU General Public License
24b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   along with this program; if not, write to the Free Software
25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   02111-1307, USA.
27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   The GNU General Public License is contained in the file COPYING.
29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
30b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Contributed by Christian Borntraeger */
32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_basics.h"
34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_vki.h"
35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_vkiscnums.h"
36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_libcsetjmp.h"    // to keep _threadstate.h happy
37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_threadstate.h"
38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_aspacemgr.h"
39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_libcbase.h"
40b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_libcassert.h"
41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_libcprint.h"
42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_machine.h"
43b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_options.h"
44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_sigframe.h"
45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_signals.h"
46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_tooliface.h"
47b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_trampoline.h"
48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGA_s390x)
50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* This module creates and removes signal frames for signal deliveries
52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   on s390x-linux.
53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Note, this file contains kernel-specific knowledge in the form of
55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   'struct sigframe' and 'struct rt_sigframe'.
56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Either a 'struct sigframe' or a 'struct rtsigframe' is pushed
58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   onto the client's stack.  This contains a subsidiary
59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vki_ucontext.  That holds the vcpu's state across the signal,
60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   so that the sighandler can mess with the vcpu state if it
61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   really wants.
62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define SET_SIGNAL_GPR(zztst, zzn, zzval)                    \
65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   do { zztst->arch.vex.guest_r##zzn = (unsigned long)(zzval);              \
66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_TRACK( post_reg_write, Vg_CoreSignal, zztst->tid,     \
67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                offsetof(VexGuestS390XState,guest_r##zzn), \
68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                sizeof(UWord) );                             \
69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } while (0)
70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*------------------------------------------------------------*/
72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- Signal frame layouts                                 ---*/
73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*------------------------------------------------------------*/
74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// A structure in which to save the application's registers
76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// during the execution of signal handlers.
77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// Linux has 2 signal frame structures: one for normal signal
79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// deliveries, and one for SA_SIGINFO deliveries (also known as RT
80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// signals).
81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov//
82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// In theory, so long as we get the arguments to the handler function
83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// right, it doesn't matter what the exact layout of the rest of the
84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// frame is.  Unfortunately, things like gcc's exception unwinding
85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// make assumptions about the locations of various parts of the frame,
86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov// so we need to duplicate it exactly.
87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Valgrind-specific parts of the signal frame */
89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstruct vg_sigframe
90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Sanity check word. */
92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UInt magicPI;
93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UInt handlerflags;	/* flags for signal handler */
95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Safely-saved version of sigNo, as described above. */
98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Int  sigNo_private;
99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* XXX This is wrong.  Surely we should store the shadow values
101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      into the shadow memory behind the actual values? */
102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VexGuestS390XState vex_shadow1;
103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VexGuestS390XState vex_shadow2;
104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* HACK ALERT */
106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VexGuestS390XState vex;
107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* end HACK ALERT */
108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* saved signal mask to be restored when handler returns */
110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vki_sigset_t	mask;
111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Sanity check word.  Is the highest-addressed word; do not
113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      move!*/
114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UInt magicE;
115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov};
116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define S390_SYSCALL_SIZE 2
118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstruct sigframe
120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UChar callee_used_stack[__VKI_SIGNAL_FRAMESIZE];
122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   struct vki_sigcontext sc;
123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   _vki_sigregs sregs;
124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Int sigNo;
125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UChar retcode[S390_SYSCALL_SIZE];
126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   struct vg_sigframe vg;
128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov};
129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstruct rt_sigframe
131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UChar callee_used_stack[__VKI_SIGNAL_FRAMESIZE];
133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   UChar retcode[S390_SYSCALL_SIZE];
134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   struct vki_siginfo info;
135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   struct vki_ucontext uc;
136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   struct vg_sigframe vg;
138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov};
139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*------------------------------------------------------------*/
141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- Creating signal frames                               ---*/
142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*------------------------------------------------------------*/
143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Saves all user-controlled register into a _vki_sigregs structure */
145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void save_sigregs(ThreadState *tst, _vki_sigregs *sigregs)
146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.gprs[0]  = tst->arch.vex.guest_r0;
148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.gprs[1]  = tst->arch.vex.guest_r1;
149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.gprs[2]  = tst->arch.vex.guest_r2;
150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.gprs[3]  = tst->arch.vex.guest_r3;
151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.gprs[4]  = tst->arch.vex.guest_r4;
152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.gprs[5]  = tst->arch.vex.guest_r5;
153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.gprs[6]  = tst->arch.vex.guest_r6;
154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.gprs[7]  = tst->arch.vex.guest_r7;
155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.gprs[8]  = tst->arch.vex.guest_r8;
156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.gprs[9]  = tst->arch.vex.guest_r9;
157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.gprs[10] = tst->arch.vex.guest_r10;
158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.gprs[11] = tst->arch.vex.guest_r11;
159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.gprs[12] = tst->arch.vex.guest_r12;
160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.gprs[13] = tst->arch.vex.guest_r13;
161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.gprs[14] = tst->arch.vex.guest_r14;
162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.gprs[15] = tst->arch.vex.guest_r15;
163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.acrs[0]  = tst->arch.vex.guest_a0;
165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.acrs[1]  = tst->arch.vex.guest_a1;
166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.acrs[2]  = tst->arch.vex.guest_a2;
167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.acrs[3]  = tst->arch.vex.guest_a3;
168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.acrs[4]  = tst->arch.vex.guest_a4;
169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.acrs[5]  = tst->arch.vex.guest_a5;
170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.acrs[6]  = tst->arch.vex.guest_a6;
171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.acrs[7]  = tst->arch.vex.guest_a7;
172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.acrs[8]  = tst->arch.vex.guest_a8;
173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.acrs[9]  = tst->arch.vex.guest_a9;
174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.acrs[10] = tst->arch.vex.guest_a10;
175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.acrs[11] = tst->arch.vex.guest_a11;
176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.acrs[12] = tst->arch.vex.guest_a12;
177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.acrs[13] = tst->arch.vex.guest_a13;
178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.acrs[14] = tst->arch.vex.guest_a14;
179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.acrs[15] = tst->arch.vex.guest_a15;
180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->fpregs.fprs[0] = tst->arch.vex.guest_f0;
182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->fpregs.fprs[1] = tst->arch.vex.guest_f1;
183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->fpregs.fprs[2] = tst->arch.vex.guest_f2;
184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->fpregs.fprs[3] = tst->arch.vex.guest_f3;
185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->fpregs.fprs[4] = tst->arch.vex.guest_f4;
186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->fpregs.fprs[5] = tst->arch.vex.guest_f5;
187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->fpregs.fprs[6] = tst->arch.vex.guest_f6;
188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->fpregs.fprs[7] = tst->arch.vex.guest_f7;
189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->fpregs.fprs[8] = tst->arch.vex.guest_f8;
190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->fpregs.fprs[9] = tst->arch.vex.guest_f9;
191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->fpregs.fprs[10] = tst->arch.vex.guest_f10;
192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->fpregs.fprs[11] = tst->arch.vex.guest_f11;
193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->fpregs.fprs[12] = tst->arch.vex.guest_f12;
194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->fpregs.fprs[13] = tst->arch.vex.guest_f13;
195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->fpregs.fprs[14] = tst->arch.vex.guest_f14;
196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->fpregs.fprs[15] = tst->arch.vex.guest_f15;
197b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->fpregs.fpc      = tst->arch.vex.guest_fpc;
198b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.psw.addr = tst->arch.vex.guest_IA;
200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* save a sane dummy mask */
201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sigregs->regs.psw.mask = 0x0705000180000000UL;
202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void restore_sigregs(ThreadState *tst, _vki_sigregs *sigregs)
205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_r0  = sigregs->regs.gprs[0];
207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_r1  = sigregs->regs.gprs[1];
208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_r2  = sigregs->regs.gprs[2];
209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_r3  = sigregs->regs.gprs[3];
210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_r4  = sigregs->regs.gprs[4];
211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_r5  = sigregs->regs.gprs[5];
212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_r6  = sigregs->regs.gprs[6];
213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_r7  = sigregs->regs.gprs[7];
214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_r8  = sigregs->regs.gprs[8];
215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_r9  = sigregs->regs.gprs[9];
216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_r10 = sigregs->regs.gprs[10];
217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_r11 = sigregs->regs.gprs[11];
218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_r12 = sigregs->regs.gprs[12];
219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_r13 = sigregs->regs.gprs[13];
220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_r14 = sigregs->regs.gprs[14];
221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_r15 = sigregs->regs.gprs[15];
222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_a0  = sigregs->regs.acrs[0];
224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_a1  = sigregs->regs.acrs[1];
225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_a2  = sigregs->regs.acrs[2];
226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_a3  = sigregs->regs.acrs[3];
227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_a4  = sigregs->regs.acrs[4];
228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_a5  = sigregs->regs.acrs[5];
229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_a6  = sigregs->regs.acrs[6];
230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_a7  = sigregs->regs.acrs[7];
231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_a8  = sigregs->regs.acrs[8];
232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_a9  = sigregs->regs.acrs[9];
233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_a10 = sigregs->regs.acrs[10];
234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_a11 = sigregs->regs.acrs[11];
235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_a12 = sigregs->regs.acrs[12];
236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_a13 = sigregs->regs.acrs[13];
237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_a14 = sigregs->regs.acrs[14];
238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_a15 = sigregs->regs.acrs[15];
239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_f0  = sigregs->fpregs.fprs[0];
241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_f1  = sigregs->fpregs.fprs[1];
242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_f2  = sigregs->fpregs.fprs[2];
243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_f3  = sigregs->fpregs.fprs[3];
244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_f4  = sigregs->fpregs.fprs[4];
245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_f5  = sigregs->fpregs.fprs[5];
246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_f6  = sigregs->fpregs.fprs[6];
247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_f7  = sigregs->fpregs.fprs[7];
248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_f8  = sigregs->fpregs.fprs[8];
249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_f9  = sigregs->fpregs.fprs[9];
250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_f10 = sigregs->fpregs.fprs[10];
251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_f11 = sigregs->fpregs.fprs[11];
252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_f12 = sigregs->fpregs.fprs[12];
253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_f13 = sigregs->fpregs.fprs[13];
254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_f14 = sigregs->fpregs.fprs[14];
255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_f15 = sigregs->fpregs.fprs[15];
256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_fpc = sigregs->fpregs.fpc;
257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_IA = sigregs->regs.psw.addr;
259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Extend the stack segment downwards if needed so as to ensure the
262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   new signal frames are mapped to something.  Return a Bool
263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   indicating whether or not the operation was successful.
264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov*/
265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Bool extend ( ThreadState *tst, Addr addr, SizeT size )
266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ThreadId        tid = tst->tid;
268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   NSegment const* stackseg = NULL;
269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (VG_(extend_stack)(addr, tst->client_stack_szB)) {
271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      stackseg = VG_(am_find_nsegment)(addr);
272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (0 && stackseg)
273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	 VG_(printf)("frame=%#lx seg=%#lx-%#lx\n",
274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov		     addr, stackseg->start, stackseg->end);
275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) {
278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(message)(
279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         Vg_UserMsg,
280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "Can't extend stack to %#lx during signal delivery for thread %d:\n",
281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         addr, tid);
282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (stackseg == NULL)
283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(message)(Vg_UserMsg, "  no stack segment\n");
284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      else
285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         VG_(message)(Vg_UserMsg, "  too small or bad protection modes\n");
286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* set SIGSEGV to default handler */
288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(set_default_handler)(VKI_SIGSEGV);
289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(synth_fault_mapping)(tid, addr);
290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* The whole process should be about to die, since the default
292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	 action of SIGSEGV to kill the whole process. */
293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return False;
294b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* For tracking memory events, indicate the entire frame has been
297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      allocated. */
298b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB,
299b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov             size + VG_STACK_REDZONE_SZB, tid );
300b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
301b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return True;
302b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
303b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
304b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
305b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Build the Valgrind-specific part of a signal frame. */
306b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
307b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void build_vg_sigframe(struct vg_sigframe *frame,
308b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			      ThreadState *tst,
309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			      UInt flags,
310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			      Int sigNo)
311b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   frame->sigNo_private = sigNo;
313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   frame->magicPI       = 0x31415927;
314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   frame->vex_shadow1   = tst->arch.vex_shadow1;
315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   frame->vex_shadow2   = tst->arch.vex_shadow2;
316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* HACK ALERT */
317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   frame->vex           = tst->arch.vex;
318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* end HACK ALERT */
319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   frame->mask          = tst->sig_mask;
320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   frame->handlerflags  = flags;
321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   frame->magicE        = 0x27182818;
322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Addr build_sigframe(ThreadState *tst,
326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			   Addr sp_top_of_frame,
327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			   const vki_siginfo_t *siginfo,
328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			   const struct vki_ucontext *siguc,
329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			   UInt flags,
330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			   const vki_sigset_t *mask,
331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			   void *restorer)
332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
333b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   struct sigframe *frame;
334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Addr sp = sp_top_of_frame;
335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vg_assert((flags & VKI_SA_SIGINFO) == 0);
337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vg_assert((sizeof(*frame) & 7) == 0);
338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vg_assert((sp & 7) == 0);
339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sp -= sizeof(*frame);
341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   frame = (struct sigframe *)sp;
342b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
343b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (!extend(tst, sp, sizeof(*frame)))
344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return sp_top_of_frame;
345b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
346b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* retcode, sigNo, sc, sregs fields are to be written */
347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame",
348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	     sp, offsetof(struct sigframe, vg) );
349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   save_sigregs(tst, &frame->sregs);
351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   frame->sigNo = siginfo->si_signo;
353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   frame->sc.sregs = &frame->sregs;
354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_(memcpy)(frame->sc.oldmask, mask->sig, sizeof(frame->sc.oldmask));
355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (flags & VKI_SA_RESTORER) {
357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      SET_SIGNAL_GPR(tst, 14, restorer);
358b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } else {
359b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      frame->retcode[0] = 0x0a;
360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      frame->retcode[1] = __NR_sigreturn;
361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* This normally should be &frame->recode. but since there
362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         might be problems with non-exec stack and we must discard
363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         the translation for the on-stack sigreturn we just use the
364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         trampoline like x86,ppc. We still fill in the retcode, lets
365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         just hope that nobody actually jumps here */
366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      SET_SIGNAL_GPR(tst, 14, (Addr)&VG_(s390x_linux_SUBST_FOR_sigreturn));
367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   SET_SIGNAL_GPR(tst, 2, siginfo->si_signo);
370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   SET_SIGNAL_GPR(tst, 3, &frame->sc);
371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* fixs390: we dont fill in trapno and prot_addr in r4 and r5*/
372b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
373b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Set up backchain. */
374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *((Addr *) sp) = sp_top_of_frame;
375b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
376b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
377b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov             sp, offsetof(struct sigframe, vg) );
378b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
379b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   build_vg_sigframe(&frame->vg, tst, flags, siginfo->si_signo);
380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
381b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sp;
382b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
383b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic Addr build_rt_sigframe(ThreadState *tst,
385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			      Addr sp_top_of_frame,
386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			      const vki_siginfo_t *siginfo,
387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			      const struct vki_ucontext *siguc,
388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			      UInt flags,
389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			      const vki_sigset_t *mask,
390b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			      void *restorer)
391b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   struct rt_sigframe *frame;
393b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Addr sp = sp_top_of_frame;
394b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Int sigNo = siginfo->si_signo;
395b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
396b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vg_assert((flags & VKI_SA_SIGINFO) != 0);
397b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vg_assert((sizeof(*frame) & 7) == 0);
398b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   vg_assert((sp & 7) == 0);
399b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
400b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sp -= sizeof(*frame);
401b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   frame = (struct rt_sigframe *)sp;
402b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
403b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (!extend(tst, sp, sizeof(*frame)))
404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return sp_top_of_frame;
405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* retcode, sigNo, sc, sregs fields are to be written */
407b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame",
408b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov	     sp, offsetof(struct rt_sigframe, vg) );
409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   save_sigregs(tst, &frame->uc.uc_mcontext);
411b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (flags & VKI_SA_RESTORER) {
413b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      frame->retcode[0] = 0;
414b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      frame->retcode[1] = 0;
415b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      SET_SIGNAL_GPR(tst, 14, restorer);
416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   } else {
417b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      frame->retcode[0] = 0x0a;
418b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      frame->retcode[1] = __NR_rt_sigreturn;
419b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* This normally should be &frame->recode. but since there
420b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         might be problems with non-exec stack and we must discard
421b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         the translation for the on-stack sigreturn we just use the
422b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         trampoline like x86,ppc. We still fill in the retcode, lets
423b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         just hope that nobody actually jumps here */
424b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      SET_SIGNAL_GPR(tst, 14, (Addr)&VG_(s390x_linux_SUBST_FOR_rt_sigreturn));
425b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
426b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
427b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_(memcpy)(&frame->info, siginfo, sizeof(vki_siginfo_t));
428b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   frame->uc.uc_flags = 0;
429b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   frame->uc.uc_link = 0;
430b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   frame->uc.uc_sigmask = *mask;
431b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   frame->uc.uc_stack = tst->altstack;
432b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
433b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   SET_SIGNAL_GPR(tst, 2, siginfo->si_signo);
434b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   SET_SIGNAL_GPR(tst, 3, &frame->info);
435b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   SET_SIGNAL_GPR(tst, 4, &frame->uc);
436b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
437b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Set up backchain. */
438b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *((Addr *) sp) = sp_top_of_frame;
439b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
440b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
441b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov             sp, offsetof(struct rt_sigframe, vg) );
442b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
443b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   build_vg_sigframe(&frame->vg, tst, flags, sigNo);
444b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sp;
445b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* EXPORTED */
448b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid VG_(sigframe_create)( ThreadId tid,
449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			   Addr sp_top_of_frame,
450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			   const vki_siginfo_t *siginfo,
451b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			   const struct vki_ucontext *siguc,
452b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			   void *handler,
453b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			   UInt flags,
454b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			   const vki_sigset_t *mask,
455b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			   void *restorer )
456b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
457b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Addr sp;
458b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ThreadState* tst = VG_(get_ThreadState)(tid);
459b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
460b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (flags & VKI_SA_SIGINFO)
461b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      sp = build_rt_sigframe(tst, sp_top_of_frame, siginfo, siguc,
462b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			     flags, mask, restorer);
463b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   else
464b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      sp = build_sigframe(tst, sp_top_of_frame, siginfo, siguc,
465b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			  flags, mask, restorer);
466b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
467b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Set the thread so it will next run the handler. */
468b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_(set_SP)(tid, sp);
469b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr));
470b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
471b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_IA = (Addr) handler;
472b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* We might have interrupted a repeating instruction that uses the guest
473b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      counter. Since our VEX requires that a new instruction will see a
474b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      guest counter == 0, we have to set it here. The old value will be
475b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      restored by restore_vg_sigframe. */
476b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex.guest_counter = 0;
477b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* This thread needs to be marked runnable, but we leave that the
478b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      caller to do. */
479b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
480b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
481b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
482b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*------------------------------------------------------------*/
483b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- Destroying signal frames                             ---*/
484b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*------------------------------------------------------------*/
485b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
486b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Return False and don't do anything, just set the client to take a
487b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   segfault, if it looks like the frame is corrupted. */
488b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
489b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovBool restore_vg_sigframe ( ThreadState *tst,
490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                           struct vg_sigframe *frame, Int *sigNo )
491b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
492b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (frame->magicPI != 0x31415927 ||
493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov       frame->magicE  != 0x27182818) {
494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(message)(Vg_UserMsg, "Thread %d return signal frame "
495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov			       "corrupted.  Killing process.\n",
496b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov		   tst->tid);
497b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(set_default_handler)(VKI_SIGSEGV);
498b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(synth_fault)(tst->tid);
499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *sigNo = VKI_SIGSEGV;
500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      return False;
501b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
502b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->sig_mask         = frame->mask;
503b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->tmp_sig_mask     = frame->mask;
504b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex_shadow1 = frame->vex_shadow1;
505b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex_shadow2 = frame->vex_shadow2;
506b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* HACK ALERT */
507b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst->arch.vex         = frame->vex;
508b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* end HACK ALERT */
509b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *sigNo                = frame->sigNo_private;
510b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return True;
511b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
512b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
514b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovSizeT restore_sigframe ( ThreadState *tst,
515b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                         struct sigframe *frame, Int *sigNo )
516b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
517b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (restore_vg_sigframe(tst, &frame->vg, sigNo))
518b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      restore_sigregs(tst, frame->sc.sregs);
519b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sizeof(*frame);
521b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
522b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
523b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic
524b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovSizeT restore_rt_sigframe ( ThreadState *tst,
525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                            struct rt_sigframe *frame, Int *sigNo )
526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (restore_vg_sigframe(tst, &frame->vg, sigNo)) {
528b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      restore_sigregs(tst, &frame->uc.uc_mcontext);
529b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
530b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sizeof(*frame);
531b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
532b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
533b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
534b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* EXPORTED */
535b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
536b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Addr          sp;
538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ThreadState*  tst;
539b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   SizeT         size;
540b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   Int            sigNo;
541b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
542b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   tst = VG_(get_ThreadState)(tid);
543b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
544b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Correctly reestablish the frame base address. */
545b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sp   = tst->arch.vex.guest_SP;
546b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
547b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (!isRT)
548b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      size = restore_sigframe(tst, (struct sigframe *)sp, &sigNo);
549b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   else
550b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      size = restore_rt_sigframe(tst, (struct rt_sigframe *)sp, &sigNo);
551b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
552b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* same as for creation: we must announce the full memory (including
553b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      alignment), otherwise massif might fail on longjmp */
554b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_TRACK( die_mem_stack_signal, sp - VG_STACK_REDZONE_SZB,
555b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov             size + VG_STACK_REDZONE_SZB );
556b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
557b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (VG_(clo_trace_signals))
558b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VG_(message)(
559b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         Vg_DebugMsg,
560b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         "VG_(sigframe_destroy) (thread %d): isRT=%d valid magic; IP=%#llx\n",
561b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         tid, isRT, tst->arch.vex.guest_IA);
562b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
563b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* tell the tools */
564b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   VG_TRACK( post_deliver_signal, tid, sigNo );
565b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
566b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
567b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif /* VGA_s390x */
568b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
569b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--------------------------------------------------------------------*/
570b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--- end                                   sigframe-s390x-linux.c ---*/
571b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/*--------------------------------------------------------------------*/
572