1 2/*--------------------------------------------------------------------*/ 3/*--- Create/destroy signal delivery frames. ---*/ 4/*--- sigframe-mips32-linux.c ---*/ 5/*--------------------------------------------------------------------*/ 6 7/* 8 This file is part of Valgrind, a dynamic binary instrumentation 9 framework. 10 11 Copyright (C) 2010-2013 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_mips32_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 50struct vg_sig_private 51{ 52 UInt magicPI; 53 UInt sigNo_private; 54 VexGuestMIPS32State vex_shadow1; 55 VexGuestMIPS32State vex_shadow2; 56}; 57 58struct sigframe 59{ 60 UInt sf_ass[4]; /* argument save space for o32 */ 61 UInt sf_pad[2]; /* Was: signal trampoline */ 62 struct vki_sigcontext sf_sc; 63 vki_sigset_t sf_mask; 64 struct vg_sig_private priv; 65}; 66 67struct rt_sigframe 68{ 69 UInt rs_ass[4]; /* argument save space for o32 */ 70 UInt rs_pad[2]; /* Was: signal trampoline */ 71 vki_siginfo_t rs_info; 72 struct vki_ucontext rs_uc; 73 struct vg_sig_private priv; 74}; 75 76 77static 78void setup_sigcontext2 ( ThreadState* tst, struct vki_sigcontext **sc1, 79 const vki_siginfo_t *si) 80{ 81 82 struct vki_sigcontext *sc = *sc1; 83 84 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcontext", 85 (Addr)sc, sizeof(unsigned long long)*34 ); 86 sc->sc_regs[1] = tst->arch.vex.guest_r1; 87 sc->sc_regs[2] = tst->arch.vex.guest_r2; 88 sc->sc_regs[3] = tst->arch.vex.guest_r3; 89 sc->sc_regs[4] = tst->arch.vex.guest_r4; 90 sc->sc_regs[5] = tst->arch.vex.guest_r5; 91 sc->sc_regs[6] = tst->arch.vex.guest_r6; 92 sc->sc_regs[7] = tst->arch.vex.guest_r7; 93 sc->sc_regs[8] = tst->arch.vex.guest_r8; 94 sc->sc_regs[9] = tst->arch.vex.guest_r9; 95 sc->sc_regs[10] = tst->arch.vex.guest_r10; 96 sc->sc_regs[11] = tst->arch.vex.guest_r11; 97 sc->sc_regs[12] = tst->arch.vex.guest_r12; 98 sc->sc_regs[13] = tst->arch.vex.guest_r13; 99 sc->sc_regs[14] = tst->arch.vex.guest_r14; 100 sc->sc_regs[15] = tst->arch.vex.guest_r15; 101 sc->sc_regs[16] = tst->arch.vex.guest_r16; 102 sc->sc_regs[17] = tst->arch.vex.guest_r17; 103 sc->sc_regs[18] = tst->arch.vex.guest_r18; 104 sc->sc_regs[19] = tst->arch.vex.guest_r19; 105 sc->sc_regs[20] = tst->arch.vex.guest_r20; 106 sc->sc_regs[21] = tst->arch.vex.guest_r21; 107 sc->sc_regs[22] = tst->arch.vex.guest_r22; 108 sc->sc_regs[23] = tst->arch.vex.guest_r23; 109 sc->sc_regs[24] = tst->arch.vex.guest_r24; 110 sc->sc_regs[25] = tst->arch.vex.guest_r25; 111 sc->sc_regs[26] = tst->arch.vex.guest_r26; 112 sc->sc_regs[27] = tst->arch.vex.guest_r27; 113 sc->sc_regs[28] = tst->arch.vex.guest_r28; 114 sc->sc_regs[29] = tst->arch.vex.guest_r29; 115 sc->sc_regs[30] = tst->arch.vex.guest_r30; 116 sc->sc_regs[31] = tst->arch.vex.guest_r31; 117 sc->sc_pc = tst->arch.vex.guest_PC; 118 sc->sc_mdhi = tst->arch.vex.guest_HI; 119 sc->sc_mdlo = tst->arch.vex.guest_LO; 120} 121 122/* EXPORTED */ 123void VG_(sigframe_create)( ThreadId tid, 124 Addr sp_top_of_frame, 125 const vki_siginfo_t *siginfo, 126 const struct vki_ucontext *siguc, 127 void *handler, 128 UInt flags, 129 const vki_sigset_t *mask, 130 void *restorer ) 131{ 132 Addr sp; 133 ThreadState* tst = VG_(get_ThreadState)(tid); 134 Int sigNo = siginfo->si_signo; 135 struct vg_sig_private *priv; 136 137 /* Stack must be 8-byte aligned */ 138 sp_top_of_frame &= ~0xf; 139 140 if (flags & VKI_SA_SIGINFO) 141 { 142 sp = sp_top_of_frame - sizeof(struct rt_sigframe); 143 } 144 else 145 { 146 sp = sp_top_of_frame - sizeof(struct sigframe); 147 } 148 149 tst = VG_(get_ThreadState)(tid); 150 if (! ML_(sf_maybe_extend_stack)(tst, sp, sp_top_of_frame - sp, flags)) 151 return; 152 153 vg_assert(VG_IS_8_ALIGNED(sp)); 154 155 if (flags & VKI_SA_SIGINFO) 156 { 157 struct rt_sigframe *frame = (struct rt_sigframe *) sp; 158 struct vki_ucontext *ucp = &frame->rs_uc; 159 if (VG_(clo_trace_signals)) 160 VG_(printf)("rt_sigframe\n"); 161 /* Create siginfo. */ 162 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame siginfo", 163 (Addr)&frame->rs_info, sizeof(frame->rs_info) ); 164 165 VG_(memcpy)(&frame->rs_info, siginfo, sizeof(*siginfo)); 166 167 VG_TRACK( post_mem_write, Vg_CoreSignal, tid, 168 (Addr)&frame->rs_info, sizeof(frame->rs_info) ); 169 170 /* Create the ucontext. */ 171 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext", 172 (Addr)ucp, offsetof(struct vki_ucontext, uc_mcontext) ); 173 174 ucp->uc_flags = 0; 175 ucp->uc_link = 0; 176 ucp->uc_stack = tst->altstack; 177 178 VG_TRACK( post_mem_write, Vg_CoreSignal, tid, (Addr)ucp, 179 offsetof(struct vki_ucontext, uc_mcontext) ); 180 181 struct vki_sigcontext *scp = &(frame->rs_uc.uc_mcontext); 182 setup_sigcontext2(tst, &(scp), siginfo); 183 184 ucp->uc_sigmask = tst->sig_mask; 185 186 priv = &frame->priv; 187 188 /* 189 * Arguments to signal handler: 190 * 191 * a0 = signal number 192 * a1 = 0 (should be cause) 193 * a2 = pointer to ucontext 194 * 195 * $25 and c0_epc point to the signal handler, $29 points to 196 * the struct rt_sigframe. 197 */ 198 199 tst->arch.vex.guest_r4 = siginfo->si_signo; 200 tst->arch.vex.guest_r5 = (Addr) &frame->rs_info; 201 tst->arch.vex.guest_r6 = (Addr) &frame->rs_uc; 202 tst->arch.vex.guest_r29 = (Addr) frame; 203 tst->arch.vex.guest_r25 = (Addr) handler; 204 205 if (flags & VKI_SA_RESTORER) 206 { 207 tst->arch.vex.guest_r31 = (Addr) restorer; 208 } 209 else 210 { 211 tst->arch.vex.guest_r31 = (Addr)&VG_(mips32_linux_SUBST_FOR_rt_sigreturn); 212 } 213 214 } 215 else 216 { 217 if (VG_(clo_trace_signals)) 218 VG_(printf)("sigframe\n"); 219 struct sigframe *frame = (struct sigframe *) sp; 220 struct vki_sigcontext *scp = &(frame->sf_sc); 221 setup_sigcontext2(tst, &(scp), siginfo); 222 frame->sf_mask = tst->sig_mask; 223 priv = &frame->priv; 224 /* 225 * Arguments to signal handler: 226 * 227 * a0 = signal number 228 * a1 = 0 (should be cause) 229 * a2 = pointer to struct sigcontext 230 * 231 * $25 and c0_epc point to the signal handler, $29 points to the 232 * struct sigframe. 233 */ 234 tst->arch.vex.guest_r4 = siginfo->si_signo; 235 tst->arch.vex.guest_r5 = 0; 236 tst->arch.vex.guest_r6 = (Addr) &frame->sf_sc; 237 tst->arch.vex.guest_r29 = (Addr) frame; 238 tst->arch.vex.guest_r25 = (Addr) handler; 239 240 if (flags & VKI_SA_RESTORER) 241 { 242 tst->arch.vex.guest_r31 = (Addr) restorer; 243 } 244 else 245 { 246 tst->arch.vex.guest_r31 = (Addr)&VG_(mips32_linux_SUBST_FOR_sigreturn); 247 } 248 } 249 250 priv->magicPI = 0x31415927; 251 priv->sigNo_private = sigNo; 252 priv->vex_shadow1 = tst->arch.vex_shadow1; 253 priv->vex_shadow2 = tst->arch.vex_shadow2; 254 /* Set the thread so it will next run the handler. */ 255 /* tst->m_sp = sp; also notify the tool we've updated SP */ 256 VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr)); 257 if (VG_(clo_trace_signals)) 258 VG_(printf)("handler = %p\n", handler); 259 tst->arch.vex.guest_PC = (Addr) handler; 260 /* This thread needs to be marked runnable, but we leave that the 261 caller to do. */ 262} 263 264/* EXPORTED */ 265void VG_(sigframe_destroy)( ThreadId tid, Bool isRT ) 266{ 267 ThreadState *tst; 268 struct vg_sig_private *priv1; 269 Addr sp; 270 UInt frame_size; 271 struct vki_sigcontext *mc; 272 Int sigNo; 273 Bool has_siginfo = isRT; 274 275 vg_assert(VG_(is_valid_tid)(tid)); 276 tst = VG_(get_ThreadState)(tid); 277 sp = tst->arch.vex.guest_r29; 278 if (has_siginfo) 279 { 280 struct rt_sigframe *frame = (struct rt_sigframe *)sp; 281 struct vki_ucontext *ucp = &frame->rs_uc; 282 frame_size = sizeof(*frame); 283 mc = &ucp->uc_mcontext; 284 priv1 = &frame->priv; 285 vg_assert(priv1->magicPI == 0x31415927); 286 sigNo = priv1->sigNo_private; 287 } 288 else 289 { 290 struct sigframe *frame = (struct sigframe *)sp; 291 frame_size = sizeof(*frame); 292 mc = &(frame->sf_sc); 293 priv1 = &frame->priv; 294 vg_assert(priv1->magicPI == 0x31415927); 295 tst->sig_mask = frame->sf_mask; 296 tst->tmp_sig_mask = tst->sig_mask; 297 sigNo = priv1->sigNo_private; 298 } 299 //restore regs 300 tst->arch.vex.guest_r1 = mc->sc_regs[1]; 301 tst->arch.vex.guest_r2 = mc->sc_regs[2]; 302 tst->arch.vex.guest_r3 = mc->sc_regs[3]; 303 tst->arch.vex.guest_r4 = mc->sc_regs[4]; 304 tst->arch.vex.guest_r5 = mc->sc_regs[5]; 305 tst->arch.vex.guest_r6 = mc->sc_regs[6]; 306 tst->arch.vex.guest_r7 = mc->sc_regs[7]; 307 tst->arch.vex.guest_r8 = mc->sc_regs[8]; 308 tst->arch.vex.guest_r9 = mc->sc_regs[9]; 309 tst->arch.vex.guest_r10 = mc->sc_regs[10]; 310 tst->arch.vex.guest_r11 = mc->sc_regs[11]; 311 tst->arch.vex.guest_r12 = mc->sc_regs[12]; 312 tst->arch.vex.guest_r13= mc->sc_regs[13]; 313 tst->arch.vex.guest_r14 = mc->sc_regs[14]; 314 tst->arch.vex.guest_r15 = mc->sc_regs[15]; 315 tst->arch.vex.guest_r16 = mc->sc_regs[16]; 316 tst->arch.vex.guest_r17 = mc->sc_regs[17]; 317 tst->arch.vex.guest_r18 = mc->sc_regs[18]; 318 tst->arch.vex.guest_r19 = mc->sc_regs[19]; 319 tst->arch.vex.guest_r20 = mc->sc_regs[20]; 320 tst->arch.vex.guest_r21 = mc->sc_regs[21]; 321 tst->arch.vex.guest_r22 = mc->sc_regs[22]; 322 tst->arch.vex.guest_r23 = mc->sc_regs[23]; 323 tst->arch.vex.guest_r24 = mc->sc_regs[24]; 324 tst->arch.vex.guest_r25 = mc->sc_regs[25]; 325 tst->arch.vex.guest_r26 = mc->sc_regs[26]; 326 tst->arch.vex.guest_r27 = mc->sc_regs[27]; 327 tst->arch.vex.guest_r28 = mc->sc_regs[28]; 328 tst->arch.vex.guest_r30 = mc->sc_regs[30]; 329 tst->arch.vex.guest_PC = mc->sc_pc; 330 tst->arch.vex.guest_r31 = mc->sc_regs[31]; 331 tst->arch.vex.guest_r29 = mc->sc_regs[29]; 332 333 tst->arch.vex.guest_HI = mc->sc_mdhi; 334 tst->arch.vex.guest_LO = mc->sc_mdlo; 335 tst->arch.vex_shadow1 = priv1->vex_shadow1; 336 tst->arch.vex_shadow2 = priv1->vex_shadow2; 337 338 VG_TRACK(die_mem_stack_signal, sp, frame_size); 339 if (VG_(clo_trace_signals)) 340 VG_(message)( Vg_DebugMsg, 341 "VG_(signal_return) (thread %d): isRT=%d valid magic; EIP=%#x\n", 342 tid, isRT, tst->arch.vex.guest_PC); 343 /* tell the tools */ 344 VG_TRACK( post_deliver_signal, tid, sigNo ); 345} 346 347#endif // defined(VGP_mips32_linux) 348 349/*--------------------------------------------------------------------*/ 350/*--- end sigframe-mips32-linux.c ---*/ 351/*--------------------------------------------------------------------*/ 352