1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Create/destroy signal delivery frames. ---*/ 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- sigframe-arm-linux.c ---*/ 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of Valgrind, a dynamic binary instrumentation 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown framework. 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 11663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Copyright (C) 2000-2012 Nicholas Nethercote 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown njn@valgrind.org 13663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Copyright (C) 2004-2012 Paul Mackerras 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown paulus@samba.org 15663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng Copyright (C) 2008-2012 Evan Geller 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown gaze@bea.ms 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02111-1307, USA. 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGP_arm_linux) 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_basics.h" 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_vki.h" 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_vkiscnums.h" 41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_threadstate.h" 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_aspacemgr.h" 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcbase.h" 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcassert.h" 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_libcprint.h" 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_machine.h" 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_options.h" 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_sigframe.h" 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_signals.h" 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_tooliface.h" 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_trampoline.h" 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "pub_core_transtab.h" // VG_(discard_translations) 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* This uses the hack of dumping the vex guest state along with both 57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov shadows in the frame, and restoring it afterwards from there, 58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov rather than pulling it out of the ucontext. That means that signal 59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov handlers which modify the ucontext and then return, expecting their 60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov modifications to take effect, will have those modifications 61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ignored. This could be fixed properly with an hour or so more 62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov effort. */ 63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct vg_sig_private { 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt magicPI; 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt sigNo_private; 68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov VexGuestARMState vex; 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VexGuestARMState vex_shadow1; 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VexGuestARMState vex_shadow2; 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}; 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct sigframe { 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct vki_ucontext uc; 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned long retcode[2]; 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct vg_sig_private vp; 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}; 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstruct rt_sigframe { 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vki_siginfo_t info; 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct sigframe sig; 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}; 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic Bool extend ( ThreadState *tst, Addr addr, SizeT size ) 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ThreadId tid = tst->tid; 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown NSegment const* stackseg = NULL; 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(extend_stack)(addr, tst->client_stack_szB)) { 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown stackseg = VG_(am_find_nsegment)(addr); 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (0 && stackseg) 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("frame=%#lx seg=%#lx-%#lx\n", 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addr, stackseg->start, stackseg->end); 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) { 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)( 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Vg_UserMsg, 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "Can't extend stack to %#lx during signal delivery for thread %d:", 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown addr, tid); 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (stackseg == NULL) 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, " no stack segment"); 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_UserMsg, " too small or bad protection modes"); 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* set SIGSEGV to default handler */ 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(set_default_handler)(VKI_SIGSEGV); 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(synth_fault_mapping)(tid, addr); 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* The whole process should be about to die, since the default 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown action of SIGSEGV to kill the whole process. */ 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return False; 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* For tracking memory events, indicate the entire frame has been 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown allocated. */ 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB, 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown size + VG_STACK_REDZONE_SZB, tid ); 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return True; 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void synth_ucontext( ThreadId tid, const vki_siginfo_t *si, 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord trapno, UWord err, const vki_sigset_t *set, 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct vki_ucontext *uc){ 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ThreadState *tst = VG_(get_ThreadState)(tid); 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct vki_sigcontext *sc = &uc->uc_mcontext; 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memset)(uc, 0, sizeof(*uc)); 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown uc->uc_flags = 0; 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown uc->uc_link = 0; 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown uc->uc_sigmask = *set; 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown uc->uc_stack = tst->altstack; 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define SC2(reg,REG) sc->arm_##reg = tst->arch.vex.guest_##REG 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SC2(r0,R0); 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SC2(r1,R1); 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SC2(r2,R2); 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SC2(r3,R3); 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SC2(r4,R4); 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SC2(r5,R5); 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SC2(r6,R6); 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SC2(r7,R7); 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SC2(r8,R8); 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SC2(r9,R9); 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SC2(r10,R10); 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SC2(fp,R11); 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SC2(ip,R12); 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SC2(sp,R13); 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SC2(lr,R14); 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SC2(pc,R15T); 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef SC2 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sc->trap_no = trapno; 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sc->error_code = err; 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sc->fault_address = (UInt)si->_sifields._sigfault._addr; 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void build_sigframe(ThreadState *tst, 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct sigframe *frame, 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const vki_siginfo_t *siginfo, 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const struct vki_ucontext *siguc, 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void *handler, UInt flags, 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const vki_sigset_t *mask, 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void *restorer){ 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord trapno; 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord err; 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int sigNo = siginfo->si_signo; 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct vg_sig_private *priv = &frame->vp; 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame", 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Addr)frame, offsetof(struct sigframe, vp)); 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if(siguc) { 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown trapno = siguc->uc_mcontext.trap_no; 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown err = siguc->uc_mcontext.error_code; 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown trapno = 0; 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown err = 0; 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown synth_ucontext(tst->tid, siginfo, trapno, err, mask, &frame->uc); 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Addr)frame, offsetof(struct sigframe, vp)); 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown priv->magicPI = 0x31415927; 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown priv->sigNo_private = sigNo; 193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov priv->vex = tst->arch.vex; 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown priv->vex_shadow1 = tst->arch.vex_shadow1; 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown priv->vex_shadow2 = tst->arch.vex_shadow2; 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* EXPORTED */ 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(sigframe_create)( ThreadId tid, 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr sp_top_of_frame, 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const vki_siginfo_t *siginfo, 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const struct vki_ucontext *siguc, 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void *handler, 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt flags, 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown const vki_sigset_t *mask, 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void *restorer ) 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// struct vg_sig_private *priv; 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr sp = sp_top_of_frame; 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ThreadState *tst; 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int sigNo = siginfo->si_signo; 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// Addr faultaddr; 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt size; 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tst = VG_(get_ThreadState)(tid); 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown size = flags & VKI_SA_SIGINFO ? sizeof(struct rt_sigframe) : 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(struct sigframe); 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sp -= size; 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sp = VG_ROUNDDN(sp, 16); 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if(!extend(tst, sp, size)) 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown I_die_here; // XXX Incorrect behavior 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (flags & VKI_SA_SIGINFO){ 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct rt_sigframe *rsf = (struct rt_sigframe *)sp; 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Track our writes to siginfo */ 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, /* VVVVV */ 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "signal handler siginfo", (Addr)rsf, 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown offsetof(struct rt_sigframe, sig)); 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(memcpy)(&rsf->info, siginfo, sizeof(vki_siginfo_t)); 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if(sigNo == VKI_SIGILL && siginfo->si_code > 0) { 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown rsf->info._sifields._sigfault._addr = (Addr *) (tst)->arch.vex.guest_R12; /* IP */ 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, /* ^^^^^ */ 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown (Addr)rsf, offsetof(struct rt_sigframe, sig)); 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown build_sigframe(tst, &rsf->sig, siginfo, siguc, 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown handler, flags, mask, restorer); 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tst->arch.vex.guest_R1 = (Addr)&rsf->info; 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tst->arch.vex.guest_R2 = (Addr)&rsf->sig.uc; 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown else { 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown build_sigframe(tst, (struct sigframe *)sp, siginfo, siguc, 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown handler, flags, mask, restorer); 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(set_SP)(tid, sp); 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sizeof(Addr)); 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tst->arch.vex.guest_R0 = sigNo; 260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (flags & VKI_SA_RESTORER) 262663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tst->arch.vex.guest_R14 = (Addr)restorer; 263663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng else 264663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng tst->arch.vex.guest_R14 265663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng = (flags & VKI_SA_SIGINFO) 266663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng ? (Addr)&VG_(arm_linux_SUBST_FOR_rt_sigreturn) 267663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : (Addr)&VG_(arm_linux_SUBST_FOR_sigreturn); 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tst->arch.vex.guest_R15T = (Addr) handler; /* R15 == PC */ 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Destroying signal frames ---*/ 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*------------------------------------------------------------*/ 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* EXPORTED */ 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid VG_(sigframe_destroy)( ThreadId tid, Bool isRT ) 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ThreadState *tst; 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct vg_sig_private *priv; 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr sp; 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt frame_size; 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct vki_sigcontext *mc; 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int sigNo; 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Bool has_siginfo = isRT; 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(VG_(is_valid_tid)(tid)); 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tst = VG_(get_ThreadState)(tid); 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sp = tst->arch.vex.guest_R13; 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (has_siginfo) { 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct rt_sigframe *frame = (struct rt_sigframe *)sp; 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown frame_size = sizeof(*frame); 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc = &frame->sig.uc.uc_mcontext; 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown priv = &frame->sig.vp; 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(priv->magicPI == 0x31415927); 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tst->sig_mask = frame->sig.uc.uc_sigmask; 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } else { 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct sigframe *frame = (struct sigframe *)sp; 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown frame_size = sizeof(*frame); 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mc = &frame->uc.uc_mcontext; 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown priv = &frame->vp; 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(priv->magicPI == 0x31415927); 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tst->sig_mask = frame->uc.uc_sigmask; 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*tst->sig_mask.sig[0] = frame->uc.uc_mcontext.oldmask; 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tst->sig_mask.sig[1] = frame->uc.uc_mcontext._unused[3]; 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)("Setting signmask to %08x%08x\n",tst->sig_mask[0],tst->sig_mask[1]); 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tst->tmp_sig_mask = tst->sig_mask; 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sigNo = priv->sigNo_private; 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //XXX: restore regs 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define REST(reg,REG) tst->arch.vex.guest_##REG = mc->arm_##reg; 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown REST(r0,R0); 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown REST(r1,R1); 319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown REST(r2,R2); 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown REST(r3,R3); 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown REST(r4,R4); 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown REST(r5,R5); 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown REST(r6,R6); 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown REST(r7,R7); 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown REST(r8,R8); 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown REST(r9,R9); 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown REST(r10,R10); 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown REST(fp,R11); 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown REST(ip,R12); 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown REST(sp,R13); 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown REST(lr,R14); 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown REST(pc,R15T); 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# undef REST 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* Uh, the next line makes all the REST() above pointless. */ 336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov tst->arch.vex = priv->vex; 337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tst->arch.vex_shadow1 = priv->vex_shadow1; 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tst->arch.vex_shadow2 = priv->vex_shadow2; 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_TRACK( die_mem_stack_signal, sp - VG_STACK_REDZONE_SZB, 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown frame_size + VG_STACK_REDZONE_SZB ); 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(clo_trace_signals)) 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(message)(Vg_DebugMsg, 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "vg_pop_signal_frame (thread %d): " 347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "isRT=%d valid magic; PC=%#x\n", 348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tid, has_siginfo, tst->arch.vex.guest_R15T); 349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* tell the tools */ 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_TRACK( post_deliver_signal, tid, sigNo ); 352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif // defined(VGP_arm_linux) 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end sigframe-arm-linux.c ---*/ 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 359