2 /*--------------------------------------------------------------------*/
3 /*--- Create/destroy signal delivery frames. ---*/
4 /*--- sigframe-tilegx-linux.c ---*/
5 /*--------------------------------------------------------------------*/
8 This file is part of Valgrind, a dynamic binary instrumentation
11 Copyright (C) 2010-2013 Tilera Corp.
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 The GNU General Public License is contained in the file COPYING.
31 /* Contributed by Zhi-Gang Liu <zliu at tilera dot com> */
33 #if defined(VGP_tilegx_linux)
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"
55 VexGuestTILEGXState vex_shadow1
;
56 VexGuestTILEGXState vex_shadow2
;
59 #ifndef C_ABI_SAVE_AREA_SIZE
60 #define C_ABI_SAVE_AREA_SIZE 16
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
;
71 void setup_sigcontext2 ( ThreadState
* tst
, struct vki_sigcontext
**sc1
,
72 const vki_siginfo_t
*si
)
75 struct vki_sigcontext
*sc
= *sc1
;
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
;
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
,
145 const vki_sigset_t
*mask
,
151 Int sigNo
= siginfo
->si_signo
;
152 struct vg_sig_private
*priv
;
154 /* Stack must be 8-byte aligned */
155 sp_top_of_frame
&= ~0x7ULL
;
157 sp
= sp_top_of_frame
- sizeof(struct rt_sigframe
);
159 tst
= VG_(get_ThreadState
)(tid
);
160 if (! ML_(sf_maybe_extend_stack
)(tst
, sp
, sizeof(struct rt_sigframe
), flags
))
163 vg_assert(VG_IS_8_ALIGNED(sp
));
165 /* SIGILL defines addr to be the faulting address */
167 faultaddr
= (Addr
)siginfo
->_sifields
._sigfault
._addr
;
168 if (sigNo
== VKI_SIGILL
&& siginfo
->si_code
> 0)
169 faultaddr
= tst
->arch
.vex
.guest_pc
;
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
) );
180 VG_(memcpy
)(&frame
->rs_info
, siginfo
, sizeof(*siginfo
));
182 VG_TRACK( post_mem_write
, Vg_CoreSignal
, tid
,
183 (Addr
)&frame
->rs_info
, sizeof(frame
->rs_info
) );
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
) );
191 ucp
->uc_stack
= tst
->altstack
;
193 VG_TRACK( post_mem_write
, Vg_CoreSignal
, tid
, (Addr
)ucp
,
194 offsetof(struct vki_ucontext
, uc_mcontext
) );
196 struct vki_sigcontext
*scp
= &(frame
->rs_uc
.uc_mcontext
);
197 setup_sigcontext2(tst
, &(scp
), siginfo
);
199 ucp
->uc_sigmask
= tst
->sig_mask
;
204 * Arguments to signal handler:
207 * r1 = 0 (should be cause)
208 * r2 = pointer to ucontext
210 * r54 points to the struct rt_sigframe.
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
;
218 if (flags
& VKI_SA_RESTORER
)
220 tst
->arch
.vex
.guest_r55
= (Addr
) restorer
;
224 tst
->arch
.vex
.guest_r55
= (Addr
)&VG_(tilegx_linux_SUBST_FOR_rt_sigreturn
);
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
240 VG_(printf
)("pushed signal frame; sp now = %lx, "
241 "next %pc = %lx, status=%d\n",
242 (Addr
)frame
, tst
->arch
.vex
.guest_pc
, tst
->status
);
246 void VG_(sigframe_destroy
)( ThreadId tid
, Bool isRT
)
249 struct vg_sig_private
*priv1
;
252 struct vki_sigcontext
*mc
;
254 Bool has_siginfo
= isRT
;
256 vg_assert(VG_(is_valid_tid
)(tid
));
257 tst
= VG_(get_ThreadState
)(tid
);
258 sp
= tst
->arch
.vex
.guest_r54
+ 8;
261 struct rt_sigframe
*frame
= (struct rt_sigframe
*)sp
;
262 struct vki_ucontext
*ucp
= &frame
->rs_uc
;
265 VG_(printf
)("destroy signal frame; sp = %lx, "
266 " %pc = %lx, status=%d\n",
267 (Addr
)frame
, tst
->arch
.vex
.guest_pc
, tst
->status
);
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
;
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
;
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 %d): isRT=%d valid magic; EIP=%#x\n",
343 tid
, isRT
, tst
->arch
.vex
.guest_pc
);
345 VG_TRACK( post_deliver_signal
, tid
, sigNo
);
348 #endif // defined(VGP_tilegx_linux)
350 /*--------------------------------------------------------------------*/
351 /*--- end sigframe-tilegx-linux.c ---*/
352 /*--------------------------------------------------------------------*/