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-2012 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_libcsetjmp.h" // to keep _threadstate.h happy 38#include "pub_core_threadstate.h" 39#include "pub_core_aspacemgr.h" 40#include "pub_core_libcbase.h" 41#include "pub_core_libcassert.h" 42#include "pub_core_libcprint.h" 43#include "pub_core_machine.h" 44#include "pub_core_options.h" 45#include "pub_core_sigframe.h" 46#include "pub_core_signals.h" 47#include "pub_core_tooliface.h" 48#include "pub_core_trampoline.h" 49#include "pub_core_transtab.h" // VG_(discard_translations) 50 51struct vg_sig_private 52{ 53 UInt magicPI; 54 UInt sigNo_private; 55 VexGuestMIPS32State vex_shadow1; 56 VexGuestMIPS32State vex_shadow2; 57}; 58 59struct sigframe 60{ 61 UInt sf_ass[4]; /* argument save space for o32 */ 62 UInt sf_pad[2]; /* Was: signal trampoline */ 63 struct vki_sigcontext sf_sc; 64 vki_sigset_t sf_mask; 65 struct vg_sig_private priv; 66}; 67 68struct rt_sigframe 69{ 70 UInt rs_ass[4]; /* argument save space for o32 */ 71 UInt rs_pad[2]; /* Was: signal trampoline */ 72 vki_siginfo_t rs_info; 73 struct vki_ucontext rs_uc; 74 struct vg_sig_private priv; 75}; 76 77/* Extend the stack segment downwards if needed so as to ensure the 78 new signal frames are mapped to something. Return a Bool 79 indicating whether or not the operation was successful. 80*/ 81static Bool extend ( ThreadState *tst, Addr addr, SizeT size ) 82{ 83 ThreadId tid = tst->tid; 84 NSegment const* stackseg = NULL; 85 86 if (VG_(extend_stack)(addr, tst->client_stack_szB)) 87 { 88 stackseg = VG_(am_find_nsegment)(addr); 89 } 90 91 if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) 92 { 93 VG_(message)(Vg_UserMsg, 94 "Can't extend stack to %#lx during signal delivery for thread %d:\n", 95 addr, tid ); 96 if (stackseg == NULL) 97 VG_(message)( Vg_UserMsg, " no stack segment\n" ); 98 else 99 VG_(message)( Vg_UserMsg, " too small or bad protection modes\n" ); 100 101 /* set SIGSEGV to default handler */ 102 VG_(set_default_handler)( VKI_SIGSEGV ); 103 VG_(synth_fault_mapping)( tid, addr ); 104 105 /* The whole process should be about to die, since the default 106 action of SIGSEGV to kill the whole process. */ 107 return False; 108 } 109 110 /* For tracking memory events, indicate the entire frame has been 111 allocated. */ 112 VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB, 113 size + VG_STACK_REDZONE_SZB, tid ); 114 115 return True; 116} 117 118static 119void setup_sigcontext2 ( ThreadState* tst, struct vki_sigcontext **sc1, const vki_siginfo_t *si) 120{ 121 122 struct vki_sigcontext *sc = *sc1; 123 124 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcontext", 125 (Addr)sc, sizeof(unsigned long long)*34 ); 126 sc->sc_regs[1] = tst->arch.vex.guest_r1; 127 sc->sc_regs[2] = tst->arch.vex.guest_r2; 128 sc->sc_regs[3] = tst->arch.vex.guest_r3; 129 sc->sc_regs[4] = tst->arch.vex.guest_r4; 130 sc->sc_regs[5] = tst->arch.vex.guest_r5; 131 sc->sc_regs[6] = tst->arch.vex.guest_r6; 132 sc->sc_regs[7] = tst->arch.vex.guest_r7; 133 sc->sc_regs[8] = tst->arch.vex.guest_r8; 134 sc->sc_regs[9] = tst->arch.vex.guest_r9; 135 sc->sc_regs[10] = tst->arch.vex.guest_r10; 136 sc->sc_regs[11] = tst->arch.vex.guest_r11; 137 sc->sc_regs[12] = tst->arch.vex.guest_r12; 138 sc->sc_regs[13] = tst->arch.vex.guest_r13; 139 sc->sc_regs[14] = tst->arch.vex.guest_r14; 140 sc->sc_regs[15] = tst->arch.vex.guest_r15; 141 sc->sc_regs[16] = tst->arch.vex.guest_r16; 142 sc->sc_regs[17] = tst->arch.vex.guest_r17; 143 sc->sc_regs[18] = tst->arch.vex.guest_r18; 144 sc->sc_regs[19] = tst->arch.vex.guest_r19; 145 sc->sc_regs[20] = tst->arch.vex.guest_r20; 146 sc->sc_regs[21] = tst->arch.vex.guest_r21; 147 sc->sc_regs[22] = tst->arch.vex.guest_r22; 148 sc->sc_regs[23] = tst->arch.vex.guest_r23; 149 sc->sc_regs[24] = tst->arch.vex.guest_r24; 150 sc->sc_regs[25] = tst->arch.vex.guest_r25; 151 sc->sc_regs[26] = tst->arch.vex.guest_r26; 152 sc->sc_regs[27] = tst->arch.vex.guest_r27; 153 sc->sc_regs[28] = tst->arch.vex.guest_r28; 154 sc->sc_regs[29] = tst->arch.vex.guest_r29; 155 sc->sc_regs[30] = tst->arch.vex.guest_r30; 156 sc->sc_regs[31] = tst->arch.vex.guest_r31; 157 sc->sc_pc = tst->arch.vex.guest_PC; 158 sc->sc_mdhi = tst->arch.vex.guest_HI; 159 sc->sc_mdlo = tst->arch.vex.guest_LO; 160} 161 162/* EXPORTED */ 163void VG_(sigframe_create)( ThreadId tid, 164 Addr sp_top_of_frame, 165 const vki_siginfo_t *siginfo, 166 const struct vki_ucontext *siguc, 167 void *handler, 168 UInt flags, 169 const vki_sigset_t *mask, 170 void *restorer ) 171{ 172 Addr sp; 173 ThreadState* tst = VG_(get_ThreadState)(tid); 174 Addr faultaddr; 175 Int sigNo = siginfo->si_signo; 176 struct vg_sig_private *priv; 177 178 /* Stack must be 8-byte aligned */ 179 sp_top_of_frame &= ~0xf; 180 181 if (flags & VKI_SA_SIGINFO) 182 { 183 sp = sp_top_of_frame - sizeof(struct rt_sigframe); 184 } 185 else 186 { 187 sp = sp_top_of_frame - sizeof(struct sigframe); 188 } 189 190 tst = VG_(get_ThreadState)(tid); 191 if (!extend(tst, sp, sp_top_of_frame - sp)) 192 return; 193 194 vg_assert(VG_IS_8_ALIGNED(sp)); 195 196 /* SIGILL defines addr to be the faulting address */ 197 198 faultaddr = (Addr)siginfo->_sifields._sigfault._addr; 199 if (sigNo == VKI_SIGILL && siginfo->si_code > 0) 200 faultaddr = tst->arch.vex.guest_PC; 201 202 if (flags & VKI_SA_SIGINFO) 203 { 204 struct rt_sigframe *frame = (struct rt_sigframe *) sp; 205 struct vki_ucontext *ucp = &frame->rs_uc; 206 if (VG_(clo_trace_signals)) 207 VG_(printf)("rt_sigframe\n"); 208 /* Create siginfo. */ 209 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame siginfo", 210 (Addr)&frame->rs_info, sizeof(frame->rs_info) ); 211 212 VG_(memcpy)(&frame->rs_info, siginfo, sizeof(*siginfo)); 213 214 VG_TRACK( post_mem_write, Vg_CoreSignal, tid, 215 (Addr)&frame->rs_info, sizeof(frame->rs_info) ); 216 217 /* Create the ucontext. */ 218 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext", 219 (Addr)ucp, offsetof(struct vki_ucontext, uc_mcontext) ); 220 221 ucp->uc_flags = 0; 222 ucp->uc_link = 0; 223 ucp->uc_stack = tst->altstack; 224 225 VG_TRACK( post_mem_write, Vg_CoreSignal, tid, (Addr)ucp, 226 offsetof(struct vki_ucontext, uc_mcontext) ); 227 228 struct vki_sigcontext *scp = &(frame->rs_uc.uc_mcontext); 229 setup_sigcontext2(tst, &(scp), siginfo); 230 231 ucp->uc_sigmask = tst->sig_mask; 232 233 priv = &frame->priv; 234 235 /* 236 * Arguments to signal handler: 237 * 238 * a0 = signal number 239 * a1 = 0 (should be cause) 240 * a2 = pointer to ucontext 241 * 242 * $25 and c0_epc point to the signal handler, $29 points to 243 * the struct rt_sigframe. 244 */ 245 246 tst->arch.vex.guest_r4 = siginfo->si_signo; 247 tst->arch.vex.guest_r5 = (Addr) &frame->rs_info; 248 tst->arch.vex.guest_r6 = (Addr) &frame->rs_uc; 249 tst->arch.vex.guest_r29 = (Addr) frame; 250 tst->arch.vex.guest_r25 = (Addr) handler; 251 252 if (flags & VKI_SA_RESTORER) 253 { 254 tst->arch.vex.guest_r31 = (Addr) restorer; 255 } 256 else 257 { 258 tst->arch.vex.guest_r31 = (Addr)&VG_(mips32_linux_SUBST_FOR_rt_sigreturn); 259 } 260 261 } 262 else 263 { 264 if (VG_(clo_trace_signals)) 265 VG_(printf)("sigframe\n"); 266 struct sigframe *frame = (struct sigframe *) sp; 267 struct vki_sigcontext *scp = &(frame->sf_sc); 268 setup_sigcontext2(tst, &(scp), siginfo); 269 frame->sf_mask = tst->sig_mask; 270 priv = &frame->priv; 271 /* 272 * Arguments to signal handler: 273 * 274 * a0 = signal number 275 * a1 = 0 (should be cause) 276 * a2 = pointer to struct sigcontext 277 * 278 * $25 and c0_epc point to the signal handler, $29 points to the 279 * struct sigframe. 280 */ 281 tst->arch.vex.guest_r4 = siginfo->si_signo; 282 tst->arch.vex.guest_r5 = 0; 283 tst->arch.vex.guest_r6 = (Addr) &frame->sf_sc; 284 tst->arch.vex.guest_r29 = (Addr) frame; 285 tst->arch.vex.guest_r25 = (Addr) handler; 286 287 if (flags & VKI_SA_RESTORER) 288 { 289 tst->arch.vex.guest_r31 = (Addr) restorer; 290 } 291 else 292 { 293 tst->arch.vex.guest_r31 = (Addr)&VG_(mips32_linux_SUBST_FOR_sigreturn); 294 } 295 } 296 297 priv->magicPI = 0x31415927; 298 priv->sigNo_private = sigNo; 299 priv->vex_shadow1 = tst->arch.vex_shadow1; 300 priv->vex_shadow2 = tst->arch.vex_shadow2; 301 /* Set the thread so it will next run the handler. */ 302 /* tst->m_sp = sp; also notify the tool we've updated SP */ 303 VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr)); 304 if (VG_(clo_trace_signals)) 305 VG_(printf)("handler = %p\n", handler); 306 tst->arch.vex.guest_PC = (Addr) handler; 307 /* This thread needs to be marked runnable, but we leave that the 308 caller to do. */ 309} 310 311/* EXPORTED */ 312void VG_(sigframe_destroy)( ThreadId tid, Bool isRT ) 313{ 314 ThreadState *tst; 315 struct vg_sig_private *priv1; 316 Addr sp; 317 UInt frame_size; 318 struct vki_sigcontext *mc; 319 Int sigNo; 320 Bool has_siginfo = isRT; 321 322 vg_assert(VG_(is_valid_tid)(tid)); 323 tst = VG_(get_ThreadState)(tid); 324 sp = tst->arch.vex.guest_r29; 325 if (has_siginfo) 326 { 327 struct rt_sigframe *frame = (struct rt_sigframe *)sp; 328 struct vki_ucontext *ucp = &frame->rs_uc; 329 frame_size = sizeof(*frame); 330 mc = &ucp->uc_mcontext; 331 priv1 = &frame->priv; 332 vg_assert(priv1->magicPI == 0x31415927); 333 sigNo = priv1->sigNo_private; 334 } 335 else 336 { 337 struct sigframe *frame = (struct sigframe *)sp; 338 frame_size = sizeof(*frame); 339 mc = &(frame->sf_sc); 340 priv1 = &frame->priv; 341 vg_assert(priv1->magicPI == 0x31415927); 342 tst->sig_mask = frame->sf_mask; 343 tst->tmp_sig_mask = tst->sig_mask; 344 sigNo = priv1->sigNo_private; 345 } 346 //restore regs 347 tst->arch.vex.guest_r1 = mc->sc_regs[1]; 348 tst->arch.vex.guest_r2 = mc->sc_regs[2]; 349 tst->arch.vex.guest_r3 = mc->sc_regs[3]; 350 tst->arch.vex.guest_r4 = mc->sc_regs[4]; 351 tst->arch.vex.guest_r5 = mc->sc_regs[5]; 352 tst->arch.vex.guest_r6 = mc->sc_regs[6]; 353 tst->arch.vex.guest_r7 = mc->sc_regs[7]; 354 tst->arch.vex.guest_r8 = mc->sc_regs[8]; 355 tst->arch.vex.guest_r9 = mc->sc_regs[9]; 356 tst->arch.vex.guest_r10 = mc->sc_regs[10]; 357 tst->arch.vex.guest_r11 = mc->sc_regs[11]; 358 tst->arch.vex.guest_r12 = mc->sc_regs[12]; 359 tst->arch.vex.guest_r13= mc->sc_regs[13]; 360 tst->arch.vex.guest_r14 = mc->sc_regs[14]; 361 tst->arch.vex.guest_r15 = mc->sc_regs[15]; 362 tst->arch.vex.guest_r16 = mc->sc_regs[16]; 363 tst->arch.vex.guest_r17 = mc->sc_regs[17]; 364 tst->arch.vex.guest_r18 = mc->sc_regs[18]; 365 tst->arch.vex.guest_r19 = mc->sc_regs[19]; 366 tst->arch.vex.guest_r20 = mc->sc_regs[20]; 367 tst->arch.vex.guest_r21 = mc->sc_regs[21]; 368 tst->arch.vex.guest_r22 = mc->sc_regs[22]; 369 tst->arch.vex.guest_r23 = mc->sc_regs[23]; 370 tst->arch.vex.guest_r24 = mc->sc_regs[24]; 371 tst->arch.vex.guest_r25 = mc->sc_regs[25]; 372 tst->arch.vex.guest_r26 = mc->sc_regs[26]; 373 tst->arch.vex.guest_r27 = mc->sc_regs[27]; 374 tst->arch.vex.guest_r28 = mc->sc_regs[28]; 375 tst->arch.vex.guest_r30 = mc->sc_regs[30]; 376 tst->arch.vex.guest_PC = mc->sc_pc; 377 tst->arch.vex.guest_r31 = mc->sc_regs[31]; 378 tst->arch.vex.guest_r29 = mc->sc_regs[29]; 379 380 tst->arch.vex.guest_HI = mc->sc_mdhi; 381 tst->arch.vex.guest_LO = mc->sc_mdlo; 382 tst->arch.vex_shadow1 = priv1->vex_shadow1; 383 tst->arch.vex_shadow2 = priv1->vex_shadow2; 384 385 VG_TRACK(die_mem_stack_signal, sp, frame_size); 386 if (VG_(clo_trace_signals)) 387 VG_(message)( Vg_DebugMsg, 388 "VG_(signal_return) (thread %d): isRT=%d valid magic; EIP=%#x\n", 389 tid, isRT, tst->arch.vex.guest_PC); 390 /* tell the tools */ 391 VG_TRACK( post_deliver_signal, tid, sigNo ); 392} 393 394#endif // defined(VGP_mips32_linux) 395 396/*--------------------------------------------------------------------*/ 397/*--- end sigframe-mips32-linux.c ---*/ 398/*--------------------------------------------------------------------*/ 399