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 50struct vg_sig_private { 51 UInt magicPI; 52 UInt sigNo_private; 53 VexGuestMIPS64State vex_shadow1; 54 VexGuestMIPS64State vex_shadow2; 55}; 56 57struct 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 65struct 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 74static 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 */ 118void 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 */ 206void 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