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