1 2 /*--------------------------------------------------------------------*/ 3 /*--- Create/destroy signal delivery frames. ---*/ 4 /*--- sigframe-s390x-linux.c ---*/ 5 /*--------------------------------------------------------------------*/ 6 7 /* 8 This file is part of Valgrind, a dynamic binary instrumentation 9 framework. 10 11 Copyright IBM Corp. 2010-2015 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 Christian Borntraeger */ 32 33 #include "pub_core_basics.h" 34 #include "pub_core_vki.h" 35 #include "pub_core_vkiscnums.h" 36 #include "pub_core_threadstate.h" 37 #include "pub_core_aspacemgr.h" 38 #include "pub_core_libcbase.h" 39 #include "pub_core_libcassert.h" 40 #include "pub_core_libcprint.h" 41 #include "pub_core_machine.h" 42 #include "pub_core_options.h" 43 #include "pub_core_sigframe.h" 44 #include "pub_core_signals.h" 45 #include "pub_core_tooliface.h" 46 #include "pub_core_trampoline.h" 47 #include "priv_sigframe.h" 48 49 #if defined(VGA_s390x) 50 51 /* This module creates and removes signal frames for signal deliveries 52 on s390x-linux. 53 54 Note, this file contains kernel-specific knowledge in the form of 55 'struct sigframe' and 'struct rt_sigframe'. 56 57 Either a 'struct sigframe' or a 'struct rtsigframe' is pushed 58 onto the client's stack. This contains a subsidiary 59 vki_ucontext. That holds the vcpu's state across the signal, 60 so that the sighandler can mess with the vcpu state if it 61 really wants. 62 */ 63 64 #define SET_SIGNAL_GPR(zztst, zzn, zzval) \ 65 do { zztst->arch.vex.guest_r##zzn = (unsigned long)(zzval); \ 66 VG_TRACK( post_reg_write, Vg_CoreSignal, zztst->tid, \ 67 offsetof(VexGuestS390XState,guest_r##zzn), \ 68 sizeof(UWord) ); \ 69 } while (0) 70 71 /*------------------------------------------------------------*/ 72 /*--- Signal frame layouts ---*/ 73 /*------------------------------------------------------------*/ 74 75 // A structure in which to save the application's registers 76 // during the execution of signal handlers. 77 78 // Linux has 2 signal frame structures: one for normal signal 79 // deliveries, and one for SA_SIGINFO deliveries (also known as RT 80 // signals). 81 // 82 // In theory, so long as we get the arguments to the handler function 83 // right, it doesn't matter what the exact layout of the rest of the 84 // frame is. Unfortunately, things like gcc's exception unwinding 85 // make assumptions about the locations of various parts of the frame, 86 // so we need to duplicate it exactly. 87 88 /* Valgrind-specific parts of the signal frame */ 89 struct vg_sigframe 90 { 91 /* Sanity check word. */ 92 UInt magicPI; 93 94 UInt handlerflags; /* flags for signal handler */ 95 96 97 /* Safely-saved version of sigNo, as described above. */ 98 Int sigNo_private; 99 100 /* XXX This is wrong. Surely we should store the shadow values 101 into the shadow memory behind the actual values? */ 102 VexGuestS390XState vex_shadow1; 103 VexGuestS390XState vex_shadow2; 104 105 /* HACK ALERT */ 106 VexGuestS390XState vex; 107 /* end HACK ALERT */ 108 109 /* saved signal mask to be restored when handler returns */ 110 vki_sigset_t mask; 111 112 /* Sanity check word. Is the highest-addressed word; do not 113 move!*/ 114 UInt magicE; 115 }; 116 117 #define S390_SYSCALL_SIZE 2 118 119 struct sigframe 120 { 121 UChar callee_used_stack[__VKI_SIGNAL_FRAMESIZE]; 122 struct vki_sigcontext sc; 123 _vki_sigregs sregs; 124 Int sigNo; 125 UChar retcode[S390_SYSCALL_SIZE]; 126 127 struct vg_sigframe vg; 128 }; 129 130 struct rt_sigframe 131 { 132 UChar callee_used_stack[__VKI_SIGNAL_FRAMESIZE]; 133 UChar retcode[S390_SYSCALL_SIZE]; 134 struct vki_siginfo info; 135 struct vki_ucontext uc; 136 137 struct vg_sigframe vg; 138 }; 139 140 /*------------------------------------------------------------*/ 141 /*--- Creating signal frames ---*/ 142 /*------------------------------------------------------------*/ 143 144 /* Saves all user-controlled register into a _vki_sigregs structure */ 145 static void save_sigregs(ThreadState *tst, _vki_sigregs *sigregs) 146 { 147 sigregs->regs.gprs[0] = tst->arch.vex.guest_r0; 148 sigregs->regs.gprs[1] = tst->arch.vex.guest_r1; 149 sigregs->regs.gprs[2] = tst->arch.vex.guest_r2; 150 sigregs->regs.gprs[3] = tst->arch.vex.guest_r3; 151 sigregs->regs.gprs[4] = tst->arch.vex.guest_r4; 152 sigregs->regs.gprs[5] = tst->arch.vex.guest_r5; 153 sigregs->regs.gprs[6] = tst->arch.vex.guest_r6; 154 sigregs->regs.gprs[7] = tst->arch.vex.guest_r7; 155 sigregs->regs.gprs[8] = tst->arch.vex.guest_r8; 156 sigregs->regs.gprs[9] = tst->arch.vex.guest_r9; 157 sigregs->regs.gprs[10] = tst->arch.vex.guest_r10; 158 sigregs->regs.gprs[11] = tst->arch.vex.guest_r11; 159 sigregs->regs.gprs[12] = tst->arch.vex.guest_r12; 160 sigregs->regs.gprs[13] = tst->arch.vex.guest_r13; 161 sigregs->regs.gprs[14] = tst->arch.vex.guest_r14; 162 sigregs->regs.gprs[15] = tst->arch.vex.guest_r15; 163 164 sigregs->regs.acrs[0] = tst->arch.vex.guest_a0; 165 sigregs->regs.acrs[1] = tst->arch.vex.guest_a1; 166 sigregs->regs.acrs[2] = tst->arch.vex.guest_a2; 167 sigregs->regs.acrs[3] = tst->arch.vex.guest_a3; 168 sigregs->regs.acrs[4] = tst->arch.vex.guest_a4; 169 sigregs->regs.acrs[5] = tst->arch.vex.guest_a5; 170 sigregs->regs.acrs[6] = tst->arch.vex.guest_a6; 171 sigregs->regs.acrs[7] = tst->arch.vex.guest_a7; 172 sigregs->regs.acrs[8] = tst->arch.vex.guest_a8; 173 sigregs->regs.acrs[9] = tst->arch.vex.guest_a9; 174 sigregs->regs.acrs[10] = tst->arch.vex.guest_a10; 175 sigregs->regs.acrs[11] = tst->arch.vex.guest_a11; 176 sigregs->regs.acrs[12] = tst->arch.vex.guest_a12; 177 sigregs->regs.acrs[13] = tst->arch.vex.guest_a13; 178 sigregs->regs.acrs[14] = tst->arch.vex.guest_a14; 179 sigregs->regs.acrs[15] = tst->arch.vex.guest_a15; 180 181 sigregs->fpregs.fprs[0] = tst->arch.vex.guest_f0; 182 sigregs->fpregs.fprs[1] = tst->arch.vex.guest_f1; 183 sigregs->fpregs.fprs[2] = tst->arch.vex.guest_f2; 184 sigregs->fpregs.fprs[3] = tst->arch.vex.guest_f3; 185 sigregs->fpregs.fprs[4] = tst->arch.vex.guest_f4; 186 sigregs->fpregs.fprs[5] = tst->arch.vex.guest_f5; 187 sigregs->fpregs.fprs[6] = tst->arch.vex.guest_f6; 188 sigregs->fpregs.fprs[7] = tst->arch.vex.guest_f7; 189 sigregs->fpregs.fprs[8] = tst->arch.vex.guest_f8; 190 sigregs->fpregs.fprs[9] = tst->arch.vex.guest_f9; 191 sigregs->fpregs.fprs[10] = tst->arch.vex.guest_f10; 192 sigregs->fpregs.fprs[11] = tst->arch.vex.guest_f11; 193 sigregs->fpregs.fprs[12] = tst->arch.vex.guest_f12; 194 sigregs->fpregs.fprs[13] = tst->arch.vex.guest_f13; 195 sigregs->fpregs.fprs[14] = tst->arch.vex.guest_f14; 196 sigregs->fpregs.fprs[15] = tst->arch.vex.guest_f15; 197 sigregs->fpregs.fpc = tst->arch.vex.guest_fpc; 198 199 sigregs->regs.psw.addr = tst->arch.vex.guest_IA; 200 /* save a sane dummy mask */ 201 sigregs->regs.psw.mask = 0x0705000180000000UL; 202 } 203 204 static void restore_sigregs(ThreadState *tst, _vki_sigregs *sigregs) 205 { 206 tst->arch.vex.guest_r0 = sigregs->regs.gprs[0]; 207 tst->arch.vex.guest_r1 = sigregs->regs.gprs[1]; 208 tst->arch.vex.guest_r2 = sigregs->regs.gprs[2]; 209 tst->arch.vex.guest_r3 = sigregs->regs.gprs[3]; 210 tst->arch.vex.guest_r4 = sigregs->regs.gprs[4]; 211 tst->arch.vex.guest_r5 = sigregs->regs.gprs[5]; 212 tst->arch.vex.guest_r6 = sigregs->regs.gprs[6]; 213 tst->arch.vex.guest_r7 = sigregs->regs.gprs[7]; 214 tst->arch.vex.guest_r8 = sigregs->regs.gprs[8]; 215 tst->arch.vex.guest_r9 = sigregs->regs.gprs[9]; 216 tst->arch.vex.guest_r10 = sigregs->regs.gprs[10]; 217 tst->arch.vex.guest_r11 = sigregs->regs.gprs[11]; 218 tst->arch.vex.guest_r12 = sigregs->regs.gprs[12]; 219 tst->arch.vex.guest_r13 = sigregs->regs.gprs[13]; 220 tst->arch.vex.guest_r14 = sigregs->regs.gprs[14]; 221 tst->arch.vex.guest_r15 = sigregs->regs.gprs[15]; 222 223 tst->arch.vex.guest_a0 = sigregs->regs.acrs[0]; 224 tst->arch.vex.guest_a1 = sigregs->regs.acrs[1]; 225 tst->arch.vex.guest_a2 = sigregs->regs.acrs[2]; 226 tst->arch.vex.guest_a3 = sigregs->regs.acrs[3]; 227 tst->arch.vex.guest_a4 = sigregs->regs.acrs[4]; 228 tst->arch.vex.guest_a5 = sigregs->regs.acrs[5]; 229 tst->arch.vex.guest_a6 = sigregs->regs.acrs[6]; 230 tst->arch.vex.guest_a7 = sigregs->regs.acrs[7]; 231 tst->arch.vex.guest_a8 = sigregs->regs.acrs[8]; 232 tst->arch.vex.guest_a9 = sigregs->regs.acrs[9]; 233 tst->arch.vex.guest_a10 = sigregs->regs.acrs[10]; 234 tst->arch.vex.guest_a11 = sigregs->regs.acrs[11]; 235 tst->arch.vex.guest_a12 = sigregs->regs.acrs[12]; 236 tst->arch.vex.guest_a13 = sigregs->regs.acrs[13]; 237 tst->arch.vex.guest_a14 = sigregs->regs.acrs[14]; 238 tst->arch.vex.guest_a15 = sigregs->regs.acrs[15]; 239 240 tst->arch.vex.guest_f0 = sigregs->fpregs.fprs[0]; 241 tst->arch.vex.guest_f1 = sigregs->fpregs.fprs[1]; 242 tst->arch.vex.guest_f2 = sigregs->fpregs.fprs[2]; 243 tst->arch.vex.guest_f3 = sigregs->fpregs.fprs[3]; 244 tst->arch.vex.guest_f4 = sigregs->fpregs.fprs[4]; 245 tst->arch.vex.guest_f5 = sigregs->fpregs.fprs[5]; 246 tst->arch.vex.guest_f6 = sigregs->fpregs.fprs[6]; 247 tst->arch.vex.guest_f7 = sigregs->fpregs.fprs[7]; 248 tst->arch.vex.guest_f8 = sigregs->fpregs.fprs[8]; 249 tst->arch.vex.guest_f9 = sigregs->fpregs.fprs[9]; 250 tst->arch.vex.guest_f10 = sigregs->fpregs.fprs[10]; 251 tst->arch.vex.guest_f11 = sigregs->fpregs.fprs[11]; 252 tst->arch.vex.guest_f12 = sigregs->fpregs.fprs[12]; 253 tst->arch.vex.guest_f13 = sigregs->fpregs.fprs[13]; 254 tst->arch.vex.guest_f14 = sigregs->fpregs.fprs[14]; 255 tst->arch.vex.guest_f15 = sigregs->fpregs.fprs[15]; 256 tst->arch.vex.guest_fpc = sigregs->fpregs.fpc; 257 258 tst->arch.vex.guest_IA = sigregs->regs.psw.addr; 259 } 260 261 262 /* Build the Valgrind-specific part of a signal frame. */ 263 264 static void build_vg_sigframe(struct vg_sigframe *frame, 265 ThreadState *tst, 266 UInt flags, 267 Int sigNo) 268 { 269 frame->sigNo_private = sigNo; 270 frame->magicPI = 0x31415927; 271 frame->vex_shadow1 = tst->arch.vex_shadow1; 272 frame->vex_shadow2 = tst->arch.vex_shadow2; 273 /* HACK ALERT */ 274 frame->vex = tst->arch.vex; 275 /* end HACK ALERT */ 276 frame->mask = tst->sig_mask; 277 frame->handlerflags = flags; 278 frame->magicE = 0x27182818; 279 } 280 281 282 static Addr build_sigframe(ThreadState *tst, 283 Addr sp_top_of_frame, 284 const vki_siginfo_t *siginfo, 285 const struct vki_ucontext *siguc, 286 UInt flags, 287 const vki_sigset_t *mask, 288 void *restorer) 289 { 290 struct sigframe *frame; 291 Addr sp = sp_top_of_frame; 292 293 vg_assert((flags & VKI_SA_SIGINFO) == 0); 294 vg_assert((sizeof(*frame) & 7) == 0); 295 vg_assert((sp & 7) == 0); 296 297 sp -= sizeof(*frame); 298 frame = (struct sigframe *)sp; 299 300 if (! ML_(sf_maybe_extend_stack)(tst, sp, sizeof(*frame), flags)) 301 return sp_top_of_frame; 302 303 /* retcode, sigNo, sc, sregs fields are to be written */ 304 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame", 305 sp, offsetof(struct sigframe, vg) ); 306 307 save_sigregs(tst, &frame->sregs); 308 309 frame->sigNo = siginfo->si_signo; 310 frame->sc.sregs = &frame->sregs; 311 VG_(memcpy)(frame->sc.oldmask, mask->sig, sizeof(frame->sc.oldmask)); 312 313 if (flags & VKI_SA_RESTORER) { 314 SET_SIGNAL_GPR(tst, 14, restorer); 315 } else { 316 frame->retcode[0] = 0x0a; 317 frame->retcode[1] = __NR_sigreturn; 318 /* This normally should be &frame->recode. but since there 319 might be problems with non-exec stack and we must discard 320 the translation for the on-stack sigreturn we just use the 321 trampoline like x86,ppc. We still fill in the retcode, lets 322 just hope that nobody actually jumps here */ 323 SET_SIGNAL_GPR(tst, 14, (Addr)&VG_(s390x_linux_SUBST_FOR_sigreturn)); 324 } 325 326 SET_SIGNAL_GPR(tst, 2, siginfo->si_signo); 327 SET_SIGNAL_GPR(tst, 3, &frame->sc); 328 /* fixs390: we dont fill in trapno and prot_addr in r4 and r5*/ 329 330 /* Set up backchain. */ 331 *((Addr *) sp) = sp_top_of_frame; 332 333 VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, 334 sp, offsetof(struct sigframe, vg) ); 335 336 build_vg_sigframe(&frame->vg, tst, flags, siginfo->si_signo); 337 338 return sp; 339 } 340 341 static Addr build_rt_sigframe(ThreadState *tst, 342 Addr sp_top_of_frame, 343 const vki_siginfo_t *siginfo, 344 const struct vki_ucontext *siguc, 345 UInt flags, 346 const vki_sigset_t *mask, 347 void *restorer) 348 { 349 struct rt_sigframe *frame; 350 Addr sp = sp_top_of_frame; 351 Int sigNo = siginfo->si_signo; 352 353 vg_assert((flags & VKI_SA_SIGINFO) != 0); 354 vg_assert((sizeof(*frame) & 7) == 0); 355 vg_assert((sp & 7) == 0); 356 357 sp -= sizeof(*frame); 358 frame = (struct rt_sigframe *)sp; 359 360 if (! ML_(sf_maybe_extend_stack)(tst, sp, sizeof(*frame), flags)) 361 return sp_top_of_frame; 362 363 /* retcode, sigNo, sc, sregs fields are to be written */ 364 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame", 365 sp, offsetof(struct rt_sigframe, vg) ); 366 367 save_sigregs(tst, &frame->uc.uc_mcontext); 368 369 if (flags & VKI_SA_RESTORER) { 370 frame->retcode[0] = 0; 371 frame->retcode[1] = 0; 372 SET_SIGNAL_GPR(tst, 14, restorer); 373 } else { 374 frame->retcode[0] = 0x0a; 375 frame->retcode[1] = __NR_rt_sigreturn; 376 /* This normally should be &frame->recode. but since there 377 might be problems with non-exec stack and we must discard 378 the translation for the on-stack sigreturn we just use the 379 trampoline like x86,ppc. We still fill in the retcode, lets 380 just hope that nobody actually jumps here */ 381 SET_SIGNAL_GPR(tst, 14, (Addr)&VG_(s390x_linux_SUBST_FOR_rt_sigreturn)); 382 } 383 384 VG_(memcpy)(&frame->info, siginfo, sizeof(vki_siginfo_t)); 385 frame->uc.uc_flags = 0; 386 frame->uc.uc_link = 0; 387 frame->uc.uc_sigmask = *mask; 388 frame->uc.uc_stack = tst->altstack; 389 390 SET_SIGNAL_GPR(tst, 2, siginfo->si_signo); 391 SET_SIGNAL_GPR(tst, 3, &frame->info); 392 SET_SIGNAL_GPR(tst, 4, &frame->uc); 393 394 /* Set up backchain. */ 395 *((Addr *) sp) = sp_top_of_frame; 396 397 VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, 398 sp, offsetof(struct rt_sigframe, vg) ); 399 400 build_vg_sigframe(&frame->vg, tst, flags, sigNo); 401 return sp; 402 } 403 404 /* EXPORTED */ 405 void VG_(sigframe_create)( ThreadId tid, 406 Bool on_altstack, 407 Addr sp_top_of_frame, 408 const vki_siginfo_t *siginfo, 409 const struct vki_ucontext *siguc, 410 void *handler, 411 UInt flags, 412 const vki_sigset_t *mask, 413 void *restorer ) 414 { 415 Addr sp; 416 ThreadState* tst = VG_(get_ThreadState)(tid); 417 418 if (flags & VKI_SA_SIGINFO) 419 sp = build_rt_sigframe(tst, sp_top_of_frame, siginfo, siguc, 420 flags, mask, restorer); 421 else 422 sp = build_sigframe(tst, sp_top_of_frame, siginfo, siguc, 423 flags, mask, restorer); 424 425 /* Set the thread so it will next run the handler. */ 426 VG_(set_SP)(tid, sp); 427 VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr)); 428 429 tst->arch.vex.guest_IA = (Addr) handler; 430 /* We might have interrupted a repeating instruction that uses the guest 431 counter. Since our VEX requires that a new instruction will see a 432 guest counter == 0, we have to set it here. The old value will be 433 restored by restore_vg_sigframe. */ 434 tst->arch.vex.guest_counter = 0; 435 /* This thread needs to be marked runnable, but we leave that the 436 caller to do. */ 437 } 438 439 440 /*------------------------------------------------------------*/ 441 /*--- Destroying signal frames ---*/ 442 /*------------------------------------------------------------*/ 443 444 /* Return False and don't do anything, just set the client to take a 445 segfault, if it looks like the frame is corrupted. */ 446 static 447 Bool restore_vg_sigframe ( ThreadState *tst, 448 struct vg_sigframe *frame, Int *sigNo ) 449 { 450 if (frame->magicPI != 0x31415927 || 451 frame->magicE != 0x27182818) { 452 VG_(message)(Vg_UserMsg, "Thread %u return signal frame " 453 "corrupted. Killing process.\n", 454 tst->tid); 455 VG_(set_default_handler)(VKI_SIGSEGV); 456 VG_(synth_fault)(tst->tid); 457 *sigNo = VKI_SIGSEGV; 458 return False; 459 } 460 tst->sig_mask = frame->mask; 461 tst->tmp_sig_mask = frame->mask; 462 tst->arch.vex_shadow1 = frame->vex_shadow1; 463 tst->arch.vex_shadow2 = frame->vex_shadow2; 464 /* HACK ALERT */ 465 tst->arch.vex = frame->vex; 466 /* end HACK ALERT */ 467 *sigNo = frame->sigNo_private; 468 return True; 469 } 470 471 static 472 SizeT restore_sigframe ( ThreadState *tst, 473 struct sigframe *frame, Int *sigNo ) 474 { 475 if (restore_vg_sigframe(tst, &frame->vg, sigNo)) 476 restore_sigregs(tst, frame->sc.sregs); 477 478 return sizeof(*frame); 479 } 480 481 static 482 SizeT restore_rt_sigframe ( ThreadState *tst, 483 struct rt_sigframe *frame, Int *sigNo ) 484 { 485 if (restore_vg_sigframe(tst, &frame->vg, sigNo)) { 486 restore_sigregs(tst, &frame->uc.uc_mcontext); 487 } 488 return sizeof(*frame); 489 } 490 491 492 /* EXPORTED */ 493 void VG_(sigframe_destroy)( ThreadId tid, Bool isRT ) 494 { 495 Addr sp; 496 ThreadState* tst; 497 SizeT size; 498 Int sigNo; 499 500 tst = VG_(get_ThreadState)(tid); 501 502 /* Correctly reestablish the frame base address. */ 503 sp = tst->arch.vex.guest_SP; 504 505 if (!isRT) 506 size = restore_sigframe(tst, (struct sigframe *)sp, &sigNo); 507 else 508 size = restore_rt_sigframe(tst, (struct rt_sigframe *)sp, &sigNo); 509 510 /* same as for creation: we must announce the full memory (including 511 alignment), otherwise massif might fail on longjmp */ 512 VG_TRACK( die_mem_stack_signal, sp - VG_STACK_REDZONE_SZB, 513 size + VG_STACK_REDZONE_SZB ); 514 515 if (VG_(clo_trace_signals)) 516 VG_(message)( 517 Vg_DebugMsg, 518 "VG_(sigframe_destroy) (thread %u): isRT=%d valid magic; IP=%#llx\n", 519 tid, isRT, tst->arch.vex.guest_IA); 520 521 /* tell the tools */ 522 VG_TRACK( post_deliver_signal, tid, sigNo ); 523 } 524 525 #endif /* VGA_s390x */ 526 527 /*--------------------------------------------------------------------*/ 528 /*--- end sigframe-s390x-linux.c ---*/ 529 /*--------------------------------------------------------------------*/ 530