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, 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_mips64_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"
50 struct vg_sig_private
{
53 VexGuestMIPS64State vex_shadow1
;
54 VexGuestMIPS64State vex_shadow2
;
58 UInt sf_ass
[4]; /* argument save space for o32 */
59 UInt sf_pad
[2]; /* Was: signal trampoline */
60 struct vki_sigcontext sf_sc
;
62 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
;
74 static void setup_sigcontext ( ThreadState
* tst
, struct vki_sigcontext
**sc1
,
75 const vki_siginfo_t
*si
)
77 struct vki_sigcontext
*sc
= *sc1
;
79 VG_TRACK(pre_mem_write
, Vg_CoreSignal
, tst
->tid
, "signal frame mcontext",
80 (Addr
)sc
, sizeof(unsigned long long)*34);
81 sc
->sc_regs
[1] = tst
->arch
.vex
.guest_r1
;
82 sc
->sc_regs
[2] = tst
->arch
.vex
.guest_r2
;
83 sc
->sc_regs
[3] = tst
->arch
.vex
.guest_r3
;
84 sc
->sc_regs
[4] = tst
->arch
.vex
.guest_r4
;
85 sc
->sc_regs
[5] = tst
->arch
.vex
.guest_r5
;
86 sc
->sc_regs
[6] = tst
->arch
.vex
.guest_r6
;
87 sc
->sc_regs
[7] = tst
->arch
.vex
.guest_r7
;
88 sc
->sc_regs
[8] = tst
->arch
.vex
.guest_r8
;
89 sc
->sc_regs
[9] = tst
->arch
.vex
.guest_r9
;
90 sc
->sc_regs
[10] = tst
->arch
.vex
.guest_r10
;
91 sc
->sc_regs
[11] = tst
->arch
.vex
.guest_r11
;
92 sc
->sc_regs
[12] = tst
->arch
.vex
.guest_r12
;
93 sc
->sc_regs
[13] = tst
->arch
.vex
.guest_r13
;
94 sc
->sc_regs
[14] = tst
->arch
.vex
.guest_r14
;
95 sc
->sc_regs
[15] = tst
->arch
.vex
.guest_r15
;
96 sc
->sc_regs
[16] = tst
->arch
.vex
.guest_r16
;
97 sc
->sc_regs
[17] = tst
->arch
.vex
.guest_r17
;
98 sc
->sc_regs
[18] = tst
->arch
.vex
.guest_r18
;
99 sc
->sc_regs
[19] = tst
->arch
.vex
.guest_r19
;
100 sc
->sc_regs
[20] = tst
->arch
.vex
.guest_r20
;
101 sc
->sc_regs
[21] = tst
->arch
.vex
.guest_r21
;
102 sc
->sc_regs
[22] = tst
->arch
.vex
.guest_r22
;
103 sc
->sc_regs
[23] = tst
->arch
.vex
.guest_r23
;
104 sc
->sc_regs
[24] = tst
->arch
.vex
.guest_r24
;
105 sc
->sc_regs
[25] = tst
->arch
.vex
.guest_r25
;
106 sc
->sc_regs
[26] = tst
->arch
.vex
.guest_r26
;
107 sc
->sc_regs
[27] = tst
->arch
.vex
.guest_r27
;
108 sc
->sc_regs
[28] = tst
->arch
.vex
.guest_r28
;
109 sc
->sc_regs
[29] = tst
->arch
.vex
.guest_r29
;
110 sc
->sc_regs
[30] = tst
->arch
.vex
.guest_r30
;
111 sc
->sc_regs
[31] = tst
->arch
.vex
.guest_r31
;
112 sc
->sc_pc
= tst
->arch
.vex
.guest_PC
;
113 sc
->sc_mdhi
= tst
->arch
.vex
.guest_HI
;
114 sc
->sc_mdlo
= tst
->arch
.vex
.guest_LO
;
118 void VG_(sigframe_create
) ( ThreadId tid
,
120 Addr sp_top_of_frame
,
121 const vki_siginfo_t
*siginfo
,
122 const struct vki_ucontext
*siguc
,
125 const vki_sigset_t
*mask
,
129 ThreadState
* tst
= VG_(get_ThreadState
)(tid
);
130 Int sigNo
= siginfo
->si_signo
;
131 struct vg_sig_private
*priv
;
132 /* Stack must be 16-byte aligned */
133 sp_top_of_frame
&= ~0xf;
135 sp
= sp_top_of_frame
- sizeof(struct rt_sigframe
);
137 tst
= VG_(get_ThreadState
)(tid
);
138 if (! ML_(sf_maybe_extend_stack
)(tst
, sp
, sp_top_of_frame
- sp
, flags
))
141 sp
= VG_ROUNDDN(sp
, 16);
143 struct rt_sigframe
*frame
= (struct rt_sigframe
*)sp
;
144 struct vki_ucontext
*ucp
= &frame
->rs_uc
;
145 if (VG_(clo_trace_signals
))
146 VG_(printf
)("rt_sigframe\n");
147 /* Create siginfo. */
148 VG_TRACK(pre_mem_write
, Vg_CoreSignal
, tid
, "signal frame siginfo",
149 (Addr
)&frame
->rs_info
, sizeof(frame
->rs_info
));
151 VG_(memcpy
)(&frame
->rs_info
, siginfo
, sizeof(*siginfo
));
153 VG_TRACK(post_mem_write
, Vg_CoreSignal
, tid
,
154 (Addr
)&frame
->rs_info
, sizeof(frame
->rs_info
));
156 /* Create the ucontext. */
157 VG_TRACK(pre_mem_write
, Vg_CoreSignal
, tid
, "signal frame ucontext",
158 (Addr
)ucp
, offsetof(struct vki_ucontext
, uc_mcontext
));
162 ucp
->uc_stack
= tst
->altstack
;
164 VG_TRACK(post_mem_write
, Vg_CoreSignal
, tid
, (Addr
)ucp
,
165 offsetof(struct vki_ucontext
, uc_mcontext
));
167 struct vki_sigcontext
*scp
= &(frame
->rs_uc
.uc_mcontext
);
168 setup_sigcontext(tst
, &(scp
), siginfo
);
169 ucp
->uc_sigmask
= tst
->sig_mask
;
172 /* Arguments to signal handler:
175 a1 = 0 (should be cause)
176 a2 = pointer to ucontext
178 $25 and c0_epc point to the signal handler, $29 points to
179 the struct rt_sigframe. */
181 tst
->arch
.vex
.guest_r4
= siginfo
->si_signo
;
182 tst
->arch
.vex
.guest_r5
= (Addr
) &frame
->rs_info
;
183 tst
->arch
.vex
.guest_r6
= (Addr
) &frame
->rs_uc
;
184 tst
->arch
.vex
.guest_r29
= (Addr
) frame
;
185 tst
->arch
.vex
.guest_r25
= (Addr
) handler
;
187 if (flags
& VKI_SA_RESTORER
)
188 tst
->arch
.vex
.guest_r31
= (Addr
) restorer
;
190 tst
->arch
.vex
.guest_r31
= (Addr
)&VG_(mips64_linux_SUBST_FOR_rt_sigreturn
);
192 priv
->magicPI
= 0x31415927;
193 priv
->sigNo_private
= sigNo
;
194 priv
->vex_shadow1
= tst
->arch
.vex_shadow1
;
195 priv
->vex_shadow2
= tst
->arch
.vex_shadow2
;
196 /* Set the thread so it will next run the handler. */
197 VG_TRACK( post_reg_write
, Vg_CoreSignal
, tid
, VG_O_STACK_PTR
, sizeof(Addr
));
198 if (VG_(clo_trace_signals
))
199 VG_(printf
)("handler = %p\n", handler
);
200 tst
->arch
.vex
.guest_PC
= (Addr
) handler
;
201 /* This thread needs to be marked runnable, but we leave that
206 void VG_(sigframe_destroy
) ( ThreadId tid
, Bool isRT
)
209 struct vg_sig_private
*priv1
;
212 struct vki_sigcontext
*mc
;
215 vg_assert(VG_(is_valid_tid
)(tid
));
216 tst
= VG_(get_ThreadState
)(tid
);
217 sp
= tst
->arch
.vex
.guest_r29
;
218 struct rt_sigframe
*frame
= (struct rt_sigframe
*)sp
;
219 struct vki_ucontext
*ucp
= &frame
->rs_uc
;
220 frame_size
= sizeof(*frame
);
221 mc
= &ucp
->uc_mcontext
;
222 tst
->sig_mask
= ucp
->uc_sigmask
;
223 tst
->tmp_sig_mask
= ucp
->uc_sigmask
;
224 priv1
= &frame
->priv
;
225 sigNo
= priv1
->sigNo_private
;
226 vg_assert(priv1
->magicPI
== 0x31415927);
228 tst
->arch
.vex
.guest_r1
= mc
->sc_regs
[1];
229 tst
->arch
.vex
.guest_r2
= mc
->sc_regs
[2];
230 tst
->arch
.vex
.guest_r3
= mc
->sc_regs
[3];
231 tst
->arch
.vex
.guest_r4
= mc
->sc_regs
[4];
232 tst
->arch
.vex
.guest_r5
= mc
->sc_regs
[5];
233 tst
->arch
.vex
.guest_r6
= mc
->sc_regs
[6];
234 tst
->arch
.vex
.guest_r7
= mc
->sc_regs
[7];
235 tst
->arch
.vex
.guest_r8
= mc
->sc_regs
[8];
236 tst
->arch
.vex
.guest_r9
= mc
->sc_regs
[9];
237 tst
->arch
.vex
.guest_r10
= mc
->sc_regs
[10];
238 tst
->arch
.vex
.guest_r11
= mc
->sc_regs
[11];
239 tst
->arch
.vex
.guest_r12
= mc
->sc_regs
[12];
240 tst
->arch
.vex
.guest_r13
= mc
->sc_regs
[13];
241 tst
->arch
.vex
.guest_r14
= mc
->sc_regs
[14];
242 tst
->arch
.vex
.guest_r15
= mc
->sc_regs
[15];
243 tst
->arch
.vex
.guest_r16
= mc
->sc_regs
[16];
244 tst
->arch
.vex
.guest_r17
= mc
->sc_regs
[17];
245 tst
->arch
.vex
.guest_r18
= mc
->sc_regs
[18];
246 tst
->arch
.vex
.guest_r19
= mc
->sc_regs
[19];
247 tst
->arch
.vex
.guest_r20
= mc
->sc_regs
[20];
248 tst
->arch
.vex
.guest_r21
= mc
->sc_regs
[21];
249 tst
->arch
.vex
.guest_r22
= mc
->sc_regs
[22];
250 tst
->arch
.vex
.guest_r23
= mc
->sc_regs
[23];
251 tst
->arch
.vex
.guest_r24
= mc
->sc_regs
[24];
252 tst
->arch
.vex
.guest_r25
= mc
->sc_regs
[25];
253 tst
->arch
.vex
.guest_r26
= mc
->sc_regs
[26];
254 tst
->arch
.vex
.guest_r27
= mc
->sc_regs
[27];
255 tst
->arch
.vex
.guest_r28
= mc
->sc_regs
[28];
256 tst
->arch
.vex
.guest_r30
= mc
->sc_regs
[30];
257 tst
->arch
.vex
.guest_PC
= mc
->sc_pc
;
258 tst
->arch
.vex
.guest_r31
= mc
->sc_regs
[31];
259 tst
->arch
.vex
.guest_r29
= mc
->sc_regs
[29];
261 tst
->arch
.vex
.guest_HI
= mc
->sc_mdhi
;
262 tst
->arch
.vex
.guest_LO
= mc
->sc_mdlo
;
263 tst
->arch
.vex_shadow1
= priv1
->vex_shadow1
;
264 tst
->arch
.vex_shadow2
= priv1
->vex_shadow2
;
266 VG_TRACK(die_mem_stack_signal
, sp
, frame_size
);
267 if (VG_(clo_trace_signals
))
268 VG_(message
)(Vg_DebugMsg
,
269 "VG_(signal_return) (thread %u): isRT=%d valid magic; EIP=%#llx\n",
270 tid
, isRT
, tst
->arch
.vex
.guest_PC
);
272 VG_TRACK( post_deliver_signal
, tid
, sigNo
);
275 #endif /* defined(VGP_mips64_linux) */
277 /*--------------------------------------------------------------------*/
278 /*--- end sigframe-mips64-linux.c ---*/
279 /*--------------------------------------------------------------------*/