1
2 /*--------------------------------------------------------------------*/
3 /*--- Create/destroy signal delivery frames. ---*/
4 /*--- sigframe-tilegx-linux.c ---*/
5 /*--------------------------------------------------------------------*/
6
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
11 Copyright (C) 2010-2015 Tilera Corp.
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 Zhi-Gang Liu <zliu at tilera dot com> */
32
33 #if defined(VGP_tilegx_linux)
34
35 #include "pub_core_basics.h"
36 #include "pub_core_vki.h"
37 #include "pub_core_vkiscnums.h"
38 #include "pub_core_threadstate.h"
39 #include "pub_core_aspacemgr.h"
40 #include "pub_core_libcbase.h"
41 #include "pub_core_libcassert.h"
42 #include "pub_core_libcprint.h"
43 #include "pub_core_machine.h"
44 #include "pub_core_options.h"
45 #include "pub_core_sigframe.h"
46 #include "pub_core_signals.h"
47 #include "pub_core_tooliface.h"
48 #include "pub_core_trampoline.h"
49 #include "priv_sigframe.h"
50
51 struct vg_sig_private
52 {
53 UInt magicPI;
54 UInt sigNo_private;
55 VexGuestTILEGXState vex_shadow1;
56 VexGuestTILEGXState vex_shadow2;
57 };
58
59 #ifndef C_ABI_SAVE_AREA_SIZE
60 #define C_ABI_SAVE_AREA_SIZE 16
61 #endif
62 struct rt_sigframe {
63 unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; /* caller save area */
64 vki_siginfo_t rs_info;
65 struct vki_ucontext rs_uc;
66 struct vg_sig_private priv;
67 };
68
69
70 static
setup_sigcontext2(ThreadState * tst,struct vki_sigcontext ** sc1,const vki_siginfo_t * si)71 void setup_sigcontext2 ( ThreadState* tst, struct vki_sigcontext **sc1,
72 const vki_siginfo_t *si )
73 {
74
75 struct vki_sigcontext *sc = *sc1;
76
77 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcontext",
78 (Addr)sc, sizeof(unsigned long long)*34 );
79 sc->gregs[0] = tst->arch.vex.guest_r0;
80 sc->gregs[1] = tst->arch.vex.guest_r1;
81 sc->gregs[2] = tst->arch.vex.guest_r2;
82 sc->gregs[3] = tst->arch.vex.guest_r3;
83 sc->gregs[4] = tst->arch.vex.guest_r4;
84 sc->gregs[5] = tst->arch.vex.guest_r5;
85 sc->gregs[6] = tst->arch.vex.guest_r6;
86 sc->gregs[7] = tst->arch.vex.guest_r7;
87 sc->gregs[8] = tst->arch.vex.guest_r8;
88 sc->gregs[9] = tst->arch.vex.guest_r9;
89 sc->gregs[10] = tst->arch.vex.guest_r10;
90 sc->gregs[11] = tst->arch.vex.guest_r11;
91 sc->gregs[12] = tst->arch.vex.guest_r12;
92 sc->gregs[13] = tst->arch.vex.guest_r13;
93 sc->gregs[14] = tst->arch.vex.guest_r14;
94 sc->gregs[15] = tst->arch.vex.guest_r15;
95 sc->gregs[16] = tst->arch.vex.guest_r16;
96 sc->gregs[17] = tst->arch.vex.guest_r17;
97 sc->gregs[18] = tst->arch.vex.guest_r18;
98 sc->gregs[19] = tst->arch.vex.guest_r19;
99 sc->gregs[20] = tst->arch.vex.guest_r20;
100 sc->gregs[21] = tst->arch.vex.guest_r21;
101 sc->gregs[22] = tst->arch.vex.guest_r22;
102 sc->gregs[23] = tst->arch.vex.guest_r23;
103 sc->gregs[24] = tst->arch.vex.guest_r24;
104 sc->gregs[25] = tst->arch.vex.guest_r25;
105 sc->gregs[26] = tst->arch.vex.guest_r26;
106 sc->gregs[27] = tst->arch.vex.guest_r27;
107 sc->gregs[28] = tst->arch.vex.guest_r28;
108 sc->gregs[29] = tst->arch.vex.guest_r29;
109 sc->gregs[30] = tst->arch.vex.guest_r30;
110 sc->gregs[31] = tst->arch.vex.guest_r31;
111 sc->gregs[32] = tst->arch.vex.guest_r32;
112 sc->gregs[33] = tst->arch.vex.guest_r33;
113 sc->gregs[34] = tst->arch.vex.guest_r34;
114 sc->gregs[35] = tst->arch.vex.guest_r35;
115 sc->gregs[36] = tst->arch.vex.guest_r36;
116 sc->gregs[37] = tst->arch.vex.guest_r37;
117 sc->gregs[38] = tst->arch.vex.guest_r38;
118 sc->gregs[39] = tst->arch.vex.guest_r39;
119 sc->gregs[40] = tst->arch.vex.guest_r40;
120 sc->gregs[41] = tst->arch.vex.guest_r41;
121 sc->gregs[42] = tst->arch.vex.guest_r42;
122 sc->gregs[43] = tst->arch.vex.guest_r43;
123 sc->gregs[44] = tst->arch.vex.guest_r44;
124 sc->gregs[45] = tst->arch.vex.guest_r45;
125 sc->gregs[46] = tst->arch.vex.guest_r46;
126 sc->gregs[47] = tst->arch.vex.guest_r47;
127 sc->gregs[48] = tst->arch.vex.guest_r48;
128 sc->gregs[49] = tst->arch.vex.guest_r49;
129 sc->gregs[50] = tst->arch.vex.guest_r50;
130 sc->gregs[51] = tst->arch.vex.guest_r51;
131 sc->gregs[52] = tst->arch.vex.guest_r52;
132 sc->tp = tst->arch.vex.guest_r53;
133 sc->sp = tst->arch.vex.guest_r54;
134 sc->lr = tst->arch.vex.guest_r55;
135 sc->pc = tst->arch.vex.guest_pc;
136 }
137
138 /* EXPORTED */
VG_(sigframe_create)139 void VG_(sigframe_create)( ThreadId tid,
140 Addr sp_top_of_frame,
141 const vki_siginfo_t *siginfo,
142 const struct vki_ucontext *siguc,
143 void *handler,
144 UInt flags,
145 const vki_sigset_t *mask,
146 void *restorer )
147 {
148 Addr sp;
149 ThreadState* tst;
150 Addr faultaddr;
151 Int sigNo = siginfo->si_signo;
152 struct vg_sig_private *priv;
153
154 /* Stack must be 8-byte aligned */
155 sp_top_of_frame &= ~0x7ULL;
156
157 sp = sp_top_of_frame - sizeof(struct rt_sigframe);
158
159 tst = VG_(get_ThreadState)(tid);
160 if (! ML_(sf_maybe_extend_stack)(tst, sp, sizeof(struct rt_sigframe), flags))
161 return;
162
163 vg_assert(VG_IS_8_ALIGNED(sp));
164
165 /* SIGILL defines addr to be the faulting address */
166
167 faultaddr = (Addr)siginfo->_sifields._sigfault._addr;
168 if (sigNo == VKI_SIGILL && siginfo->si_code > 0)
169 faultaddr = tst->arch.vex.guest_pc;
170
171
172 struct rt_sigframe *frame = (struct rt_sigframe *) sp;
173 struct vki_ucontext *ucp = &frame->rs_uc;
174 if (VG_(clo_trace_signals))
175 VG_(printf)("rt_sigframe\n");
176 /* Create siginfo. */
177 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame siginfo",
178 (Addr)&frame->rs_info, sizeof(frame->rs_info) );
179
180 VG_(memcpy)(&frame->rs_info, siginfo, sizeof(*siginfo));
181
182 VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
183 (Addr)&frame->rs_info, sizeof(frame->rs_info) );
184
185 /* Create the ucontext. */
186 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext",
187 (Addr)ucp, offsetof(struct vki_ucontext, uc_mcontext) );
188
189 ucp->uc_flags = 0;
190 ucp->uc_link = 0;
191 ucp->uc_stack = tst->altstack;
192
193 VG_TRACK( post_mem_write, Vg_CoreSignal, tid, (Addr)ucp,
194 offsetof(struct vki_ucontext, uc_mcontext) );
195
196 struct vki_sigcontext *scp = &(frame->rs_uc.uc_mcontext);
197 setup_sigcontext2(tst, &(scp), siginfo);
198
199 ucp->uc_sigmask = tst->sig_mask;
200
201 priv = &frame->priv;
202
203 /*
204 * Arguments to signal handler:
205 *
206 * r0 = signal number
207 * r1 = 0 (should be cause)
208 * r2 = pointer to ucontext
209 *
210 * r54 points to the struct rt_sigframe.
211 */
212
213 tst->arch.vex.guest_r0 = siginfo->si_signo;
214 tst->arch.vex.guest_r1 = (Addr) &frame->rs_info;
215 tst->arch.vex.guest_r2 = (Addr) &frame->rs_uc;
216 tst->arch.vex.guest_r54 = (Addr) frame;
217
218 if (flags & VKI_SA_RESTORER)
219 {
220 tst->arch.vex.guest_r55 = (Addr) restorer;
221 }
222 else
223 {
224 tst->arch.vex.guest_r55 = (Addr)&VG_(tilegx_linux_SUBST_FOR_rt_sigreturn);
225 }
226
227 priv->magicPI = 0x31415927;
228 priv->sigNo_private = sigNo;
229 priv->vex_shadow1 = tst->arch.vex_shadow1;
230 priv->vex_shadow2 = tst->arch.vex_shadow2;
231 /* Set the thread so it will next run the handler. */
232 /* tst->m_sp = sp; also notify the tool we've updated SP */
233 VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr));
234 if (VG_(clo_trace_signals))
235 VG_(printf)("handler = %p\n", handler);
236 tst->arch.vex.guest_pc = (Addr) handler;
237 /* This thread needs to be marked runnable, but we leave that the
238 caller to do. */
239 if (0)
240 VG_(printf)("pushed signal frame; sp now = %lx, "
241 "next %pc = %lx, status=%d\n",
242 (Addr)frame, tst->arch.vex.guest_pc, (Int)tst->status);
243 }
244
245 /* EXPORTED */
VG_(sigframe_destroy)246 void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
247 {
248 ThreadState *tst;
249 struct vg_sig_private *priv1;
250 Addr sp;
251 UInt frame_size;
252 struct vki_sigcontext *mc;
253 Int sigNo;
254 Bool has_siginfo = isRT;
255
256 vg_assert(VG_(is_valid_tid)(tid));
257 tst = VG_(get_ThreadState)(tid);
258 sp = tst->arch.vex.guest_r54 + 8;
259 if (has_siginfo)
260 {
261 struct rt_sigframe *frame = (struct rt_sigframe *)sp;
262 struct vki_ucontext *ucp = &frame->rs_uc;
263
264 if (0)
265 VG_(printf)("destroy signal frame; sp = %lx, "
266 " %pc = %lx, status=%d\n",
267 (Addr)frame, tst->arch.vex.guest_pc, (Int)tst->status);
268
269 frame_size = sizeof(*frame);
270 mc = &ucp->uc_mcontext;
271 priv1 = &frame->priv;
272 vg_assert(priv1->magicPI == 0x31415927);
273 sigNo = priv1->sigNo_private;
274 }
275 else
276 {
277 vg_assert(0);
278 }
279
280 //restore regs
281 tst->arch.vex.guest_r0 = mc->gregs[0];
282 tst->arch.vex.guest_r1 = mc->gregs[1];
283 tst->arch.vex.guest_r2 = mc->gregs[2];
284 tst->arch.vex.guest_r3 = mc->gregs[3];
285 tst->arch.vex.guest_r4 = mc->gregs[4];
286 tst->arch.vex.guest_r5 = mc->gregs[5];
287 tst->arch.vex.guest_r6 = mc->gregs[6];
288 tst->arch.vex.guest_r7 = mc->gregs[7];
289 tst->arch.vex.guest_r8 = mc->gregs[8];
290 tst->arch.vex.guest_r9 = mc->gregs[9];
291 tst->arch.vex.guest_r10 = mc->gregs[10];
292 tst->arch.vex.guest_r11 = mc->gregs[11];
293 tst->arch.vex.guest_r12 = mc->gregs[12];
294 tst->arch.vex.guest_r13 = mc->gregs[13];
295 tst->arch.vex.guest_r14 = mc->gregs[14];
296 tst->arch.vex.guest_r15 = mc->gregs[15];
297 tst->arch.vex.guest_r16 = mc->gregs[16];
298 tst->arch.vex.guest_r17 = mc->gregs[17];
299 tst->arch.vex.guest_r18 = mc->gregs[18];
300 tst->arch.vex.guest_r19 = mc->gregs[19];
301 tst->arch.vex.guest_r20 = mc->gregs[20];
302 tst->arch.vex.guest_r21 = mc->gregs[21];
303 tst->arch.vex.guest_r22 = mc->gregs[22];
304 tst->arch.vex.guest_r23 = mc->gregs[23];
305 tst->arch.vex.guest_r24 = mc->gregs[24];
306 tst->arch.vex.guest_r25 = mc->gregs[25];
307 tst->arch.vex.guest_r26 = mc->gregs[26];
308 tst->arch.vex.guest_r27 = mc->gregs[27];
309 tst->arch.vex.guest_r28 = mc->gregs[28];
310 tst->arch.vex.guest_r29 = mc->gregs[29];
311 tst->arch.vex.guest_r30 = mc->gregs[30];
312 tst->arch.vex.guest_r31 = mc->gregs[31];
313 tst->arch.vex.guest_r32 = mc->gregs[32];
314 tst->arch.vex.guest_r33 = mc->gregs[33];
315 tst->arch.vex.guest_r34 = mc->gregs[34];
316 tst->arch.vex.guest_r35 = mc->gregs[35];
317 tst->arch.vex.guest_r36 = mc->gregs[36];
318 tst->arch.vex.guest_r37 = mc->gregs[37];
319 tst->arch.vex.guest_r38 = mc->gregs[38];
320 tst->arch.vex.guest_r39 = mc->gregs[39];
321 tst->arch.vex.guest_r40 = mc->gregs[40];
322 tst->arch.vex.guest_r41 = mc->gregs[41];
323 tst->arch.vex.guest_r42 = mc->gregs[42];
324 tst->arch.vex.guest_r43 = mc->gregs[43];
325 tst->arch.vex.guest_r44 = mc->gregs[44];
326 tst->arch.vex.guest_r45 = mc->gregs[45];
327 tst->arch.vex.guest_r46 = mc->gregs[46];
328 tst->arch.vex.guest_r47 = mc->gregs[47];
329 tst->arch.vex.guest_r48 = mc->gregs[48];
330 tst->arch.vex.guest_r49 = mc->gregs[49];
331 tst->arch.vex.guest_r50 = mc->gregs[50];
332 tst->arch.vex.guest_r51 = mc->gregs[51];
333 tst->arch.vex.guest_r52 = mc->gregs[52];
334 tst->arch.vex.guest_r53 = mc->tp;
335 tst->arch.vex.guest_r54 = mc->sp;
336 tst->arch.vex.guest_r55 = mc->lr;
337 tst->arch.vex.guest_pc = mc->pc;
338
339 VG_TRACK(die_mem_stack_signal, sp, frame_size);
340 if (VG_(clo_trace_signals))
341 VG_(message)( Vg_DebugMsg,
342 "VG_(signal_return) (thread %u): isRT=%d valid magic; EIP=%#x\n",
343 tid, isRT, tst->arch.vex.guest_pc);
344 /* tell the tools */
345 VG_TRACK( post_deliver_signal, tid, sigNo );
346 }
347
348 #endif // defined(VGP_tilegx_linux)
349
350 /*--------------------------------------------------------------------*/
351 /*--- end sigframe-tilegx-linux.c ---*/
352 /*--------------------------------------------------------------------*/
353