1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 2c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch/*--------------------------------------------------------------------*/ 3c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch/*--- Create/destroy signal delivery frames. ---*/ 4c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch/*--- sigframe-arm-linux.c ---*/ 5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch/*--------------------------------------------------------------------*/ 6c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 70529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch/* 80529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch This file is part of Valgrind, a dynamic binary instrumentation 9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch framework. 10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Copyright (C) 2000-2013 Nicholas Nethercote 120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch njn@valgrind.org 130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Copyright (C) 2004-2013 Paul Mackerras 140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch paulus@samba.org 15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Copyright (C) 2008-2013 Evan Geller 16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gaze@bea.ms 17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch This program is free software; you can redistribute it and/or 19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch modify it under the terms of the GNU General Public License as 20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch published by the Free Software Foundation; either version 2 of the 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch License, or (at your option) any later version. 22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch This program is distributed in the hope that it will be useful, but 24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch WITHOUT ANY WARRANTY; without even the implied warranty of 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch General Public License for more details. 27c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch You should have received a copy of the GNU General Public License 290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch along with this program; if not, write to the Free Software 300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 02111-1307, USA. 320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch The GNU General Public License is contained in the file COPYING. 340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch*/ 350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#if defined(VGP_arm_linux) 370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "pub_core_basics.h" 390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "pub_core_vki.h" 400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "pub_core_vkiscnums.h" 410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy 420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "pub_core_threadstate.h" 430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "pub_core_aspacemgr.h" 440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "pub_core_libcbase.h" 450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "pub_core_libcassert.h" 460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "pub_core_libcprint.h" 470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "pub_core_machine.h" 480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "pub_core_options.h" 490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "pub_core_sigframe.h" 500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "pub_core_signals.h" 510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "pub_core_tooliface.h" 520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "pub_core_trampoline.h" 530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "pub_core_transtab.h" // VG_(discard_translations) 540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch/* This uses the hack of dumping the vex guest state along with both 570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch shadows in the frame, and restoring it afterwards from there, 580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch rather than pulling it out of the ucontext. That means that signal 590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch handlers which modify the ucontext and then return, expecting their 600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch modifications to take effect, will have those modifications 610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ignored. This could be fixed properly with an hour or so more 620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch effort. */ 630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstruct vg_sig_private { 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UInt magicPI; 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UInt sigNo_private; 680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VexGuestARMState vex; 690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VexGuestARMState vex_shadow1; 700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VexGuestARMState vex_shadow2; 710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}; 720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstruct sigframe { 740529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch struct vki_ucontext uc; 750529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch unsigned long retcode[2]; 760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch struct vg_sig_private vp; 770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}; 780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochstruct rt_sigframe { 800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch vki_siginfo_t info; 810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch struct sigframe sig; 825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}; 835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustatic Bool extend ( ThreadState *tst, Addr addr, SizeT size ) 855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu{ 865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ThreadId tid = tst->tid; 875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu NSegment const* stackseg = NULL; 885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (VG_(extend_stack)(addr, tst->client_stack_szB)) { 905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu stackseg = VG_(am_find_nsegment)(addr); 915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (0 && stackseg) 925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VG_(printf)("frame=%#lx seg=%#lx-%#lx\n", 935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu addr, stackseg->start, stackseg->end); 945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) { 975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VG_(message)( 985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu Vg_UserMsg, 995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu "Can't extend stack to %#lx during signal delivery for thread %d:", 1005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu addr, tid); 1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (stackseg == NULL) 1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VG_(message)(Vg_UserMsg, " no stack segment"); 1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu else 1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VG_(message)(Vg_UserMsg, " too small or bad protection modes"); 1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu /* set SIGSEGV to default handler */ 1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VG_(set_default_handler)(VKI_SIGSEGV); 1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VG_(synth_fault_mapping)(tid, addr); 1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu /* The whole process should be about to die, since the default 1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu action of SIGSEGV to kill the whole process. */ 1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return False; 1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu /* For tracking memory events, indicate the entire frame has been 1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu allocated. */ 1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB, 1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu size + VG_STACK_REDZONE_SZB, tid ); 1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return True; 1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustatic void synth_ucontext( ThreadId tid, const vki_siginfo_t *si, 1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu UWord trapno, UWord err, const vki_sigset_t *set, 125f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) struct vki_ucontext *uc){ 1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ThreadState *tst = VG_(get_ThreadState)(tid); 1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu struct vki_sigcontext *sc = &uc->uc_mcontext; 1295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu VG_(memset)(uc, 0, sizeof(*uc)); 1315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uc->uc_flags = 0; 133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch uc->uc_link = 0; 1345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu uc->uc_sigmask = *set; 1355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu uc->uc_stack = tst->altstack; 1365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu# define SC2(reg,REG) sc->arm_##reg = tst->arch.vex.guest_##REG 1385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SC2(r0,R0); 1395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SC2(r1,R1); 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SC2(r2,R2); 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SC2(r3,R3); 1425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SC2(r4,R4); 1435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SC2(r5,R5); 1445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SC2(r6,R6); 1455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SC2(r7,R7); 1465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SC2(r8,R8); 1475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SC2(r9,R9); 1485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SC2(r10,R10); 1495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SC2(fp,R11); 1505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SC2(ip,R12); 1515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SC2(sp,R13); 1525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SC2(lr,R14); 1535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SC2(pc,R15T); 1545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu# undef SC2 1555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu sc->trap_no = trapno; 1575c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu sc->error_code = err; 158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sc->fault_address = (UInt)si->_sifields._sigfault._addr; 159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic void build_sigframe(ThreadState *tst, 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci struct sigframe *frame, 1640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const vki_siginfo_t *siginfo, 1650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const struct vki_ucontext *siguc, 1660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void *handler, UInt flags, 1670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const vki_sigset_t *mask, 1680529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void *restorer){ 1690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch UWord trapno; 1710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch UWord err; 172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Int sigNo = siginfo->si_signo; 173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch struct vg_sig_private *priv = &frame->vp; 174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame", 176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch (Addr)frame, offsetof(struct sigframe, vp)); 177c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if(siguc) { 1790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch trapno = siguc->uc_mcontext.trap_no; 1800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch err = siguc->uc_mcontext.error_code; 1810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } else { 1820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch trapno = 0; 1830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch err = 0; 1840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 1850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch synth_ucontext(tst->tid, siginfo, trapno, err, mask, &frame->uc); 1870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, 1890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch (Addr)frame, offsetof(struct sigframe, vp)); 1900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch priv->magicPI = 0x31415927; 1920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch priv->sigNo_private = sigNo; 1936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) priv->vex = tst->arch.vex; 1940529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch priv->vex_shadow1 = tst->arch.vex_shadow1; 1950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch priv->vex_shadow2 = tst->arch.vex_shadow2; 1960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 1980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 1990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 200c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 2010529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch/* EXPORTED */ 2020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid VG_(sigframe_create)( ThreadId tid, 203c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Addr sp_top_of_frame, 204c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const vki_siginfo_t *siginfo, 2050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const struct vki_ucontext *siguc, 2060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void *handler, 207c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch UInt flags, 2080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const vki_sigset_t *mask, 2090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch void *restorer ) 210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch{ 2110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// struct vg_sig_private *priv; 2120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Addr sp = sp_top_of_frame; 213c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ThreadState *tst; 2140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Int sigNo = siginfo->si_signo; 2150529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Addr faultaddr; 216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch UInt size; 2170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 218c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch tst = VG_(get_ThreadState)(tid); 219c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 220c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch size = flags & VKI_SA_SIGINFO ? sizeof(struct rt_sigframe) : 221c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch sizeof(struct sigframe); 2220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch sp -= size; 224c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch sp = VG_ROUNDDN(sp, 16); 2250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if(!extend(tst, sp, size)) 227c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch I_die_here; // XXX Incorrect behavior 2280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (flags & VKI_SA_SIGINFO){ 231c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch struct rt_sigframe *rsf = (struct rt_sigframe *)sp; 2320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch /* Track our writes to siginfo */ 2340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, /* VVVVV */ 2350529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch "signal handler siginfo", (Addr)rsf, 2360529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch offsetof(struct rt_sigframe, sig)); 2370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VG_(memcpy)(&rsf->info, siginfo, sizeof(vki_siginfo_t)); 239c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 2400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if(sigNo == VKI_SIGILL && siginfo->si_code > 0) { 2410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch rsf->info._sifields._sigfault._addr = (Addr *) (tst)->arch.vex.guest_R12; /* IP */ 2420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, /* ^^^^^ */ 2440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch (Addr)rsf, offsetof(struct rt_sigframe, sig)); 2450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch build_sigframe(tst, &rsf->sig, siginfo, siguc, 2470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch handler, flags, mask, restorer); 248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch tst->arch.vex.guest_R1 = (Addr)&rsf->info; 249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch tst->arch.vex.guest_R2 = (Addr)&rsf->sig.uc; 2500529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 2510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch else { 252c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch build_sigframe(tst, (struct sigframe *)sp, siginfo, siguc, 2530529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch handler, flags, mask, restorer); 2540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 255c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 2560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VG_(set_SP)(tid, sp); 2570529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, 258c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch sizeof(Addr)); 259c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch tst->arch.vex.guest_R0 = sigNo; 2600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2610529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (flags & VKI_SA_RESTORER) 2620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch tst->arch.vex.guest_R14 = (Addr)restorer; 2630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch else 264c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch tst->arch.vex.guest_R14 2650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch = (flags & VKI_SA_SIGINFO) 2660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ? (Addr)&VG_(arm_linux_SUBST_FOR_rt_sigreturn) 2670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch : (Addr)&VG_(arm_linux_SUBST_FOR_sigreturn); 268c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 269c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch tst->arch.vex.guest_R15T = (Addr) handler; /* R15 == PC */ 2700529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 2710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch/*------------------------------------------------------------*/ 274c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch/*--- Destroying signal frames ---*/ 275c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch/*------------------------------------------------------------*/ 2760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch/* EXPORTED */ 2780529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid VG_(sigframe_destroy)( ThreadId tid, Bool isRT ) 2790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch{ 280c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ThreadState *tst; 281c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch struct vg_sig_private *priv; 2820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Addr sp; 2830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch UInt frame_size; 2840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch struct vki_sigcontext *mc; 2850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Int sigNo; 286c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Bool has_siginfo = isRT; 287c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 2880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch vg_assert(VG_(is_valid_tid)(tid)); 2890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch tst = VG_(get_ThreadState)(tid); 2900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch sp = tst->arch.vex.guest_R13; 2910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 2920529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (has_siginfo) { 293c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch struct rt_sigframe *frame = (struct rt_sigframe *)sp; 294c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch frame_size = sizeof(*frame); 2950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch mc = &frame->sig.uc.uc_mcontext; 2960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch priv = &frame->sig.vp; 2970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch vg_assert(priv->magicPI == 0x31415927); 298c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch tst->sig_mask = frame->sig.uc.uc_sigmask; 299c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else { 3000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch struct sigframe *frame = (struct sigframe *)sp; 301c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch frame_size = sizeof(*frame); 302c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch mc = &frame->uc.uc_mcontext; 303c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch priv = &frame->vp; 304c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch vg_assert(priv->magicPI == 0x31415927); 3050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch tst->sig_mask = frame->uc.uc_sigmask; 306c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch /*tst->sig_mask.sig[0] = frame->uc.uc_mcontext.oldmask; 307c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch tst->sig_mask.sig[1] = frame->uc.uc_mcontext._unused[3]; 308c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch VG_(printf)("Setting signmask to %08x%08x\n",tst->sig_mask[0],tst->sig_mask[1]); 309*/ 310 } 311 tst->tmp_sig_mask = tst->sig_mask; 312 313 sigNo = priv->sigNo_private; 314 315 //XXX: restore regs 316# define REST(reg,REG) tst->arch.vex.guest_##REG = mc->arm_##reg; 317 REST(r0,R0); 318 REST(r1,R1); 319 REST(r2,R2); 320 REST(r3,R3); 321 REST(r4,R4); 322 REST(r5,R5); 323 REST(r6,R6); 324 REST(r7,R7); 325 REST(r8,R8); 326 REST(r9,R9); 327 REST(r10,R10); 328 REST(fp,R11); 329 REST(ip,R12); 330 REST(sp,R13); 331 REST(lr,R14); 332 REST(pc,R15T); 333# undef REST 334 335 /* Uh, the next line makes all the REST() above pointless. */ 336 tst->arch.vex = priv->vex; 337 338 tst->arch.vex_shadow1 = priv->vex_shadow1; 339 tst->arch.vex_shadow2 = priv->vex_shadow2; 340 341 VG_TRACK( die_mem_stack_signal, sp - VG_STACK_REDZONE_SZB, 342 frame_size + VG_STACK_REDZONE_SZB ); 343 344 if (VG_(clo_trace_signals)) 345 VG_(message)(Vg_DebugMsg, 346 "vg_pop_signal_frame (thread %d): " 347 "isRT=%d valid magic; PC=%#x\n", 348 tid, has_siginfo, tst->arch.vex.guest_R15T); 349 350 /* tell the tools */ 351 VG_TRACK( post_deliver_signal, tid, sigNo ); 352} 353 354#endif // defined(VGP_arm_linux) 355 356/*--------------------------------------------------------------------*/ 357/*--- end sigframe-arm-linux.c ---*/ 358/*--------------------------------------------------------------------*/ 359