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