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
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, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
29 #if defined(VGP_mips32_linux)
31 #include "pub_core_basics.h"
32 #include "pub_core_vki.h"
33 #include "pub_core_vkiscnums.h"
34 #include "pub_core_threadstate.h"
35 #include "pub_core_aspacemgr.h"
36 #include "pub_core_libcbase.h"
37 #include "pub_core_libcassert.h"
38 #include "pub_core_libcprint.h"
39 #include "pub_core_machine.h"
40 #include "pub_core_options.h"
41 #include "pub_core_sigframe.h"
42 #include "pub_core_signals.h"
43 #include "pub_core_tooliface.h"
44 #include "pub_core_trampoline.h"
45 #include "priv_sigframe.h"
51 VexGuestMIPS32State vex_shadow1
;
52 VexGuestMIPS32State vex_shadow2
;
57 UInt sf_ass
[4]; /* argument save space for o32 */
58 UInt sf_pad
[2]; /* Was: signal trampoline */
59 struct vki_sigcontext sf_sc
;
61 struct vg_sig_private priv
;
66 UInt rs_ass
[4]; /* argument save space for o32 */
67 UInt rs_pad
[2]; /* Was: signal trampoline */
68 vki_siginfo_t rs_info
;
69 struct vki_ucontext rs_uc
;
70 struct vg_sig_private priv
;
75 void setup_sigcontext2 ( ThreadState
* tst
, struct vki_sigcontext
**sc1
,
76 const vki_siginfo_t
*si
)
79 struct vki_sigcontext
*sc
= *sc1
;
81 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tst
->tid
, "signal frame mcontext",
82 (Addr
)sc
, sizeof(unsigned long long)*34 );
83 sc
->sc_regs
[1] = tst
->arch
.vex
.guest_r1
;
84 sc
->sc_regs
[2] = tst
->arch
.vex
.guest_r2
;
85 sc
->sc_regs
[3] = tst
->arch
.vex
.guest_r3
;
86 sc
->sc_regs
[4] = tst
->arch
.vex
.guest_r4
;
87 sc
->sc_regs
[5] = tst
->arch
.vex
.guest_r5
;
88 sc
->sc_regs
[6] = tst
->arch
.vex
.guest_r6
;
89 sc
->sc_regs
[7] = tst
->arch
.vex
.guest_r7
;
90 sc
->sc_regs
[8] = tst
->arch
.vex
.guest_r8
;
91 sc
->sc_regs
[9] = tst
->arch
.vex
.guest_r9
;
92 sc
->sc_regs
[10] = tst
->arch
.vex
.guest_r10
;
93 sc
->sc_regs
[11] = tst
->arch
.vex
.guest_r11
;
94 sc
->sc_regs
[12] = tst
->arch
.vex
.guest_r12
;
95 sc
->sc_regs
[13] = tst
->arch
.vex
.guest_r13
;
96 sc
->sc_regs
[14] = tst
->arch
.vex
.guest_r14
;
97 sc
->sc_regs
[15] = tst
->arch
.vex
.guest_r15
;
98 sc
->sc_regs
[16] = tst
->arch
.vex
.guest_r16
;
99 sc
->sc_regs
[17] = tst
->arch
.vex
.guest_r17
;
100 sc
->sc_regs
[18] = tst
->arch
.vex
.guest_r18
;
101 sc
->sc_regs
[19] = tst
->arch
.vex
.guest_r19
;
102 sc
->sc_regs
[20] = tst
->arch
.vex
.guest_r20
;
103 sc
->sc_regs
[21] = tst
->arch
.vex
.guest_r21
;
104 sc
->sc_regs
[22] = tst
->arch
.vex
.guest_r22
;
105 sc
->sc_regs
[23] = tst
->arch
.vex
.guest_r23
;
106 sc
->sc_regs
[24] = tst
->arch
.vex
.guest_r24
;
107 sc
->sc_regs
[25] = tst
->arch
.vex
.guest_r25
;
108 sc
->sc_regs
[26] = tst
->arch
.vex
.guest_r26
;
109 sc
->sc_regs
[27] = tst
->arch
.vex
.guest_r27
;
110 sc
->sc_regs
[28] = tst
->arch
.vex
.guest_r28
;
111 sc
->sc_regs
[29] = tst
->arch
.vex
.guest_r29
;
112 sc
->sc_regs
[30] = tst
->arch
.vex
.guest_r30
;
113 sc
->sc_regs
[31] = tst
->arch
.vex
.guest_r31
;
114 sc
->sc_pc
= tst
->arch
.vex
.guest_PC
;
115 sc
->sc_mdhi
= tst
->arch
.vex
.guest_HI
;
116 sc
->sc_mdlo
= tst
->arch
.vex
.guest_LO
;
120 void VG_(sigframe_create
)( ThreadId tid
,
122 Addr sp_top_of_frame
,
123 const vki_siginfo_t
*siginfo
,
124 const struct vki_ucontext
*siguc
,
127 const vki_sigset_t
*mask
,
131 ThreadState
* tst
= VG_(get_ThreadState
)(tid
);
132 Int sigNo
= siginfo
->si_signo
;
133 struct vg_sig_private
*priv
;
135 /* Stack must be 8-byte aligned */
136 sp_top_of_frame
&= ~0xf;
138 if (flags
& VKI_SA_SIGINFO
)
140 sp
= sp_top_of_frame
- sizeof(struct rt_sigframe
);
144 sp
= sp_top_of_frame
- sizeof(struct sigframe
);
147 tst
= VG_(get_ThreadState
)(tid
);
148 if (! ML_(sf_maybe_extend_stack
)(tst
, sp
, sp_top_of_frame
- sp
, flags
))
151 vg_assert(VG_IS_8_ALIGNED(sp
));
153 if (flags
& VKI_SA_SIGINFO
)
155 struct rt_sigframe
*frame
= (struct rt_sigframe
*) sp
;
156 struct vki_ucontext
*ucp
= &frame
->rs_uc
;
157 if (VG_(clo_trace_signals
))
158 VG_(printf
)("rt_sigframe\n");
159 /* Create siginfo. */
160 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tid
, "signal frame siginfo",
161 (Addr
)&frame
->rs_info
, sizeof(frame
->rs_info
) );
163 VG_(memcpy
)(&frame
->rs_info
, siginfo
, sizeof(*siginfo
));
165 VG_TRACK( post_mem_write
, Vg_CoreSignal
, tid
,
166 (Addr
)&frame
->rs_info
, sizeof(frame
->rs_info
) );
168 /* Create the ucontext. */
169 VG_TRACK( pre_mem_write
, Vg_CoreSignal
, tid
, "signal frame ucontext",
170 (Addr
)ucp
, offsetof(struct vki_ucontext
, uc_mcontext
) );
174 ucp
->uc_stack
= tst
->altstack
;
176 VG_TRACK( post_mem_write
, Vg_CoreSignal
, tid
, (Addr
)ucp
,
177 offsetof(struct vki_ucontext
, uc_mcontext
) );
179 struct vki_sigcontext
*scp
= &(frame
->rs_uc
.uc_mcontext
);
180 setup_sigcontext2(tst
, &(scp
), siginfo
);
182 ucp
->uc_sigmask
= tst
->sig_mask
;
187 * Arguments to signal handler:
190 * a1 = 0 (should be cause)
191 * a2 = pointer to ucontext
193 * $25 and c0_epc point to the signal handler, $29 points to
194 * the struct rt_sigframe.
197 tst
->arch
.vex
.guest_r4
= siginfo
->si_signo
;
198 tst
->arch
.vex
.guest_r5
= (Addr
) &frame
->rs_info
;
199 tst
->arch
.vex
.guest_r6
= (Addr
) &frame
->rs_uc
;
200 tst
->arch
.vex
.guest_r29
= (Addr
) frame
;
201 tst
->arch
.vex
.guest_r25
= (Addr
) handler
;
203 if (flags
& VKI_SA_RESTORER
)
205 tst
->arch
.vex
.guest_r31
= (Addr
) restorer
;
209 tst
->arch
.vex
.guest_r31
= (Addr
)&VG_(mips32_linux_SUBST_FOR_rt_sigreturn
);
215 if (VG_(clo_trace_signals
))
216 VG_(printf
)("sigframe\n");
217 struct sigframe
*frame
= (struct sigframe
*) sp
;
218 struct vki_sigcontext
*scp
= &(frame
->sf_sc
);
219 setup_sigcontext2(tst
, &(scp
), siginfo
);
220 frame
->sf_mask
= tst
->sig_mask
;
223 * Arguments to signal handler:
226 * a1 = 0 (should be cause)
227 * a2 = pointer to struct sigcontext
229 * $25 and c0_epc point to the signal handler, $29 points to the
232 tst
->arch
.vex
.guest_r4
= siginfo
->si_signo
;
233 tst
->arch
.vex
.guest_r5
= 0;
234 tst
->arch
.vex
.guest_r6
= (Addr
) &frame
->sf_sc
;
235 tst
->arch
.vex
.guest_r29
= (Addr
) frame
;
236 tst
->arch
.vex
.guest_r25
= (Addr
) handler
;
238 if (flags
& VKI_SA_RESTORER
)
240 tst
->arch
.vex
.guest_r31
= (Addr
) restorer
;
244 tst
->arch
.vex
.guest_r31
= (Addr
)&VG_(mips32_linux_SUBST_FOR_sigreturn
);
248 priv
->magicPI
= 0x31415927;
249 priv
->sigNo_private
= sigNo
;
250 priv
->vex_shadow1
= tst
->arch
.vex_shadow1
;
251 priv
->vex_shadow2
= tst
->arch
.vex_shadow2
;
252 /* Set the thread so it will next run the handler. */
253 /* tst->m_sp = sp; also notify the tool we've updated SP */
254 VG_TRACK( post_reg_write
, Vg_CoreSignal
, tid
, VG_O_STACK_PTR
, sizeof(Addr
));
255 if (VG_(clo_trace_signals
))
256 VG_(printf
)("handler = %p\n", handler
);
257 tst
->arch
.vex
.guest_PC
= (Addr
) handler
;
258 /* This thread needs to be marked runnable, but we leave that the
263 void VG_(sigframe_destroy
)( ThreadId tid
, Bool isRT
)
266 struct vg_sig_private
*priv1
;
269 struct vki_sigcontext
*mc
;
271 Bool has_siginfo
= isRT
;
273 vg_assert(VG_(is_valid_tid
)(tid
));
274 tst
= VG_(get_ThreadState
)(tid
);
275 sp
= tst
->arch
.vex
.guest_r29
;
278 struct rt_sigframe
*frame
= (struct rt_sigframe
*)sp
;
279 struct vki_ucontext
*ucp
= &frame
->rs_uc
;
280 frame_size
= sizeof(*frame
);
281 mc
= &ucp
->uc_mcontext
;
282 priv1
= &frame
->priv
;
283 vg_assert(priv1
->magicPI
== 0x31415927);
284 sigNo
= priv1
->sigNo_private
;
288 struct sigframe
*frame
= (struct sigframe
*)sp
;
289 frame_size
= sizeof(*frame
);
290 mc
= &(frame
->sf_sc
);
291 priv1
= &frame
->priv
;
292 vg_assert(priv1
->magicPI
== 0x31415927);
293 tst
->sig_mask
= frame
->sf_mask
;
294 tst
->tmp_sig_mask
= tst
->sig_mask
;
295 sigNo
= priv1
->sigNo_private
;
298 tst
->arch
.vex
.guest_r1
= mc
->sc_regs
[1];
299 tst
->arch
.vex
.guest_r2
= mc
->sc_regs
[2];
300 tst
->arch
.vex
.guest_r3
= mc
->sc_regs
[3];
301 tst
->arch
.vex
.guest_r4
= mc
->sc_regs
[4];
302 tst
->arch
.vex
.guest_r5
= mc
->sc_regs
[5];
303 tst
->arch
.vex
.guest_r6
= mc
->sc_regs
[6];
304 tst
->arch
.vex
.guest_r7
= mc
->sc_regs
[7];
305 tst
->arch
.vex
.guest_r8
= mc
->sc_regs
[8];
306 tst
->arch
.vex
.guest_r9
= mc
->sc_regs
[9];
307 tst
->arch
.vex
.guest_r10
= mc
->sc_regs
[10];
308 tst
->arch
.vex
.guest_r11
= mc
->sc_regs
[11];
309 tst
->arch
.vex
.guest_r12
= mc
->sc_regs
[12];
310 tst
->arch
.vex
.guest_r13
= mc
->sc_regs
[13];
311 tst
->arch
.vex
.guest_r14
= mc
->sc_regs
[14];
312 tst
->arch
.vex
.guest_r15
= mc
->sc_regs
[15];
313 tst
->arch
.vex
.guest_r16
= mc
->sc_regs
[16];
314 tst
->arch
.vex
.guest_r17
= mc
->sc_regs
[17];
315 tst
->arch
.vex
.guest_r18
= mc
->sc_regs
[18];
316 tst
->arch
.vex
.guest_r19
= mc
->sc_regs
[19];
317 tst
->arch
.vex
.guest_r20
= mc
->sc_regs
[20];
318 tst
->arch
.vex
.guest_r21
= mc
->sc_regs
[21];
319 tst
->arch
.vex
.guest_r22
= mc
->sc_regs
[22];
320 tst
->arch
.vex
.guest_r23
= mc
->sc_regs
[23];
321 tst
->arch
.vex
.guest_r24
= mc
->sc_regs
[24];
322 tst
->arch
.vex
.guest_r25
= mc
->sc_regs
[25];
323 tst
->arch
.vex
.guest_r26
= mc
->sc_regs
[26];
324 tst
->arch
.vex
.guest_r27
= mc
->sc_regs
[27];
325 tst
->arch
.vex
.guest_r28
= mc
->sc_regs
[28];
326 tst
->arch
.vex
.guest_r30
= mc
->sc_regs
[30];
327 tst
->arch
.vex
.guest_PC
= mc
->sc_pc
;
328 tst
->arch
.vex
.guest_r31
= mc
->sc_regs
[31];
329 tst
->arch
.vex
.guest_r29
= mc
->sc_regs
[29];
331 tst
->arch
.vex
.guest_HI
= mc
->sc_mdhi
;
332 tst
->arch
.vex
.guest_LO
= mc
->sc_mdlo
;
333 tst
->arch
.vex_shadow1
= priv1
->vex_shadow1
;
334 tst
->arch
.vex_shadow2
= priv1
->vex_shadow2
;
336 VG_TRACK(die_mem_stack_signal
, sp
, frame_size
);
337 if (VG_(clo_trace_signals
))
338 VG_(message
)( Vg_DebugMsg
,
339 "VG_(signal_return) (thread %u): isRT=%d valid magic; EIP=%#x\n",
340 tid
, isRT
, tst
->arch
.vex
.guest_PC
);
342 VG_TRACK( post_deliver_signal
, tid
, sigNo
);
345 #endif // defined(VGP_mips32_linux)
347 /*--------------------------------------------------------------------*/
348 /*--- end sigframe-mips32-linux.c ---*/
349 /*--------------------------------------------------------------------*/