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