1 2/*--------------------------------------------------------------------*/ 3/*--- Create/destroy signal delivery frames. ---*/ 4/*--- sigframe-tilegx-linux.c ---*/ 5/*--------------------------------------------------------------------*/ 6 7/* 8 This file is part of Valgrind, a dynamic binary instrumentation 9 framework. 10 11 Copyright (C) 2010-2013 Tilera Corp. 12 13 This program is free software; you can redistribute it and/or 14 modify it under the terms of the GNU General Public License as 15 published by the Free Software Foundation; either version 2 of the 16 License, or (at your option) any later version. 17 18 This program is distributed in the hope that it will be useful, but 19 WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 General Public License for more details. 22 23 You should have received a copy of the GNU General Public License 24 along with this program; if not, write to the Free Software 25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 26 02111-1307, USA. 27 28 The GNU General Public License is contained in the file COPYING. 29*/ 30 31/* Contributed by Zhi-Gang Liu <zliu at tilera dot com> */ 32 33#if defined(VGP_tilegx_linux) 34 35#include "pub_core_basics.h" 36#include "pub_core_vki.h" 37#include "pub_core_vkiscnums.h" 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 "priv_sigframe.h" 50 51struct vg_sig_private 52{ 53 UInt magicPI; 54 UInt sigNo_private; 55 VexGuestTILEGXState vex_shadow1; 56 VexGuestTILEGXState vex_shadow2; 57}; 58 59#ifndef C_ABI_SAVE_AREA_SIZE 60#define C_ABI_SAVE_AREA_SIZE 16 61#endif 62struct rt_sigframe { 63 unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; /* caller save area */ 64 vki_siginfo_t rs_info; 65 struct vki_ucontext rs_uc; 66 struct vg_sig_private priv; 67}; 68 69 70static 71void setup_sigcontext2 ( ThreadState* tst, struct vki_sigcontext **sc1, 72 const vki_siginfo_t *si ) 73{ 74 75 struct vki_sigcontext *sc = *sc1; 76 77 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcontext", 78 (Addr)sc, sizeof(unsigned long long)*34 ); 79 sc->gregs[0] = tst->arch.vex.guest_r0; 80 sc->gregs[1] = tst->arch.vex.guest_r1; 81 sc->gregs[2] = tst->arch.vex.guest_r2; 82 sc->gregs[3] = tst->arch.vex.guest_r3; 83 sc->gregs[4] = tst->arch.vex.guest_r4; 84 sc->gregs[5] = tst->arch.vex.guest_r5; 85 sc->gregs[6] = tst->arch.vex.guest_r6; 86 sc->gregs[7] = tst->arch.vex.guest_r7; 87 sc->gregs[8] = tst->arch.vex.guest_r8; 88 sc->gregs[9] = tst->arch.vex.guest_r9; 89 sc->gregs[10] = tst->arch.vex.guest_r10; 90 sc->gregs[11] = tst->arch.vex.guest_r11; 91 sc->gregs[12] = tst->arch.vex.guest_r12; 92 sc->gregs[13] = tst->arch.vex.guest_r13; 93 sc->gregs[14] = tst->arch.vex.guest_r14; 94 sc->gregs[15] = tst->arch.vex.guest_r15; 95 sc->gregs[16] = tst->arch.vex.guest_r16; 96 sc->gregs[17] = tst->arch.vex.guest_r17; 97 sc->gregs[18] = tst->arch.vex.guest_r18; 98 sc->gregs[19] = tst->arch.vex.guest_r19; 99 sc->gregs[20] = tst->arch.vex.guest_r20; 100 sc->gregs[21] = tst->arch.vex.guest_r21; 101 sc->gregs[22] = tst->arch.vex.guest_r22; 102 sc->gregs[23] = tst->arch.vex.guest_r23; 103 sc->gregs[24] = tst->arch.vex.guest_r24; 104 sc->gregs[25] = tst->arch.vex.guest_r25; 105 sc->gregs[26] = tst->arch.vex.guest_r26; 106 sc->gregs[27] = tst->arch.vex.guest_r27; 107 sc->gregs[28] = tst->arch.vex.guest_r28; 108 sc->gregs[29] = tst->arch.vex.guest_r29; 109 sc->gregs[30] = tst->arch.vex.guest_r30; 110 sc->gregs[31] = tst->arch.vex.guest_r31; 111 sc->gregs[32] = tst->arch.vex.guest_r32; 112 sc->gregs[33] = tst->arch.vex.guest_r33; 113 sc->gregs[34] = tst->arch.vex.guest_r34; 114 sc->gregs[35] = tst->arch.vex.guest_r35; 115 sc->gregs[36] = tst->arch.vex.guest_r36; 116 sc->gregs[37] = tst->arch.vex.guest_r37; 117 sc->gregs[38] = tst->arch.vex.guest_r38; 118 sc->gregs[39] = tst->arch.vex.guest_r39; 119 sc->gregs[40] = tst->arch.vex.guest_r40; 120 sc->gregs[41] = tst->arch.vex.guest_r41; 121 sc->gregs[42] = tst->arch.vex.guest_r42; 122 sc->gregs[43] = tst->arch.vex.guest_r43; 123 sc->gregs[44] = tst->arch.vex.guest_r44; 124 sc->gregs[45] = tst->arch.vex.guest_r45; 125 sc->gregs[46] = tst->arch.vex.guest_r46; 126 sc->gregs[47] = tst->arch.vex.guest_r47; 127 sc->gregs[48] = tst->arch.vex.guest_r48; 128 sc->gregs[49] = tst->arch.vex.guest_r49; 129 sc->gregs[50] = tst->arch.vex.guest_r50; 130 sc->gregs[51] = tst->arch.vex.guest_r51; 131 sc->gregs[52] = tst->arch.vex.guest_r52; 132 sc->tp = tst->arch.vex.guest_r53; 133 sc->sp = tst->arch.vex.guest_r54; 134 sc->lr = tst->arch.vex.guest_r55; 135 sc->pc = tst->arch.vex.guest_pc; 136} 137 138/* EXPORTED */ 139void VG_(sigframe_create)( ThreadId tid, 140 Addr sp_top_of_frame, 141 const vki_siginfo_t *siginfo, 142 const struct vki_ucontext *siguc, 143 void *handler, 144 UInt flags, 145 const vki_sigset_t *mask, 146 void *restorer ) 147{ 148 Addr sp; 149 ThreadState* tst; 150 Addr faultaddr; 151 Int sigNo = siginfo->si_signo; 152 struct vg_sig_private *priv; 153 154 /* Stack must be 8-byte aligned */ 155 sp_top_of_frame &= ~0x7ULL; 156 157 sp = sp_top_of_frame - sizeof(struct rt_sigframe); 158 159 tst = VG_(get_ThreadState)(tid); 160 if (! ML_(sf_maybe_extend_stack)(tst, sp, sizeof(struct rt_sigframe), flags)) 161 return; 162 163 vg_assert(VG_IS_8_ALIGNED(sp)); 164 165 /* SIGILL defines addr to be the faulting address */ 166 167 faultaddr = (Addr)siginfo->_sifields._sigfault._addr; 168 if (sigNo == VKI_SIGILL && siginfo->si_code > 0) 169 faultaddr = tst->arch.vex.guest_pc; 170 171 172 struct rt_sigframe *frame = (struct rt_sigframe *) sp; 173 struct vki_ucontext *ucp = &frame->rs_uc; 174 if (VG_(clo_trace_signals)) 175 VG_(printf)("rt_sigframe\n"); 176 /* Create siginfo. */ 177 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame siginfo", 178 (Addr)&frame->rs_info, sizeof(frame->rs_info) ); 179 180 VG_(memcpy)(&frame->rs_info, siginfo, sizeof(*siginfo)); 181 182 VG_TRACK( post_mem_write, Vg_CoreSignal, tid, 183 (Addr)&frame->rs_info, sizeof(frame->rs_info) ); 184 185 /* Create the ucontext. */ 186 VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext", 187 (Addr)ucp, offsetof(struct vki_ucontext, uc_mcontext) ); 188 189 ucp->uc_flags = 0; 190 ucp->uc_link = 0; 191 ucp->uc_stack = tst->altstack; 192 193 VG_TRACK( post_mem_write, Vg_CoreSignal, tid, (Addr)ucp, 194 offsetof(struct vki_ucontext, uc_mcontext) ); 195 196 struct vki_sigcontext *scp = &(frame->rs_uc.uc_mcontext); 197 setup_sigcontext2(tst, &(scp), siginfo); 198 199 ucp->uc_sigmask = tst->sig_mask; 200 201 priv = &frame->priv; 202 203 /* 204 * Arguments to signal handler: 205 * 206 * r0 = signal number 207 * r1 = 0 (should be cause) 208 * r2 = pointer to ucontext 209 * 210 * r54 points to the struct rt_sigframe. 211 */ 212 213 tst->arch.vex.guest_r0 = siginfo->si_signo; 214 tst->arch.vex.guest_r1 = (Addr) &frame->rs_info; 215 tst->arch.vex.guest_r2 = (Addr) &frame->rs_uc; 216 tst->arch.vex.guest_r54 = (Addr) frame; 217 218 if (flags & VKI_SA_RESTORER) 219 { 220 tst->arch.vex.guest_r55 = (Addr) restorer; 221 } 222 else 223 { 224 tst->arch.vex.guest_r55 = (Addr)&VG_(tilegx_linux_SUBST_FOR_rt_sigreturn); 225 } 226 227 priv->magicPI = 0x31415927; 228 priv->sigNo_private = sigNo; 229 priv->vex_shadow1 = tst->arch.vex_shadow1; 230 priv->vex_shadow2 = tst->arch.vex_shadow2; 231 /* Set the thread so it will next run the handler. */ 232 /* tst->m_sp = sp; also notify the tool we've updated SP */ 233 VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr)); 234 if (VG_(clo_trace_signals)) 235 VG_(printf)("handler = %p\n", handler); 236 tst->arch.vex.guest_pc = (Addr) handler; 237 /* This thread needs to be marked runnable, but we leave that the 238 caller to do. */ 239 if (0) 240 VG_(printf)("pushed signal frame; sp now = %lx, " 241 "next %pc = %lx, status=%d\n", 242 (Addr)frame, tst->arch.vex.guest_pc, tst->status); 243} 244 245/* EXPORTED */ 246void VG_(sigframe_destroy)( ThreadId tid, Bool isRT ) 247{ 248 ThreadState *tst; 249 struct vg_sig_private *priv1; 250 Addr sp; 251 UInt frame_size; 252 struct vki_sigcontext *mc; 253 Int sigNo; 254 Bool has_siginfo = isRT; 255 256 vg_assert(VG_(is_valid_tid)(tid)); 257 tst = VG_(get_ThreadState)(tid); 258 sp = tst->arch.vex.guest_r54 + 8; 259 if (has_siginfo) 260 { 261 struct rt_sigframe *frame = (struct rt_sigframe *)sp; 262 struct vki_ucontext *ucp = &frame->rs_uc; 263 264 if (0) 265 VG_(printf)("destory signal frame; sp = %lx, " 266 " %pc = %lx, status=%d\n", 267 (Addr)frame, tst->arch.vex.guest_pc, tst->status); 268 269 frame_size = sizeof(*frame); 270 mc = &ucp->uc_mcontext; 271 priv1 = &frame->priv; 272 vg_assert(priv1->magicPI == 0x31415927); 273 sigNo = priv1->sigNo_private; 274 } 275 else 276 { 277 vg_assert(0); 278 } 279 280 //restore regs 281 tst->arch.vex.guest_r0 = mc->gregs[0]; 282 tst->arch.vex.guest_r1 = mc->gregs[1]; 283 tst->arch.vex.guest_r2 = mc->gregs[2]; 284 tst->arch.vex.guest_r3 = mc->gregs[3]; 285 tst->arch.vex.guest_r4 = mc->gregs[4]; 286 tst->arch.vex.guest_r5 = mc->gregs[5]; 287 tst->arch.vex.guest_r6 = mc->gregs[6]; 288 tst->arch.vex.guest_r7 = mc->gregs[7]; 289 tst->arch.vex.guest_r8 = mc->gregs[8]; 290 tst->arch.vex.guest_r9 = mc->gregs[9]; 291 tst->arch.vex.guest_r10 = mc->gregs[10]; 292 tst->arch.vex.guest_r11 = mc->gregs[11]; 293 tst->arch.vex.guest_r12 = mc->gregs[12]; 294 tst->arch.vex.guest_r13 = mc->gregs[13]; 295 tst->arch.vex.guest_r14 = mc->gregs[14]; 296 tst->arch.vex.guest_r15 = mc->gregs[15]; 297 tst->arch.vex.guest_r16 = mc->gregs[16]; 298 tst->arch.vex.guest_r17 = mc->gregs[17]; 299 tst->arch.vex.guest_r18 = mc->gregs[18]; 300 tst->arch.vex.guest_r19 = mc->gregs[19]; 301 tst->arch.vex.guest_r20 = mc->gregs[20]; 302 tst->arch.vex.guest_r21 = mc->gregs[21]; 303 tst->arch.vex.guest_r22 = mc->gregs[22]; 304 tst->arch.vex.guest_r23 = mc->gregs[23]; 305 tst->arch.vex.guest_r24 = mc->gregs[24]; 306 tst->arch.vex.guest_r25 = mc->gregs[25]; 307 tst->arch.vex.guest_r26 = mc->gregs[26]; 308 tst->arch.vex.guest_r27 = mc->gregs[27]; 309 tst->arch.vex.guest_r28 = mc->gregs[28]; 310 tst->arch.vex.guest_r29 = mc->gregs[29]; 311 tst->arch.vex.guest_r30 = mc->gregs[30]; 312 tst->arch.vex.guest_r31 = mc->gregs[31]; 313 tst->arch.vex.guest_r32 = mc->gregs[32]; 314 tst->arch.vex.guest_r33 = mc->gregs[33]; 315 tst->arch.vex.guest_r34 = mc->gregs[34]; 316 tst->arch.vex.guest_r35 = mc->gregs[35]; 317 tst->arch.vex.guest_r36 = mc->gregs[36]; 318 tst->arch.vex.guest_r37 = mc->gregs[37]; 319 tst->arch.vex.guest_r38 = mc->gregs[38]; 320 tst->arch.vex.guest_r39 = mc->gregs[39]; 321 tst->arch.vex.guest_r40 = mc->gregs[40]; 322 tst->arch.vex.guest_r41 = mc->gregs[41]; 323 tst->arch.vex.guest_r42 = mc->gregs[42]; 324 tst->arch.vex.guest_r43 = mc->gregs[43]; 325 tst->arch.vex.guest_r44 = mc->gregs[44]; 326 tst->arch.vex.guest_r45 = mc->gregs[45]; 327 tst->arch.vex.guest_r46 = mc->gregs[46]; 328 tst->arch.vex.guest_r47 = mc->gregs[47]; 329 tst->arch.vex.guest_r48 = mc->gregs[48]; 330 tst->arch.vex.guest_r49 = mc->gregs[49]; 331 tst->arch.vex.guest_r50 = mc->gregs[50]; 332 tst->arch.vex.guest_r51 = mc->gregs[51]; 333 tst->arch.vex.guest_r52 = mc->gregs[52]; 334 tst->arch.vex.guest_r53 = mc->tp; 335 tst->arch.vex.guest_r54 = mc->sp; 336 tst->arch.vex.guest_r55 = mc->lr; 337 tst->arch.vex.guest_pc = mc->pc; 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 %d): 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_tilegx_linux) 349 350/*--------------------------------------------------------------------*/ 351/*--- end sigframe-tilegx-linux.c ---*/ 352/*--------------------------------------------------------------------*/ 353