blob: 4b23dc746a653ef84e20fa953b4c1b3b9dfd3428 [file] [log] [blame]
sewardjc68994d2012-06-07 09:23:23 +00001
2/*--------------------------------------------------------------------*/
3/*--- Create/destroy signal delivery frames. ---*/
4/*--- sigframe-mips32-linux.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
sewardj0f157dd2013-10-18 14:27:36 +000011 Copyright (C) 2010-2013 RT-RK
sewardjc68994d2012-06-07 09:23:23 +000012 mips-valgrind@rt-rk.com
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
30*/
31
32#if defined(VGP_mips32_linux)
33
34#include "pub_core_basics.h"
35#include "pub_core_vki.h"
36#include "pub_core_vkiscnums.h"
sewardjc68994d2012-06-07 09:23:23 +000037#include "pub_core_threadstate.h"
38#include "pub_core_aspacemgr.h"
39#include "pub_core_libcbase.h"
40#include "pub_core_libcassert.h"
41#include "pub_core_libcprint.h"
42#include "pub_core_machine.h"
43#include "pub_core_options.h"
44#include "pub_core_sigframe.h"
45#include "pub_core_signals.h"
46#include "pub_core_tooliface.h"
47#include "pub_core_trampoline.h"
florian01fcf6a2015-04-18 10:33:54 +000048#include "priv_sigframe.h"
sewardjc68994d2012-06-07 09:23:23 +000049
50struct vg_sig_private
51{
52 UInt magicPI;
53 UInt sigNo_private;
54 VexGuestMIPS32State vex_shadow1;
55 VexGuestMIPS32State vex_shadow2;
56};
57
58struct sigframe
59{
60 UInt sf_ass[4]; /* argument save space for o32 */
61 UInt sf_pad[2]; /* Was: signal trampoline */
62 struct vki_sigcontext sf_sc;
63 vki_sigset_t sf_mask;
64 struct vg_sig_private priv;
65};
66
67struct rt_sigframe
68{
69 UInt rs_ass[4]; /* argument save space for o32 */
70 UInt rs_pad[2]; /* Was: signal trampoline */
71 vki_siginfo_t rs_info;
72 struct vki_ucontext rs_uc;
73 struct vg_sig_private priv;
74};
75
sewardjc68994d2012-06-07 09:23:23 +000076
77static
petarj4df0bfc2013-02-27 23:17:33 +000078void setup_sigcontext2 ( ThreadState* tst, struct vki_sigcontext **sc1,
79 const vki_siginfo_t *si)
sewardjc68994d2012-06-07 09:23:23 +000080{
81
82 struct vki_sigcontext *sc = *sc1;
83
84 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcontext",
85 (Addr)sc, sizeof(unsigned long long)*34 );
86 sc->sc_regs[1] = tst->arch.vex.guest_r1;
87 sc->sc_regs[2] = tst->arch.vex.guest_r2;
88 sc->sc_regs[3] = tst->arch.vex.guest_r3;
89 sc->sc_regs[4] = tst->arch.vex.guest_r4;
90 sc->sc_regs[5] = tst->arch.vex.guest_r5;
91 sc->sc_regs[6] = tst->arch.vex.guest_r6;
92 sc->sc_regs[7] = tst->arch.vex.guest_r7;
93 sc->sc_regs[8] = tst->arch.vex.guest_r8;
94 sc->sc_regs[9] = tst->arch.vex.guest_r9;
95 sc->sc_regs[10] = tst->arch.vex.guest_r10;
96 sc->sc_regs[11] = tst->arch.vex.guest_r11;
97 sc->sc_regs[12] = tst->arch.vex.guest_r12;
98 sc->sc_regs[13] = tst->arch.vex.guest_r13;
99 sc->sc_regs[14] = tst->arch.vex.guest_r14;
100 sc->sc_regs[15] = tst->arch.vex.guest_r15;
101 sc->sc_regs[16] = tst->arch.vex.guest_r16;
102 sc->sc_regs[17] = tst->arch.vex.guest_r17;
103 sc->sc_regs[18] = tst->arch.vex.guest_r18;
104 sc->sc_regs[19] = tst->arch.vex.guest_r19;
105 sc->sc_regs[20] = tst->arch.vex.guest_r20;
106 sc->sc_regs[21] = tst->arch.vex.guest_r21;
107 sc->sc_regs[22] = tst->arch.vex.guest_r22;
108 sc->sc_regs[23] = tst->arch.vex.guest_r23;
109 sc->sc_regs[24] = tst->arch.vex.guest_r24;
110 sc->sc_regs[25] = tst->arch.vex.guest_r25;
111 sc->sc_regs[26] = tst->arch.vex.guest_r26;
112 sc->sc_regs[27] = tst->arch.vex.guest_r27;
113 sc->sc_regs[28] = tst->arch.vex.guest_r28;
114 sc->sc_regs[29] = tst->arch.vex.guest_r29;
115 sc->sc_regs[30] = tst->arch.vex.guest_r30;
116 sc->sc_regs[31] = tst->arch.vex.guest_r31;
117 sc->sc_pc = tst->arch.vex.guest_PC;
118 sc->sc_mdhi = tst->arch.vex.guest_HI;
119 sc->sc_mdlo = tst->arch.vex.guest_LO;
120}
121
122/* EXPORTED */
123void VG_(sigframe_create)( ThreadId tid,
124 Addr sp_top_of_frame,
125 const vki_siginfo_t *siginfo,
126 const struct vki_ucontext *siguc,
127 void *handler,
128 UInt flags,
129 const vki_sigset_t *mask,
130 void *restorer )
131{
132 Addr sp;
133 ThreadState* tst = VG_(get_ThreadState)(tid);
sewardjc68994d2012-06-07 09:23:23 +0000134 Int sigNo = siginfo->si_signo;
135 struct vg_sig_private *priv;
136
137 /* Stack must be 8-byte aligned */
138 sp_top_of_frame &= ~0xf;
139
140 if (flags & VKI_SA_SIGINFO)
141 {
142 sp = sp_top_of_frame - sizeof(struct rt_sigframe);
143 }
144 else
145 {
146 sp = sp_top_of_frame - sizeof(struct sigframe);
147 }
148
149 tst = VG_(get_ThreadState)(tid);
florian7d4a28b2015-04-23 15:20:00 +0000150 if (! ML_(sf_maybe_extend_stack)(tst, sp, sp_top_of_frame - sp, flags))
sewardjc68994d2012-06-07 09:23:23 +0000151 return;
152
153 vg_assert(VG_IS_8_ALIGNED(sp));
sewardjc68994d2012-06-07 09:23:23 +0000154
155 if (flags & VKI_SA_SIGINFO)
156 {
157 struct rt_sigframe *frame = (struct rt_sigframe *) sp;
158 struct vki_ucontext *ucp = &frame->rs_uc;
159 if (VG_(clo_trace_signals))
160 VG_(printf)("rt_sigframe\n");
161 /* Create siginfo. */
162 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame siginfo",
163 (Addr)&frame->rs_info, sizeof(frame->rs_info) );
164
165 VG_(memcpy)(&frame->rs_info, siginfo, sizeof(*siginfo));
166
167 VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
168 (Addr)&frame->rs_info, sizeof(frame->rs_info) );
169
170 /* Create the ucontext. */
171 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext",
172 (Addr)ucp, offsetof(struct vki_ucontext, uc_mcontext) );
173
174 ucp->uc_flags = 0;
175 ucp->uc_link = 0;
176 ucp->uc_stack = tst->altstack;
177
178 VG_TRACK( post_mem_write, Vg_CoreSignal, tid, (Addr)ucp,
179 offsetof(struct vki_ucontext, uc_mcontext) );
180
181 struct vki_sigcontext *scp = &(frame->rs_uc.uc_mcontext);
182 setup_sigcontext2(tst, &(scp), siginfo);
183
184 ucp->uc_sigmask = tst->sig_mask;
185
186 priv = &frame->priv;
187
188 /*
189 * Arguments to signal handler:
190 *
191 * a0 = signal number
192 * a1 = 0 (should be cause)
193 * a2 = pointer to ucontext
194 *
195 * $25 and c0_epc point to the signal handler, $29 points to
196 * the struct rt_sigframe.
197 */
198
199 tst->arch.vex.guest_r4 = siginfo->si_signo;
200 tst->arch.vex.guest_r5 = (Addr) &frame->rs_info;
201 tst->arch.vex.guest_r6 = (Addr) &frame->rs_uc;
202 tst->arch.vex.guest_r29 = (Addr) frame;
203 tst->arch.vex.guest_r25 = (Addr) handler;
204
205 if (flags & VKI_SA_RESTORER)
206 {
207 tst->arch.vex.guest_r31 = (Addr) restorer;
208 }
209 else
210 {
211 tst->arch.vex.guest_r31 = (Addr)&VG_(mips32_linux_SUBST_FOR_rt_sigreturn);
212 }
213
214 }
215 else
216 {
217 if (VG_(clo_trace_signals))
218 VG_(printf)("sigframe\n");
219 struct sigframe *frame = (struct sigframe *) sp;
220 struct vki_sigcontext *scp = &(frame->sf_sc);
221 setup_sigcontext2(tst, &(scp), siginfo);
222 frame->sf_mask = tst->sig_mask;
223 priv = &frame->priv;
224 /*
225 * Arguments to signal handler:
226 *
227 * a0 = signal number
228 * a1 = 0 (should be cause)
229 * a2 = pointer to struct sigcontext
230 *
231 * $25 and c0_epc point to the signal handler, $29 points to the
232 * struct sigframe.
233 */
234 tst->arch.vex.guest_r4 = siginfo->si_signo;
235 tst->arch.vex.guest_r5 = 0;
236 tst->arch.vex.guest_r6 = (Addr) &frame->sf_sc;
237 tst->arch.vex.guest_r29 = (Addr) frame;
238 tst->arch.vex.guest_r25 = (Addr) handler;
239
240 if (flags & VKI_SA_RESTORER)
241 {
242 tst->arch.vex.guest_r31 = (Addr) restorer;
243 }
244 else
245 {
246 tst->arch.vex.guest_r31 = (Addr)&VG_(mips32_linux_SUBST_FOR_sigreturn);
247 }
248 }
249
250 priv->magicPI = 0x31415927;
251 priv->sigNo_private = sigNo;
252 priv->vex_shadow1 = tst->arch.vex_shadow1;
253 priv->vex_shadow2 = tst->arch.vex_shadow2;
254 /* Set the thread so it will next run the handler. */
255 /* tst->m_sp = sp; also notify the tool we've updated SP */
256 VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr));
257 if (VG_(clo_trace_signals))
258 VG_(printf)("handler = %p\n", handler);
259 tst->arch.vex.guest_PC = (Addr) handler;
260 /* This thread needs to be marked runnable, but we leave that the
261 caller to do. */
262}
263
264/* EXPORTED */
265void VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
266{
267 ThreadState *tst;
268 struct vg_sig_private *priv1;
269 Addr sp;
270 UInt frame_size;
271 struct vki_sigcontext *mc;
272 Int sigNo;
273 Bool has_siginfo = isRT;
274
275 vg_assert(VG_(is_valid_tid)(tid));
276 tst = VG_(get_ThreadState)(tid);
277 sp = tst->arch.vex.guest_r29;
278 if (has_siginfo)
279 {
280 struct rt_sigframe *frame = (struct rt_sigframe *)sp;
281 struct vki_ucontext *ucp = &frame->rs_uc;
282 frame_size = sizeof(*frame);
283 mc = &ucp->uc_mcontext;
284 priv1 = &frame->priv;
285 vg_assert(priv1->magicPI == 0x31415927);
286 sigNo = priv1->sigNo_private;
287 }
288 else
289 {
290 struct sigframe *frame = (struct sigframe *)sp;
291 frame_size = sizeof(*frame);
292 mc = &(frame->sf_sc);
293 priv1 = &frame->priv;
294 vg_assert(priv1->magicPI == 0x31415927);
295 tst->sig_mask = frame->sf_mask;
296 tst->tmp_sig_mask = tst->sig_mask;
297 sigNo = priv1->sigNo_private;
298 }
299 //restore regs
300 tst->arch.vex.guest_r1 = mc->sc_regs[1];
301 tst->arch.vex.guest_r2 = mc->sc_regs[2];
302 tst->arch.vex.guest_r3 = mc->sc_regs[3];
303 tst->arch.vex.guest_r4 = mc->sc_regs[4];
304 tst->arch.vex.guest_r5 = mc->sc_regs[5];
305 tst->arch.vex.guest_r6 = mc->sc_regs[6];
306 tst->arch.vex.guest_r7 = mc->sc_regs[7];
307 tst->arch.vex.guest_r8 = mc->sc_regs[8];
308 tst->arch.vex.guest_r9 = mc->sc_regs[9];
309 tst->arch.vex.guest_r10 = mc->sc_regs[10];
310 tst->arch.vex.guest_r11 = mc->sc_regs[11];
311 tst->arch.vex.guest_r12 = mc->sc_regs[12];
312 tst->arch.vex.guest_r13= mc->sc_regs[13];
313 tst->arch.vex.guest_r14 = mc->sc_regs[14];
314 tst->arch.vex.guest_r15 = mc->sc_regs[15];
315 tst->arch.vex.guest_r16 = mc->sc_regs[16];
316 tst->arch.vex.guest_r17 = mc->sc_regs[17];
317 tst->arch.vex.guest_r18 = mc->sc_regs[18];
318 tst->arch.vex.guest_r19 = mc->sc_regs[19];
319 tst->arch.vex.guest_r20 = mc->sc_regs[20];
320 tst->arch.vex.guest_r21 = mc->sc_regs[21];
321 tst->arch.vex.guest_r22 = mc->sc_regs[22];
322 tst->arch.vex.guest_r23 = mc->sc_regs[23];
323 tst->arch.vex.guest_r24 = mc->sc_regs[24];
324 tst->arch.vex.guest_r25 = mc->sc_regs[25];
325 tst->arch.vex.guest_r26 = mc->sc_regs[26];
326 tst->arch.vex.guest_r27 = mc->sc_regs[27];
327 tst->arch.vex.guest_r28 = mc->sc_regs[28];
328 tst->arch.vex.guest_r30 = mc->sc_regs[30];
329 tst->arch.vex.guest_PC = mc->sc_pc;
330 tst->arch.vex.guest_r31 = mc->sc_regs[31];
331 tst->arch.vex.guest_r29 = mc->sc_regs[29];
332
333 tst->arch.vex.guest_HI = mc->sc_mdhi;
334 tst->arch.vex.guest_LO = mc->sc_mdlo;
335 tst->arch.vex_shadow1 = priv1->vex_shadow1;
336 tst->arch.vex_shadow2 = priv1->vex_shadow2;
337
338 VG_TRACK(die_mem_stack_signal, sp, frame_size);
339 if (VG_(clo_trace_signals))
340 VG_(message)( Vg_DebugMsg,
341 "VG_(signal_return) (thread %d): isRT=%d valid magic; EIP=%#x\n",
342 tid, isRT, tst->arch.vex.guest_PC);
343 /* tell the tools */
344 VG_TRACK( post_deliver_signal, tid, sigNo );
345}
346
347#endif // defined(VGP_mips32_linux)
348
349/*--------------------------------------------------------------------*/
350/*--- end sigframe-mips32-linux.c ---*/
351/*--------------------------------------------------------------------*/