• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*--------------------------------------------------------------------*/
3 /*--- Create/destroy signal delivery frames.                       ---*/
4 /*---                                  sigframe-mips64-linux.c     ---*/
5 /*--------------------------------------------------------------------*/
6 
7 /*
8    This file is part of Valgrind, a dynamic binary instrumentation
9    framework.
10 
11    Copyright (C) 2010-2015 RT-RK
12       mips-valgrind@rt-rk.com
13 
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.
18 
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.
23 
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
27    02111-1307, USA.
28 
29    The GNU General Public License is contained in the file COPYING.
30 */
31 
32 #if defined(VGP_mips64_linux)
33 
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"
49 
50 struct vg_sig_private {
51    UInt magicPI;
52    UInt sigNo_private;
53    VexGuestMIPS64State vex_shadow1;
54    VexGuestMIPS64State vex_shadow2;
55 };
56 
57 struct sigframe {
58    UInt sf_ass[4];  /* argument save space for o32 */
59    UInt sf_pad[2];  /* Was: signal trampoline */
60    struct vki_sigcontext sf_sc;
61    vki_sigset_t sf_mask;
62    struct vg_sig_private priv;
63 };
64 
65 struct rt_sigframe {
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;
71 };
72 
73 
setup_sigcontext(ThreadState * tst,struct vki_sigcontext ** sc1,const vki_siginfo_t * si)74 static void setup_sigcontext ( ThreadState* tst, struct vki_sigcontext **sc1,
75                                const vki_siginfo_t *si)
76 {
77    struct vki_sigcontext *sc = *sc1;
78 
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;
115 }
116 
117 /* EXPORTED */
VG_(sigframe_create)118 void VG_(sigframe_create) ( ThreadId tid,
119                             Bool on_altstack,
120                             Addr sp_top_of_frame,
121                             const vki_siginfo_t *siginfo,
122                             const struct vki_ucontext *siguc,
123                             void *handler,
124                             UInt flags,
125                             const vki_sigset_t *mask,
126                             void *restorer )
127 {
128    Addr sp;
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;
134 
135    sp = sp_top_of_frame - sizeof(struct rt_sigframe);
136 
137    tst = VG_(get_ThreadState)(tid);
138    if (! ML_(sf_maybe_extend_stack)(tst, sp, sp_top_of_frame - sp, flags))
139       return;
140 
141    sp = VG_ROUNDDN(sp, 16);
142 
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));
150 
151    VG_(memcpy)(&frame->rs_info, siginfo, sizeof(*siginfo));
152 
153    VG_TRACK(post_mem_write, Vg_CoreSignal, tid,
154             (Addr)&frame->rs_info, sizeof(frame->rs_info));
155 
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));
159 
160    ucp->uc_flags = 0;
161    ucp->uc_link = 0;
162    ucp->uc_stack = tst->altstack;
163 
164    VG_TRACK(post_mem_write, Vg_CoreSignal, tid, (Addr)ucp,
165             offsetof(struct vki_ucontext, uc_mcontext));
166 
167    struct vki_sigcontext *scp = &(frame->rs_uc.uc_mcontext);
168    setup_sigcontext(tst, &(scp), siginfo);
169    ucp->uc_sigmask = tst->sig_mask;
170    priv = &frame->priv;
171 
172    /* Arguments to signal handler:
173 
174       a0 = signal number
175       a1 = 0 (should be cause)
176       a2 = pointer to ucontext
177 
178       $25 and c0_epc point to the signal handler, $29 points to
179       the struct rt_sigframe. */
180 
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;
186 
187    if (flags & VKI_SA_RESTORER)
188       tst->arch.vex.guest_r31 = (Addr) restorer;
189    else
190       tst->arch.vex.guest_r31 = (Addr)&VG_(mips64_linux_SUBST_FOR_rt_sigreturn);
191 
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
202       the caller to do. */
203 }
204 
205 /* EXPORTED */
VG_(sigframe_destroy)206 void VG_(sigframe_destroy) ( ThreadId tid, Bool isRT )
207 {
208    ThreadState *tst;
209    struct vg_sig_private *priv1;
210    Addr sp;
211    UInt frame_size;
212    struct vki_sigcontext *mc;
213    Int sigNo;
214 
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);
227    /* restore regs */
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];
260 
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;
265 
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);
271    /* tell the tools */
272    VG_TRACK( post_deliver_signal, tid, sigNo );
273 }
274 
275 #endif /* defined(VGP_mips64_linux) */
276 
277 /*--------------------------------------------------------------------*/
278 /*--- end                                  sigframe-mips64-linux.c ---*/
279 /*--------------------------------------------------------------------*/
280