1436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 2436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--------------------------------------------------------------------*/ 3436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--- Create/destroy signal delivery frames. ---*/ 4436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--- sigframe-arm64-linux.c ---*/ 5436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--------------------------------------------------------------------*/ 6436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 7436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* 8436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov This file is part of Valgrind, a dynamic binary instrumentation 9436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov framework. 10436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 11436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Copyright (C) 2013-2013 OpenWorks 12436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov info@open-works.net 13436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 14436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov This program is free software; you can redistribute it and/or 15436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov modify it under the terms of the GNU General Public License as 16436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov published by the Free Software Foundation; either version 2 of the 17436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov License, or (at your option) any later version. 18436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 19436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov This program is distributed in the hope that it will be useful, but 20436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov WITHOUT ANY WARRANTY; without even the implied warranty of 21436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov General Public License for more details. 23436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 24436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov You should have received a copy of the GNU General Public License 25436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov along with this program; if not, write to the Free Software 26436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 02111-1307, USA. 28436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 29436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov The GNU General Public License is contained in the file COPYING. 30436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov*/ 31436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 32436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#if defined(VGP_arm64_linux) 33436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 34436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_basics.h" 35436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_vki.h" 36436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ #include "pub_core_vkiscnums.h" 37436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy 38436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_threadstate.h" 39436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_aspacemgr.h" 40436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_libcbase.h" 41436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_libcassert.h" 42436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_libcprint.h" 43436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_machine.h" 44436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_options.h" 45436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_sigframe.h" 46436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_signals.h" 47436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_tooliface.h" 48436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#include "pub_core_trampoline.h" 49436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ #include "pub_core_transtab.h" // VG_(discard_translations) 50436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 51436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 52436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* This uses the hack of dumping the vex guest state along with both 53436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov shadows in the frame, and restoring it afterwards from there, 54436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov rather than pulling it out of the ucontext. That means that signal 55436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov handlers which modify the ucontext and then return, expecting their 56436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov modifications to take effect, will have those modifications 57436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ignored. This could be fixed properly with an hour or so more 58436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov effort. */ 59436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 60436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* This also always does the 'has siginfo' behaviour whether or 61436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov not it is requested. */ 62436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 63436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstruct vg_sig_private { 64436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt magicPI; 65436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt sigNo_private; 66436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VexGuestARM64State vex; 67436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VexGuestARM64State vex_shadow1; 68436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VexGuestARM64State vex_shadow2; 69436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}; 70436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 71436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstruct sigframe { 72436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov struct vki_ucontext uc; 73436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov unsigned long retcode[2]; 74436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov struct vg_sig_private vp; 75436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}; 76436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 77436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstruct rt_sigframe { 78436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vki_siginfo_t info; 79436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov struct sigframe sig; 80436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov}; 81436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 82436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic Bool extend ( ThreadState *tst, Addr addr, SizeT size ) 83436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 84436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ThreadId tid = tst->tid; 85436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov NSegment const* stackseg = NULL; 86436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 87436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (VG_(extend_stack)(addr, tst->client_stack_szB)) { 88436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov stackseg = VG_(am_find_nsegment)(addr); 89436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (0 && stackseg) 90436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(printf)("frame=%#lx seg=%#lx-%#lx\n", 91436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addr, stackseg->start, stackseg->end); 92436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 93436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 94436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) { 95436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(message)( 96436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Vg_UserMsg, 97436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "Can't extend stack to %#lx during signal delivery for thread %d:", 98436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov addr, tid); 99436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (stackseg == NULL) 100436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(message)(Vg_UserMsg, " no stack segment"); 101436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else 102436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(message)(Vg_UserMsg, " too small or bad protection modes"); 103436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 104436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* set SIGSEGV to default handler */ 105436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(set_default_handler)(VKI_SIGSEGV); 106436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(synth_fault_mapping)(tid, addr); 107436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 108436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* The whole process should be about to die, since the default 109436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov action of SIGSEGV to kill the whole process. */ 110436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return False; 111436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 112436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 113436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* For tracking memory events, indicate the entire frame has been 114436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov allocated. */ 115436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB, 116436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov size + VG_STACK_REDZONE_SZB, tid ); 117436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 118436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return True; 119436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 120436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 121436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void synth_ucontext( ThreadId tid, const vki_siginfo_t *si, 122436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord trapno, UWord err, const vki_sigset_t *set, 123436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov struct vki_ucontext *uc) 124436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 125436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 126436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ThreadState *tst = VG_(get_ThreadState)(tid); 127436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov struct vki_sigcontext *sc = &uc->uc_mcontext; 128436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 129436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(memset)(uc, 0, sizeof(*uc)); 130436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 131436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov uc->uc_flags = 0; 132436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov uc->uc_link = 0; 133436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov uc->uc_sigmask = *set; 134436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov uc->uc_stack = tst->altstack; 135436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 136436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# define SC2(reg) sc->regs[reg] = tst->arch.vex.guest_X##reg 137436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov SC2(0); SC2(1); SC2(2); SC2(3); 138436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov SC2(4); SC2(5); SC2(6); SC2(7); 139436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov SC2(8); SC2(9); SC2(10); SC2(11); 140436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov SC2(12); SC2(13); SC2(14); SC2(15); 141436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov SC2(16); SC2(17); SC2(18); SC2(19); 142436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov SC2(20); SC2(21); SC2(22); SC2(23); 143436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov SC2(24); SC2(25); SC2(26); SC2(27); 144436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov SC2(28); SC2(29); SC2(30); 145436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov# undef SC2 146436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sc->sp = tst->arch.vex.guest_XSP; 147436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sc->pc = tst->arch.vex.guest_PC; 148436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sc->pstate = 0; /* slack .. could do better */ 149436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 150436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov //sc->trap_no = trapno; 151436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov //sc->error_code = err; 152436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sc->fault_address = (ULong)si->_sifields._sigfault._addr; 153436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 154436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 155436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 156436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovstatic void build_sigframe(ThreadState *tst, 157436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov struct sigframe *frame, 158436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const vki_siginfo_t *siginfo, 159436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const struct vki_ucontext *siguc, 160436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov void *handler, UInt flags, 161436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const vki_sigset_t *mask, 162436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov void *restorer) 163436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 164436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord trapno; 165436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UWord err; 166436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int sigNo = siginfo->si_signo; 167436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov struct vg_sig_private *priv = &frame->vp; 168436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 169436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame", 170436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (Addr)frame, offsetof(struct sigframe, vp)); 171436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 172436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (siguc) { 173436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov trapno = 0; //siguc->uc_mcontext.trap_no; 174436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov err = 0; //siguc->uc_mcontext.error_code; 175436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } else { 176436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov trapno = 0; 177436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov err = 0; 178436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 179436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 180436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov synth_ucontext(tst->tid, siginfo, trapno, err, mask, &frame->uc); 181436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 182436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, 183436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (Addr)frame, offsetof(struct sigframe, vp)); 184436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 185436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov priv->magicPI = 0x31415927; 186436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov priv->sigNo_private = sigNo; 187436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov priv->vex = tst->arch.vex; 188436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov priv->vex_shadow1 = tst->arch.vex_shadow1; 189436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov priv->vex_shadow2 = tst->arch.vex_shadow2; 190436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 191436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 192436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 193436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* EXPORTED */ 194436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid VG_(sigframe_create)( ThreadId tid, 195436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Addr sp_top_of_frame, 196436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const vki_siginfo_t *siginfo, 197436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const struct vki_ucontext *siguc, 198436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov void *handler, 199436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt flags, 200436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov const vki_sigset_t *mask, 201436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov void *restorer ) 202436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 203436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ThreadState *tst; 204436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Addr sp = sp_top_of_frame; 205436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int sigNo = siginfo->si_signo; 206436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt size; 207436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 208436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tst = VG_(get_ThreadState)(tid); 209436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 210436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov size = sizeof(struct rt_sigframe); 211436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 212436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sp -= size; 213436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sp = VG_ROUNDDN(sp, 16); 214436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 215436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (!extend(tst, sp, size)) 216436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov return; // Give up. No idea if this is correct 217436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 218436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov struct rt_sigframe *rsf = (struct rt_sigframe *)sp; 219436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 220436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Track our writes to siginfo */ 221436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, /* VVVVV */ 222436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "signal handler siginfo", (Addr)rsf, 223436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov offsetof(struct rt_sigframe, sig)); 224436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 225436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(memcpy)(&rsf->info, siginfo, sizeof(vki_siginfo_t)); 226436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 227436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (sigNo == VKI_SIGILL && siginfo->si_code > 0) { 228436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov rsf->info._sifields._sigfault._addr 229436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = (Addr*)(tst)->arch.vex.guest_PC; 230436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov } 231436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, /* ^^^^^ */ 232436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov (Addr)rsf, offsetof(struct rt_sigframe, sig)); 233436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 234436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov build_sigframe(tst, &rsf->sig, siginfo, siguc, 235436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov handler, flags, mask, restorer); 236436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tst->arch.vex.guest_X1 = (Addr)&rsf->info; 237436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tst->arch.vex.guest_X2 = (Addr)&rsf->sig.uc; 238436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 239436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(set_SP)(tid, sp); 240436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, 241436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sizeof(Addr)); 242436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tst->arch.vex.guest_X0 = sigNo; 243436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 244436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (flags & VKI_SA_RESTORER) 245436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tst->arch.vex.guest_X30 = (Addr)restorer; 246436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov else 247436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tst->arch.vex.guest_X30 248436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov = (Addr)&VG_(arm64_linux_SUBST_FOR_rt_sigreturn); 249436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 250436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tst->arch.vex.guest_PC = (Addr)handler; 251436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 252436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 253436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 254436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*------------------------------------------------------------*/ 255436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--- Destroying signal frames ---*/ 256436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*------------------------------------------------------------*/ 257436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 258436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/* EXPORTED */ 259436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanovvoid VG_(sigframe_destroy)( ThreadId tid, Bool isRT ) 260436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov{ 261436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov ThreadState *tst; 262436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov struct vg_sig_private *priv; 263436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Addr sp; 264436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov UInt frame_size; 265436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ struct vki_sigcontext *mc; 266436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Int sigNo; 267436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov Bool has_siginfo = isRT; 268436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 269436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vg_assert(VG_(is_valid_tid)(tid)); 270436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tst = VG_(get_ThreadState)(tid); 271436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sp = tst->arch.vex.guest_XSP; 272436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 273436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ if (has_siginfo) { 274436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov struct rt_sigframe *frame = (struct rt_sigframe *)sp; 275436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov frame_size = sizeof(*frame); 276436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov //mc = &frame->sig.uc.uc_mcontext; 277436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov priv = &frame->sig.vp; 278436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov vg_assert(priv->magicPI == 0x31415927); 279436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tst->sig_mask = frame->sig.uc.uc_sigmask; 280436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } else { 281436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ struct sigframe *frame = (struct sigframe *)sp; 282436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ frame_size = sizeof(*frame); 283436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ mc = &frame->uc.uc_mcontext; 284436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ priv = &frame->vp; 285436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ vg_assert(priv->magicPI == 0x31415927); 286436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ tst->sig_mask = frame->uc.uc_sigmask; 287436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ //VG_(printf)("Setting signmask to %08x%08x\n", 288436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ // tst->sig_mask[0],tst->sig_mask[1]); 289436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ } 290436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tst->tmp_sig_mask = tst->sig_mask; 291436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 292436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov sigNo = priv->sigNo_private; 293436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 294436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ //XXX: restore regs 295436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ # define REST(reg,REG) tst->arch.vex.guest_##REG = mc->arm_##reg; 296436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ REST(r0,R0); 297436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ REST(r1,R1); 298436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ REST(r2,R2); 299436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ REST(r3,R3); 300436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ REST(r4,R4); 301436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ REST(r5,R5); 302436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ REST(r6,R6); 303436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ REST(r7,R7); 304436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ REST(r8,R8); 305436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ REST(r9,R9); 306436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ REST(r10,R10); 307436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ REST(fp,R11); 308436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ REST(ip,R12); 309436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ REST(sp,R13); 310436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ REST(lr,R14); 311436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ REST(pc,R15T); 312436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov//ZZ # undef REST 313436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 314436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* Uh, the next line makes all the REST() above pointless. */ 315436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tst->arch.vex = priv->vex; 316436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 317436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tst->arch.vex_shadow1 = priv->vex_shadow1; 318436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tst->arch.vex_shadow2 = priv->vex_shadow2; 319436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 320436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_TRACK( die_mem_stack_signal, sp - VG_STACK_REDZONE_SZB, 321436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov frame_size + VG_STACK_REDZONE_SZB ); 322436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 323436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov if (VG_(clo_trace_signals)) 324436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_(message)(Vg_DebugMsg, 325436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "vg_pop_signal_frame (thread %d): " 326436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov "isRT=%d valid magic; PC=%#llx\n", 327436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov tid, has_siginfo, tst->arch.vex.guest_PC); 328436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 329436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov /* tell the tools */ 330436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov VG_TRACK( post_deliver_signal, tid, sigNo ); 331436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov} 332436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 333436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov#endif // defined(VGP_arm_linux) 334436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov 335436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--------------------------------------------------------------------*/ 336436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--- end sigframe-arm64-linux.c ---*/ 337436e89c602e787e7a27dd6624b09beed41a0da8aDmitriy Ivanov/*--------------------------------------------------------------------*/ 338