ms-manual.xml: Put stray ':' inside para.
[valgrind.git] / coregrind / m_sigframe / sigframe-mips64-linux.c
blobbab6bb00dbd1d6d776a7c68119a1fd9c716e5d76
2 /*--------------------------------------------------------------------*/
3 /*--- Create/destroy signal delivery frames. ---*/
4 /*--- sigframe-mips64-linux.c ---*/
5 /*--------------------------------------------------------------------*/
7 /*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
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 {
49 UInt magicPI;
50 UInt sigNo_private;
51 VexGuestMIPS64State vex_shadow1;
52 VexGuestMIPS64State vex_shadow2;
55 struct sigframe {
56 UInt sf_ass[4]; /* argument save space for o32 */
57 UInt sf_pad[2]; /* Was: signal trampoline */
58 struct vki_sigcontext sf_sc;
59 vki_sigset_t sf_mask;
60 struct vg_sig_private priv;
63 struct rt_sigframe {
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;
115 /* EXPORTED */
116 void VG_(sigframe_create) ( ThreadId tid,
117 Bool on_altstack,
118 Addr sp_top_of_frame,
119 const vki_siginfo_t *siginfo,
120 const struct vki_ucontext *siguc,
121 void *handler,
122 UInt flags,
123 const vki_sigset_t *mask,
124 void *restorer )
126 Addr sp;
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))
137 return;
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));
158 ucp->uc_flags = 0;
159 ucp->uc_link = 0;
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;
168 priv = &frame->priv;
170 /* Arguments to signal handler:
172 a0 = signal number
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;
187 else
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
200 the caller to do. */
203 /* EXPORTED */
204 void VG_(sigframe_destroy) ( ThreadId tid, Bool isRT )
206 ThreadState *tst;
207 struct vg_sig_private *priv1;
208 Addr sp;
209 UInt frame_size;
210 struct vki_sigcontext *mc;
211 Int sigNo;
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);
225 /* restore regs */
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);
269 /* tell the tools */
270 VG_TRACK( post_deliver_signal, tid, sigNo );
273 #endif /* defined(VGP_mips64_linux) */
275 /*--------------------------------------------------------------------*/
276 /*--- end sigframe-mips64-linux.c ---*/
277 /*--------------------------------------------------------------------*/