2 /*--------------------------------------------------------------------*/
3 /*--- Create/destroy signal delivery frames. ---*/
4 /*--- sigframe-mips32-linux.c ---*/
5 /*--------------------------------------------------------------------*/
8 This file is part of Valgrind, a dynamic binary instrumentation
11 Copyright (C) 2010-2017 RT-RK
12 mips-valgrind@rt-rk.com
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.
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.
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
29 The GNU General Public License is contained in the file COPYING.
32 #if defined(VGP_mips32_linux)
34 #include "pub_core_basics.h"
35 #include "pub_core_vki.h"
36 #include "pub_core_vkiscnums.h"
37 #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"
48 #include "priv_sigframe.h"
54 VexGuestMIPS32State vex_shadow1
;
55 VexGuestMIPS32State vex_shadow2
;
60 UInt sf_ass
[4]; /* argument save space for o32 */
61 UInt sf_pad
[2]; /* Was: signal trampoline */
62 struct vki_sigcontext sf_sc
;
64 struct vg_sig_private priv
;
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
;
78 void setup_sigcontext2 ( ThreadState
* tst
, struct vki_sigcontext
**sc1
,
79 const vki_siginfo_t
*si
)
82 struct vki_sigcontext
*sc
= *sc1
;
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
;
123 void VG_(sigframe_create
)( ThreadId tid
,
125 Addr sp_top_of_frame
,
126 const vki_siginfo_t
*siginfo
,
127 const struct vki_ucontext
*siguc
,
130 const vki_sigset_t
*mask
,
134 ThreadState
* tst
= VG_(get_ThreadState
)(tid
);
135 Int sigNo
= siginfo
->si_signo
;
136 struct vg_sig_private
*priv
;
138 /* Stack must be 8-byte aligned */
139 sp_top_of_frame
&= ~0xf;
141 if (flags
& VKI_SA_SIGINFO
)
143 sp
= sp_top_of_frame
- sizeof(struct rt_sigframe
);
147 sp
= sp_top_of_frame
- sizeof(struct sigframe
);
150 tst
= VG_(get_ThreadState
)(tid
);
151 if (! ML_(sf_maybe_extend_stack
)(tst
, sp
, sp_top_of_frame
- sp
, flags
))
154 vg_assert(VG_IS_8_ALIGNED(sp
));
156 if (flags
& VKI_SA_SIGINFO
)
158 struct rt_sigframe
*frame
= (struct rt_sigframe
*) sp
;
159 struct vki_ucontext
*ucp
= &frame
->rs_uc
;
160 if (VG_(clo_trace_signals
))
161 VG_(printf
)("rt_sigframe\n");
162 /* Create siginfo. */
163 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tid
, "signal frame siginfo",
164 (Addr
)&frame
->rs_info
, sizeof(frame
->rs_info
) );
166 VG_(memcpy
)(&frame
->rs_info
, siginfo
, sizeof(*siginfo
));
168 VG_TRACK( post_mem_write
, Vg_CoreSignal
, tid
,
169 (Addr
)&frame
->rs_info
, sizeof(frame
->rs_info
) );
171 /* Create the ucontext. */
172 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tid
, "signal frame ucontext",
173 (Addr
)ucp
, offsetof(struct vki_ucontext
, uc_mcontext
) );
177 ucp
->uc_stack
= tst
->altstack
;
179 VG_TRACK( post_mem_write
, Vg_CoreSignal
, tid
, (Addr
)ucp
,
180 offsetof(struct vki_ucontext
, uc_mcontext
) );
182 struct vki_sigcontext
*scp
= &(frame
->rs_uc
.uc_mcontext
);
183 setup_sigcontext2(tst
, &(scp
), siginfo
);
185 ucp
->uc_sigmask
= tst
->sig_mask
;
190 * Arguments to signal handler:
193 * a1 = 0 (should be cause)
194 * a2 = pointer to ucontext
196 * $25 and c0_epc point to the signal handler, $29 points to
197 * the struct rt_sigframe.
200 tst
->arch
.vex
.guest_r4
= siginfo
->si_signo
;
201 tst
->arch
.vex
.guest_r5
= (Addr
) &frame
->rs_info
;
202 tst
->arch
.vex
.guest_r6
= (Addr
) &frame
->rs_uc
;
203 tst
->arch
.vex
.guest_r29
= (Addr
) frame
;
204 tst
->arch
.vex
.guest_r25
= (Addr
) handler
;
206 if (flags
& VKI_SA_RESTORER
)
208 tst
->arch
.vex
.guest_r31
= (Addr
) restorer
;
212 tst
->arch
.vex
.guest_r31
= (Addr
)&VG_(mips32_linux_SUBST_FOR_rt_sigreturn
);
218 if (VG_(clo_trace_signals
))
219 VG_(printf
)("sigframe\n");
220 struct sigframe
*frame
= (struct sigframe
*) sp
;
221 struct vki_sigcontext
*scp
= &(frame
->sf_sc
);
222 setup_sigcontext2(tst
, &(scp
), siginfo
);
223 frame
->sf_mask
= tst
->sig_mask
;
226 * Arguments to signal handler:
229 * a1 = 0 (should be cause)
230 * a2 = pointer to struct sigcontext
232 * $25 and c0_epc point to the signal handler, $29 points to the
235 tst
->arch
.vex
.guest_r4
= siginfo
->si_signo
;
236 tst
->arch
.vex
.guest_r5
= 0;
237 tst
->arch
.vex
.guest_r6
= (Addr
) &frame
->sf_sc
;
238 tst
->arch
.vex
.guest_r29
= (Addr
) frame
;
239 tst
->arch
.vex
.guest_r25
= (Addr
) handler
;
241 if (flags
& VKI_SA_RESTORER
)
243 tst
->arch
.vex
.guest_r31
= (Addr
) restorer
;
247 tst
->arch
.vex
.guest_r31
= (Addr
)&VG_(mips32_linux_SUBST_FOR_sigreturn
);
251 priv
->magicPI
= 0x31415927;
252 priv
->sigNo_private
= sigNo
;
253 priv
->vex_shadow1
= tst
->arch
.vex_shadow1
;
254 priv
->vex_shadow2
= tst
->arch
.vex_shadow2
;
255 /* Set the thread so it will next run the handler. */
256 /* tst->m_sp = sp; also notify the tool we've updated SP */
257 VG_TRACK( post_reg_write
, Vg_CoreSignal
, tid
, VG_O_STACK_PTR
, sizeof(Addr
));
258 if (VG_(clo_trace_signals
))
259 VG_(printf
)("handler = %p\n", handler
);
260 tst
->arch
.vex
.guest_PC
= (Addr
) handler
;
261 /* This thread needs to be marked runnable, but we leave that the
266 void VG_(sigframe_destroy
)( ThreadId tid
, Bool isRT
)
269 struct vg_sig_private
*priv1
;
272 struct vki_sigcontext
*mc
;
274 Bool has_siginfo
= isRT
;
276 vg_assert(VG_(is_valid_tid
)(tid
));
277 tst
= VG_(get_ThreadState
)(tid
);
278 sp
= tst
->arch
.vex
.guest_r29
;
281 struct rt_sigframe
*frame
= (struct rt_sigframe
*)sp
;
282 struct vki_ucontext
*ucp
= &frame
->rs_uc
;
283 frame_size
= sizeof(*frame
);
284 mc
= &ucp
->uc_mcontext
;
285 priv1
= &frame
->priv
;
286 vg_assert(priv1
->magicPI
== 0x31415927);
287 sigNo
= priv1
->sigNo_private
;
291 struct sigframe
*frame
= (struct sigframe
*)sp
;
292 frame_size
= sizeof(*frame
);
293 mc
= &(frame
->sf_sc
);
294 priv1
= &frame
->priv
;
295 vg_assert(priv1
->magicPI
== 0x31415927);
296 tst
->sig_mask
= frame
->sf_mask
;
297 tst
->tmp_sig_mask
= tst
->sig_mask
;
298 sigNo
= priv1
->sigNo_private
;
301 tst
->arch
.vex
.guest_r1
= mc
->sc_regs
[1];
302 tst
->arch
.vex
.guest_r2
= mc
->sc_regs
[2];
303 tst
->arch
.vex
.guest_r3
= mc
->sc_regs
[3];
304 tst
->arch
.vex
.guest_r4
= mc
->sc_regs
[4];
305 tst
->arch
.vex
.guest_r5
= mc
->sc_regs
[5];
306 tst
->arch
.vex
.guest_r6
= mc
->sc_regs
[6];
307 tst
->arch
.vex
.guest_r7
= mc
->sc_regs
[7];
308 tst
->arch
.vex
.guest_r8
= mc
->sc_regs
[8];
309 tst
->arch
.vex
.guest_r9
= mc
->sc_regs
[9];
310 tst
->arch
.vex
.guest_r10
= mc
->sc_regs
[10];
311 tst
->arch
.vex
.guest_r11
= mc
->sc_regs
[11];
312 tst
->arch
.vex
.guest_r12
= mc
->sc_regs
[12];
313 tst
->arch
.vex
.guest_r13
= mc
->sc_regs
[13];
314 tst
->arch
.vex
.guest_r14
= mc
->sc_regs
[14];
315 tst
->arch
.vex
.guest_r15
= mc
->sc_regs
[15];
316 tst
->arch
.vex
.guest_r16
= mc
->sc_regs
[16];
317 tst
->arch
.vex
.guest_r17
= mc
->sc_regs
[17];
318 tst
->arch
.vex
.guest_r18
= mc
->sc_regs
[18];
319 tst
->arch
.vex
.guest_r19
= mc
->sc_regs
[19];
320 tst
->arch
.vex
.guest_r20
= mc
->sc_regs
[20];
321 tst
->arch
.vex
.guest_r21
= mc
->sc_regs
[21];
322 tst
->arch
.vex
.guest_r22
= mc
->sc_regs
[22];
323 tst
->arch
.vex
.guest_r23
= mc
->sc_regs
[23];
324 tst
->arch
.vex
.guest_r24
= mc
->sc_regs
[24];
325 tst
->arch
.vex
.guest_r25
= mc
->sc_regs
[25];
326 tst
->arch
.vex
.guest_r26
= mc
->sc_regs
[26];
327 tst
->arch
.vex
.guest_r27
= mc
->sc_regs
[27];
328 tst
->arch
.vex
.guest_r28
= mc
->sc_regs
[28];
329 tst
->arch
.vex
.guest_r30
= mc
->sc_regs
[30];
330 tst
->arch
.vex
.guest_PC
= mc
->sc_pc
;
331 tst
->arch
.vex
.guest_r31
= mc
->sc_regs
[31];
332 tst
->arch
.vex
.guest_r29
= mc
->sc_regs
[29];
334 tst
->arch
.vex
.guest_HI
= mc
->sc_mdhi
;
335 tst
->arch
.vex
.guest_LO
= mc
->sc_mdlo
;
336 tst
->arch
.vex_shadow1
= priv1
->vex_shadow1
;
337 tst
->arch
.vex_shadow2
= priv1
->vex_shadow2
;
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
);
345 VG_TRACK( post_deliver_signal
, tid
, sigNo
);
348 #endif // defined(VGP_mips32_linux)
350 /*--------------------------------------------------------------------*/
351 /*--- end sigframe-mips32-linux.c ---*/
352 /*--------------------------------------------------------------------*/