2 /*--------------------------------------------------------------------*/
3 /*--- Create/destroy signal delivery frames. ---*/
4 /*--- sigframe-mips64-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, see <http://www.gnu.org/licenses/>.
27 The GNU General Public License is contained in the file COPYING.
30 #if defined(VGP_mips64_linux)
32 #include "pub_core_basics.h"
33 #include "pub_core_vki.h"
34 #include "pub_core_vkiscnums.h"
35 #include "pub_core_threadstate.h"
36 #include "pub_core_aspacemgr.h"
37 #include "pub_core_libcbase.h"
38 #include "pub_core_libcassert.h"
39 #include "pub_core_libcprint.h"
40 #include "pub_core_machine.h"
41 #include "pub_core_options.h"
42 #include "pub_core_sigframe.h"
43 #include "pub_core_signals.h"
44 #include "pub_core_tooliface.h"
45 #include "pub_core_trampoline.h"
46 #include "priv_sigframe.h"
48 struct vg_sig_private
{
51 VexGuestMIPS64State vex_shadow1
;
52 VexGuestMIPS64State vex_shadow2
;
56 UInt sf_ass
[4]; /* argument save space for o32 */
57 UInt sf_pad
[2]; /* Was: signal trampoline */
58 struct vki_sigcontext sf_sc
;
60 struct vg_sig_private priv
;
64 UInt rs_ass
[4]; /* argument save space for o32 */
65 UInt rs_pad
[2]; /* Was: signal trampoline */
66 vki_siginfo_t rs_info
;
67 struct vki_ucontext rs_uc
;
68 struct vg_sig_private priv
;
72 static void setup_sigcontext ( ThreadState
* tst
, struct vki_sigcontext
**sc1
,
73 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
->sc_regs
[1] = tst
->arch
.vex
.guest_r1
;
80 sc
->sc_regs
[2] = tst
->arch
.vex
.guest_r2
;
81 sc
->sc_regs
[3] = tst
->arch
.vex
.guest_r3
;
82 sc
->sc_regs
[4] = tst
->arch
.vex
.guest_r4
;
83 sc
->sc_regs
[5] = tst
->arch
.vex
.guest_r5
;
84 sc
->sc_regs
[6] = tst
->arch
.vex
.guest_r6
;
85 sc
->sc_regs
[7] = tst
->arch
.vex
.guest_r7
;
86 sc
->sc_regs
[8] = tst
->arch
.vex
.guest_r8
;
87 sc
->sc_regs
[9] = tst
->arch
.vex
.guest_r9
;
88 sc
->sc_regs
[10] = tst
->arch
.vex
.guest_r10
;
89 sc
->sc_regs
[11] = tst
->arch
.vex
.guest_r11
;
90 sc
->sc_regs
[12] = tst
->arch
.vex
.guest_r12
;
91 sc
->sc_regs
[13] = tst
->arch
.vex
.guest_r13
;
92 sc
->sc_regs
[14] = tst
->arch
.vex
.guest_r14
;
93 sc
->sc_regs
[15] = tst
->arch
.vex
.guest_r15
;
94 sc
->sc_regs
[16] = tst
->arch
.vex
.guest_r16
;
95 sc
->sc_regs
[17] = tst
->arch
.vex
.guest_r17
;
96 sc
->sc_regs
[18] = tst
->arch
.vex
.guest_r18
;
97 sc
->sc_regs
[19] = tst
->arch
.vex
.guest_r19
;
98 sc
->sc_regs
[20] = tst
->arch
.vex
.guest_r20
;
99 sc
->sc_regs
[21] = tst
->arch
.vex
.guest_r21
;
100 sc
->sc_regs
[22] = tst
->arch
.vex
.guest_r22
;
101 sc
->sc_regs
[23] = tst
->arch
.vex
.guest_r23
;
102 sc
->sc_regs
[24] = tst
->arch
.vex
.guest_r24
;
103 sc
->sc_regs
[25] = tst
->arch
.vex
.guest_r25
;
104 sc
->sc_regs
[26] = tst
->arch
.vex
.guest_r26
;
105 sc
->sc_regs
[27] = tst
->arch
.vex
.guest_r27
;
106 sc
->sc_regs
[28] = tst
->arch
.vex
.guest_r28
;
107 sc
->sc_regs
[29] = tst
->arch
.vex
.guest_r29
;
108 sc
->sc_regs
[30] = tst
->arch
.vex
.guest_r30
;
109 sc
->sc_regs
[31] = tst
->arch
.vex
.guest_r31
;
110 sc
->sc_pc
= tst
->arch
.vex
.guest_PC
;
111 sc
->sc_mdhi
= tst
->arch
.vex
.guest_HI
;
112 sc
->sc_mdlo
= tst
->arch
.vex
.guest_LO
;
116 void VG_(sigframe_create
) ( ThreadId tid
,
118 Addr sp_top_of_frame
,
119 const vki_siginfo_t
*siginfo
,
120 const struct vki_ucontext
*siguc
,
123 const vki_sigset_t
*mask
,
127 ThreadState
* tst
= VG_(get_ThreadState
)(tid
);
128 Int sigNo
= siginfo
->si_signo
;
129 struct vg_sig_private
*priv
;
130 /* Stack must be 16-byte aligned */
131 sp_top_of_frame
&= ~0xf;
133 sp
= sp_top_of_frame
- sizeof(struct rt_sigframe
);
135 tst
= VG_(get_ThreadState
)(tid
);
136 if (! ML_(sf_maybe_extend_stack
)(tst
, sp
, sp_top_of_frame
- sp
, flags
))
139 sp
= VG_ROUNDDN(sp
, 16);
141 struct rt_sigframe
*frame
= (struct rt_sigframe
*)sp
;
142 struct vki_ucontext
*ucp
= &frame
->rs_uc
;
143 if (VG_(clo_trace_signals
))
144 VG_(printf
)("rt_sigframe\n");
145 /* Create siginfo. */
146 VG_TRACK(pre_mem_write
, Vg_CoreSignal
, tid
, "signal frame siginfo",
147 (Addr
)&frame
->rs_info
, sizeof(frame
->rs_info
));
149 VG_(memcpy
)(&frame
->rs_info
, siginfo
, sizeof(*siginfo
));
151 VG_TRACK(post_mem_write
, Vg_CoreSignal
, tid
,
152 (Addr
)&frame
->rs_info
, sizeof(frame
->rs_info
));
154 /* Create the ucontext. */
155 VG_TRACK(pre_mem_write
, Vg_CoreSignal
, tid
, "signal frame ucontext",
156 (Addr
)ucp
, offsetof(struct vki_ucontext
, uc_mcontext
));
160 ucp
->uc_stack
= tst
->altstack
;
162 VG_TRACK(post_mem_write
, Vg_CoreSignal
, tid
, (Addr
)ucp
,
163 offsetof(struct vki_ucontext
, uc_mcontext
));
165 struct vki_sigcontext
*scp
= &(frame
->rs_uc
.uc_mcontext
);
166 setup_sigcontext(tst
, &(scp
), siginfo
);
167 ucp
->uc_sigmask
= tst
->sig_mask
;
170 /* Arguments to signal handler:
173 a1 = 0 (should be cause)
174 a2 = pointer to ucontext
176 $25 and c0_epc point to the signal handler, $29 points to
177 the struct rt_sigframe. */
179 tst
->arch
.vex
.guest_r4
= siginfo
->si_signo
;
180 tst
->arch
.vex
.guest_r5
= (Addr
) &frame
->rs_info
;
181 tst
->arch
.vex
.guest_r6
= (Addr
) &frame
->rs_uc
;
182 tst
->arch
.vex
.guest_r29
= (Addr
) frame
;
183 tst
->arch
.vex
.guest_r25
= (Addr
) handler
;
185 if (flags
& VKI_SA_RESTORER
)
186 tst
->arch
.vex
.guest_r31
= (Addr
) restorer
;
188 tst
->arch
.vex
.guest_r31
= (Addr
)&VG_(mips64_linux_SUBST_FOR_rt_sigreturn
);
190 priv
->magicPI
= 0x31415927;
191 priv
->sigNo_private
= sigNo
;
192 priv
->vex_shadow1
= tst
->arch
.vex_shadow1
;
193 priv
->vex_shadow2
= tst
->arch
.vex_shadow2
;
194 /* Set the thread so it will next run the handler. */
195 VG_TRACK( post_reg_write
, Vg_CoreSignal
, tid
, VG_O_STACK_PTR
, sizeof(Addr
));
196 if (VG_(clo_trace_signals
))
197 VG_(printf
)("handler = %p\n", handler
);
198 tst
->arch
.vex
.guest_PC
= (Addr
) handler
;
199 /* This thread needs to be marked runnable, but we leave that
204 void VG_(sigframe_destroy
) ( ThreadId tid
, Bool isRT
)
207 struct vg_sig_private
*priv1
;
210 struct vki_sigcontext
*mc
;
213 vg_assert(VG_(is_valid_tid
)(tid
));
214 tst
= VG_(get_ThreadState
)(tid
);
215 sp
= tst
->arch
.vex
.guest_r29
;
216 struct rt_sigframe
*frame
= (struct rt_sigframe
*)sp
;
217 struct vki_ucontext
*ucp
= &frame
->rs_uc
;
218 frame_size
= sizeof(*frame
);
219 mc
= &ucp
->uc_mcontext
;
220 tst
->sig_mask
= ucp
->uc_sigmask
;
221 tst
->tmp_sig_mask
= ucp
->uc_sigmask
;
222 priv1
= &frame
->priv
;
223 sigNo
= priv1
->sigNo_private
;
224 vg_assert(priv1
->magicPI
== 0x31415927);
226 tst
->arch
.vex
.guest_r1
= mc
->sc_regs
[1];
227 tst
->arch
.vex
.guest_r2
= mc
->sc_regs
[2];
228 tst
->arch
.vex
.guest_r3
= mc
->sc_regs
[3];
229 tst
->arch
.vex
.guest_r4
= mc
->sc_regs
[4];
230 tst
->arch
.vex
.guest_r5
= mc
->sc_regs
[5];
231 tst
->arch
.vex
.guest_r6
= mc
->sc_regs
[6];
232 tst
->arch
.vex
.guest_r7
= mc
->sc_regs
[7];
233 tst
->arch
.vex
.guest_r8
= mc
->sc_regs
[8];
234 tst
->arch
.vex
.guest_r9
= mc
->sc_regs
[9];
235 tst
->arch
.vex
.guest_r10
= mc
->sc_regs
[10];
236 tst
->arch
.vex
.guest_r11
= mc
->sc_regs
[11];
237 tst
->arch
.vex
.guest_r12
= mc
->sc_regs
[12];
238 tst
->arch
.vex
.guest_r13
= mc
->sc_regs
[13];
239 tst
->arch
.vex
.guest_r14
= mc
->sc_regs
[14];
240 tst
->arch
.vex
.guest_r15
= mc
->sc_regs
[15];
241 tst
->arch
.vex
.guest_r16
= mc
->sc_regs
[16];
242 tst
->arch
.vex
.guest_r17
= mc
->sc_regs
[17];
243 tst
->arch
.vex
.guest_r18
= mc
->sc_regs
[18];
244 tst
->arch
.vex
.guest_r19
= mc
->sc_regs
[19];
245 tst
->arch
.vex
.guest_r20
= mc
->sc_regs
[20];
246 tst
->arch
.vex
.guest_r21
= mc
->sc_regs
[21];
247 tst
->arch
.vex
.guest_r22
= mc
->sc_regs
[22];
248 tst
->arch
.vex
.guest_r23
= mc
->sc_regs
[23];
249 tst
->arch
.vex
.guest_r24
= mc
->sc_regs
[24];
250 tst
->arch
.vex
.guest_r25
= mc
->sc_regs
[25];
251 tst
->arch
.vex
.guest_r26
= mc
->sc_regs
[26];
252 tst
->arch
.vex
.guest_r27
= mc
->sc_regs
[27];
253 tst
->arch
.vex
.guest_r28
= mc
->sc_regs
[28];
254 tst
->arch
.vex
.guest_r30
= mc
->sc_regs
[30];
255 tst
->arch
.vex
.guest_PC
= mc
->sc_pc
;
256 tst
->arch
.vex
.guest_r31
= mc
->sc_regs
[31];
257 tst
->arch
.vex
.guest_r29
= mc
->sc_regs
[29];
259 tst
->arch
.vex
.guest_HI
= mc
->sc_mdhi
;
260 tst
->arch
.vex
.guest_LO
= mc
->sc_mdlo
;
261 tst
->arch
.vex_shadow1
= priv1
->vex_shadow1
;
262 tst
->arch
.vex_shadow2
= priv1
->vex_shadow2
;
264 VG_TRACK(die_mem_stack_signal
, sp
, frame_size
);
265 if (VG_(clo_trace_signals
))
266 VG_(message
)(Vg_DebugMsg
,
267 "VG_(signal_return) (thread %u): isRT=%d valid magic; EIP=%#llx\n",
268 tid
, isRT
, tst
->arch
.vex
.guest_PC
);
270 VG_TRACK( post_deliver_signal
, tid
, sigNo
);
273 #endif /* defined(VGP_mips64_linux) */
275 /*--------------------------------------------------------------------*/
276 /*--- end sigframe-mips64-linux.c ---*/
277 /*--------------------------------------------------------------------*/