159570ffbe31930ab4d678754daaeec0715117a3dsewardj
259570ffbe31930ab4d678754daaeec0715117a3dsewardj/*--------------------------------------------------------------------*/
359570ffbe31930ab4d678754daaeec0715117a3dsewardj/*--- Create/destroy signal delivery frames.                       ---*/
459570ffbe31930ab4d678754daaeec0715117a3dsewardj/*---                                         sigframe-arm-linux.c ---*/
559570ffbe31930ab4d678754daaeec0715117a3dsewardj/*--------------------------------------------------------------------*/
659570ffbe31930ab4d678754daaeec0715117a3dsewardj
759570ffbe31930ab4d678754daaeec0715117a3dsewardj/*
859570ffbe31930ab4d678754daaeec0715117a3dsewardj   This file is part of Valgrind, a dynamic binary instrumentation
959570ffbe31930ab4d678754daaeec0715117a3dsewardj   framework.
1059570ffbe31930ab4d678754daaeec0715117a3dsewardj
11ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes   Copyright (C) 2000-2017 Nicholas Nethercote
1259570ffbe31930ab4d678754daaeec0715117a3dsewardj      njn@valgrind.org
13ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes   Copyright (C) 2004-2017 Paul Mackerras
1459570ffbe31930ab4d678754daaeec0715117a3dsewardj      paulus@samba.org
15ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes   Copyright (C) 2008-2017 Evan Geller
1659570ffbe31930ab4d678754daaeec0715117a3dsewardj      gaze@bea.ms
1759570ffbe31930ab4d678754daaeec0715117a3dsewardj
1859570ffbe31930ab4d678754daaeec0715117a3dsewardj   This program is free software; you can redistribute it and/or
1959570ffbe31930ab4d678754daaeec0715117a3dsewardj   modify it under the terms of the GNU General Public License as
2059570ffbe31930ab4d678754daaeec0715117a3dsewardj   published by the Free Software Foundation; either version 2 of the
2159570ffbe31930ab4d678754daaeec0715117a3dsewardj   License, or (at your option) any later version.
2259570ffbe31930ab4d678754daaeec0715117a3dsewardj
2359570ffbe31930ab4d678754daaeec0715117a3dsewardj   This program is distributed in the hope that it will be useful, but
2459570ffbe31930ab4d678754daaeec0715117a3dsewardj   WITHOUT ANY WARRANTY; without even the implied warranty of
2559570ffbe31930ab4d678754daaeec0715117a3dsewardj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
2659570ffbe31930ab4d678754daaeec0715117a3dsewardj   General Public License for more details.
2759570ffbe31930ab4d678754daaeec0715117a3dsewardj
2859570ffbe31930ab4d678754daaeec0715117a3dsewardj   You should have received a copy of the GNU General Public License
2959570ffbe31930ab4d678754daaeec0715117a3dsewardj   along with this program; if not, write to the Free Software
3059570ffbe31930ab4d678754daaeec0715117a3dsewardj   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
3159570ffbe31930ab4d678754daaeec0715117a3dsewardj   02111-1307, USA.
3259570ffbe31930ab4d678754daaeec0715117a3dsewardj
3359570ffbe31930ab4d678754daaeec0715117a3dsewardj   The GNU General Public License is contained in the file COPYING.
3459570ffbe31930ab4d678754daaeec0715117a3dsewardj*/
3559570ffbe31930ab4d678754daaeec0715117a3dsewardj
3659570ffbe31930ab4d678754daaeec0715117a3dsewardj#if defined(VGP_arm_linux)
3759570ffbe31930ab4d678754daaeec0715117a3dsewardj
3859570ffbe31930ab4d678754daaeec0715117a3dsewardj#include "pub_core_basics.h"
3959570ffbe31930ab4d678754daaeec0715117a3dsewardj#include "pub_core_vki.h"
4059570ffbe31930ab4d678754daaeec0715117a3dsewardj#include "pub_core_vkiscnums.h"
4159570ffbe31930ab4d678754daaeec0715117a3dsewardj#include "pub_core_threadstate.h"
4259570ffbe31930ab4d678754daaeec0715117a3dsewardj#include "pub_core_aspacemgr.h"
4359570ffbe31930ab4d678754daaeec0715117a3dsewardj#include "pub_core_libcbase.h"
4459570ffbe31930ab4d678754daaeec0715117a3dsewardj#include "pub_core_libcassert.h"
4559570ffbe31930ab4d678754daaeec0715117a3dsewardj#include "pub_core_libcprint.h"
4659570ffbe31930ab4d678754daaeec0715117a3dsewardj#include "pub_core_machine.h"
4759570ffbe31930ab4d678754daaeec0715117a3dsewardj#include "pub_core_options.h"
4859570ffbe31930ab4d678754daaeec0715117a3dsewardj#include "pub_core_sigframe.h"
4959570ffbe31930ab4d678754daaeec0715117a3dsewardj#include "pub_core_signals.h"
5059570ffbe31930ab4d678754daaeec0715117a3dsewardj#include "pub_core_tooliface.h"
5159570ffbe31930ab4d678754daaeec0715117a3dsewardj#include "pub_core_trampoline.h"
5201fcf6a890ad645e4ccbf731264f19f850898c5eflorian#include "priv_sigframe.h"
5359570ffbe31930ab4d678754daaeec0715117a3dsewardj
5459570ffbe31930ab4d678754daaeec0715117a3dsewardj
55320dee232d277b1402c429f25e89e2528c230089sewardj/* This uses the hack of dumping the vex guest state along with both
56320dee232d277b1402c429f25e89e2528c230089sewardj   shadows in the frame, and restoring it afterwards from there,
57320dee232d277b1402c429f25e89e2528c230089sewardj   rather than pulling it out of the ucontext.  That means that signal
58320dee232d277b1402c429f25e89e2528c230089sewardj   handlers which modify the ucontext and then return, expecting their
59320dee232d277b1402c429f25e89e2528c230089sewardj   modifications to take effect, will have those modifications
60320dee232d277b1402c429f25e89e2528c230089sewardj   ignored.  This could be fixed properly with an hour or so more
61320dee232d277b1402c429f25e89e2528c230089sewardj   effort. */
62320dee232d277b1402c429f25e89e2528c230089sewardj
63320dee232d277b1402c429f25e89e2528c230089sewardj
6459570ffbe31930ab4d678754daaeec0715117a3dsewardjstruct vg_sig_private {
6559570ffbe31930ab4d678754daaeec0715117a3dsewardj   UInt magicPI;
6659570ffbe31930ab4d678754daaeec0715117a3dsewardj   UInt sigNo_private;
67320dee232d277b1402c429f25e89e2528c230089sewardj   VexGuestARMState vex;
6859570ffbe31930ab4d678754daaeec0715117a3dsewardj   VexGuestARMState vex_shadow1;
6959570ffbe31930ab4d678754daaeec0715117a3dsewardj   VexGuestARMState vex_shadow2;
7059570ffbe31930ab4d678754daaeec0715117a3dsewardj};
7159570ffbe31930ab4d678754daaeec0715117a3dsewardj
7259570ffbe31930ab4d678754daaeec0715117a3dsewardjstruct sigframe {
7359570ffbe31930ab4d678754daaeec0715117a3dsewardj   struct vki_ucontext uc;
7459570ffbe31930ab4d678754daaeec0715117a3dsewardj   unsigned long retcode[2];
7559570ffbe31930ab4d678754daaeec0715117a3dsewardj   struct vg_sig_private vp;
7659570ffbe31930ab4d678754daaeec0715117a3dsewardj};
7759570ffbe31930ab4d678754daaeec0715117a3dsewardj
7859570ffbe31930ab4d678754daaeec0715117a3dsewardjstruct rt_sigframe {
7959570ffbe31930ab4d678754daaeec0715117a3dsewardj   vki_siginfo_t info;
8059570ffbe31930ab4d678754daaeec0715117a3dsewardj   struct sigframe sig;
8159570ffbe31930ab4d678754daaeec0715117a3dsewardj};
8259570ffbe31930ab4d678754daaeec0715117a3dsewardj
8359570ffbe31930ab4d678754daaeec0715117a3dsewardj
8459570ffbe31930ab4d678754daaeec0715117a3dsewardjstatic void synth_ucontext( ThreadId tid, const vki_siginfo_t *si,
8559570ffbe31930ab4d678754daaeec0715117a3dsewardj                    UWord trapno, UWord err, const vki_sigset_t *set,
8659570ffbe31930ab4d678754daaeec0715117a3dsewardj                    struct vki_ucontext *uc){
8759570ffbe31930ab4d678754daaeec0715117a3dsewardj
8859570ffbe31930ab4d678754daaeec0715117a3dsewardj   ThreadState *tst = VG_(get_ThreadState)(tid);
8959570ffbe31930ab4d678754daaeec0715117a3dsewardj   struct vki_sigcontext *sc = &uc->uc_mcontext;
9059570ffbe31930ab4d678754daaeec0715117a3dsewardj
9159570ffbe31930ab4d678754daaeec0715117a3dsewardj   VG_(memset)(uc, 0, sizeof(*uc));
9259570ffbe31930ab4d678754daaeec0715117a3dsewardj
9359570ffbe31930ab4d678754daaeec0715117a3dsewardj   uc->uc_flags = 0;
9459570ffbe31930ab4d678754daaeec0715117a3dsewardj   uc->uc_link = 0;
9559570ffbe31930ab4d678754daaeec0715117a3dsewardj   uc->uc_sigmask = *set;
9659570ffbe31930ab4d678754daaeec0715117a3dsewardj   uc->uc_stack = tst->altstack;
9759570ffbe31930ab4d678754daaeec0715117a3dsewardj
9859570ffbe31930ab4d678754daaeec0715117a3dsewardj#  define SC2(reg,REG)  sc->arm_##reg = tst->arch.vex.guest_##REG
9959570ffbe31930ab4d678754daaeec0715117a3dsewardj   SC2(r0,R0);
10059570ffbe31930ab4d678754daaeec0715117a3dsewardj   SC2(r1,R1);
10159570ffbe31930ab4d678754daaeec0715117a3dsewardj   SC2(r2,R2);
10259570ffbe31930ab4d678754daaeec0715117a3dsewardj   SC2(r3,R3);
10359570ffbe31930ab4d678754daaeec0715117a3dsewardj   SC2(r4,R4);
10459570ffbe31930ab4d678754daaeec0715117a3dsewardj   SC2(r5,R5);
10559570ffbe31930ab4d678754daaeec0715117a3dsewardj   SC2(r6,R6);
10659570ffbe31930ab4d678754daaeec0715117a3dsewardj   SC2(r7,R7);
10759570ffbe31930ab4d678754daaeec0715117a3dsewardj   SC2(r8,R8);
10859570ffbe31930ab4d678754daaeec0715117a3dsewardj   SC2(r9,R9);
10959570ffbe31930ab4d678754daaeec0715117a3dsewardj   SC2(r10,R10);
11059570ffbe31930ab4d678754daaeec0715117a3dsewardj   SC2(fp,R11);
11159570ffbe31930ab4d678754daaeec0715117a3dsewardj   SC2(ip,R12);
11259570ffbe31930ab4d678754daaeec0715117a3dsewardj   SC2(sp,R13);
11359570ffbe31930ab4d678754daaeec0715117a3dsewardj   SC2(lr,R14);
1149dcfdffec13e259386e088f9be86ea8b8e2756c0sewardj   SC2(pc,R15T);
11559570ffbe31930ab4d678754daaeec0715117a3dsewardj#  undef SC2
11659570ffbe31930ab4d678754daaeec0715117a3dsewardj
11759570ffbe31930ab4d678754daaeec0715117a3dsewardj   sc->trap_no = trapno;
11859570ffbe31930ab4d678754daaeec0715117a3dsewardj   sc->error_code = err;
11959570ffbe31930ab4d678754daaeec0715117a3dsewardj   sc->fault_address = (UInt)si->_sifields._sigfault._addr;
12059570ffbe31930ab4d678754daaeec0715117a3dsewardj}
12159570ffbe31930ab4d678754daaeec0715117a3dsewardj
12259570ffbe31930ab4d678754daaeec0715117a3dsewardj
12359570ffbe31930ab4d678754daaeec0715117a3dsewardjstatic void build_sigframe(ThreadState *tst,
12459570ffbe31930ab4d678754daaeec0715117a3dsewardj            struct sigframe *frame,
12559570ffbe31930ab4d678754daaeec0715117a3dsewardj            const vki_siginfo_t *siginfo,
12659570ffbe31930ab4d678754daaeec0715117a3dsewardj            const struct vki_ucontext *siguc,
12759570ffbe31930ab4d678754daaeec0715117a3dsewardj            void *handler, UInt flags,
12859570ffbe31930ab4d678754daaeec0715117a3dsewardj            const vki_sigset_t *mask,
12959570ffbe31930ab4d678754daaeec0715117a3dsewardj            void *restorer){
13059570ffbe31930ab4d678754daaeec0715117a3dsewardj
13159570ffbe31930ab4d678754daaeec0715117a3dsewardj   UWord trapno;
13259570ffbe31930ab4d678754daaeec0715117a3dsewardj   UWord err;
13359570ffbe31930ab4d678754daaeec0715117a3dsewardj   Int  sigNo = siginfo->si_signo;
13459570ffbe31930ab4d678754daaeec0715117a3dsewardj   struct vg_sig_private *priv = &frame->vp;
13559570ffbe31930ab4d678754daaeec0715117a3dsewardj
13659570ffbe31930ab4d678754daaeec0715117a3dsewardj   VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame",
13759570ffbe31930ab4d678754daaeec0715117a3dsewardj         (Addr)frame, offsetof(struct sigframe, vp));
13859570ffbe31930ab4d678754daaeec0715117a3dsewardj
13959570ffbe31930ab4d678754daaeec0715117a3dsewardj   if(siguc) {
14059570ffbe31930ab4d678754daaeec0715117a3dsewardj      trapno = siguc->uc_mcontext.trap_no;
14159570ffbe31930ab4d678754daaeec0715117a3dsewardj      err = siguc->uc_mcontext.error_code;
14259570ffbe31930ab4d678754daaeec0715117a3dsewardj   } else {
14359570ffbe31930ab4d678754daaeec0715117a3dsewardj      trapno = 0;
14459570ffbe31930ab4d678754daaeec0715117a3dsewardj      err = 0;
14559570ffbe31930ab4d678754daaeec0715117a3dsewardj   }
14659570ffbe31930ab4d678754daaeec0715117a3dsewardj
14759570ffbe31930ab4d678754daaeec0715117a3dsewardj   synth_ucontext(tst->tid, siginfo, trapno, err, mask, &frame->uc);
14859570ffbe31930ab4d678754daaeec0715117a3dsewardj
14959570ffbe31930ab4d678754daaeec0715117a3dsewardj   VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
15059570ffbe31930ab4d678754daaeec0715117a3dsewardj         (Addr)frame, offsetof(struct sigframe, vp));
15159570ffbe31930ab4d678754daaeec0715117a3dsewardj
15259570ffbe31930ab4d678754daaeec0715117a3dsewardj   priv->magicPI = 0x31415927;
15359570ffbe31930ab4d678754daaeec0715117a3dsewardj   priv->sigNo_private = sigNo;
154320dee232d277b1402c429f25e89e2528c230089sewardj   priv->vex         = tst->arch.vex;
15559570ffbe31930ab4d678754daaeec0715117a3dsewardj   priv->vex_shadow1 = tst->arch.vex_shadow1;
15659570ffbe31930ab4d678754daaeec0715117a3dsewardj   priv->vex_shadow2 = tst->arch.vex_shadow2;
15759570ffbe31930ab4d678754daaeec0715117a3dsewardj
15859570ffbe31930ab4d678754daaeec0715117a3dsewardj}
15959570ffbe31930ab4d678754daaeec0715117a3dsewardj
16059570ffbe31930ab4d678754daaeec0715117a3dsewardj
16159570ffbe31930ab4d678754daaeec0715117a3dsewardj
16259570ffbe31930ab4d678754daaeec0715117a3dsewardj/* EXPORTED */
16359570ffbe31930ab4d678754daaeec0715117a3dsewardjvoid VG_(sigframe_create)( ThreadId tid,
1648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj                           Bool on_altstack,
16559570ffbe31930ab4d678754daaeec0715117a3dsewardj                           Addr sp_top_of_frame,
16659570ffbe31930ab4d678754daaeec0715117a3dsewardj                           const vki_siginfo_t *siginfo,
16759570ffbe31930ab4d678754daaeec0715117a3dsewardj                           const struct vki_ucontext *siguc,
16859570ffbe31930ab4d678754daaeec0715117a3dsewardj                           void *handler,
16959570ffbe31930ab4d678754daaeec0715117a3dsewardj                           UInt flags,
17059570ffbe31930ab4d678754daaeec0715117a3dsewardj                           const vki_sigset_t *mask,
17159570ffbe31930ab4d678754daaeec0715117a3dsewardj                           void *restorer )
17259570ffbe31930ab4d678754daaeec0715117a3dsewardj{
17359570ffbe31930ab4d678754daaeec0715117a3dsewardj//   struct vg_sig_private *priv;
17459570ffbe31930ab4d678754daaeec0715117a3dsewardj   Addr sp = sp_top_of_frame;
17559570ffbe31930ab4d678754daaeec0715117a3dsewardj   ThreadState *tst;
17659570ffbe31930ab4d678754daaeec0715117a3dsewardj   Int sigNo = siginfo->si_signo;
17759570ffbe31930ab4d678754daaeec0715117a3dsewardj//   Addr faultaddr;
17859570ffbe31930ab4d678754daaeec0715117a3dsewardj   UInt size;
17959570ffbe31930ab4d678754daaeec0715117a3dsewardj
18059570ffbe31930ab4d678754daaeec0715117a3dsewardj   tst = VG_(get_ThreadState)(tid);
18159570ffbe31930ab4d678754daaeec0715117a3dsewardj
18259570ffbe31930ab4d678754daaeec0715117a3dsewardj   size = flags & VKI_SA_SIGINFO ? sizeof(struct rt_sigframe) :
18359570ffbe31930ab4d678754daaeec0715117a3dsewardj      sizeof(struct sigframe);
18459570ffbe31930ab4d678754daaeec0715117a3dsewardj
18559570ffbe31930ab4d678754daaeec0715117a3dsewardj   sp -= size;
18659570ffbe31930ab4d678754daaeec0715117a3dsewardj   sp = VG_ROUNDDN(sp, 16);
18759570ffbe31930ab4d678754daaeec0715117a3dsewardj
1887d4a28b986eaf98814c530a2074e117145b14d1fflorian   if (! ML_(sf_maybe_extend_stack)(tst, sp, size, flags))
18959570ffbe31930ab4d678754daaeec0715117a3dsewardj      I_die_here; // XXX Incorrect behavior
19059570ffbe31930ab4d678754daaeec0715117a3dsewardj
19159570ffbe31930ab4d678754daaeec0715117a3dsewardj
19259570ffbe31930ab4d678754daaeec0715117a3dsewardj   if (flags & VKI_SA_SIGINFO){
19359570ffbe31930ab4d678754daaeec0715117a3dsewardj      struct rt_sigframe *rsf = (struct rt_sigframe *)sp;
19459570ffbe31930ab4d678754daaeec0715117a3dsewardj
19559570ffbe31930ab4d678754daaeec0715117a3dsewardj      /* Track our writes to siginfo */
19659570ffbe31930ab4d678754daaeec0715117a3dsewardj      VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid,  /* VVVVV */
19759570ffbe31930ab4d678754daaeec0715117a3dsewardj            "signal handler siginfo", (Addr)rsf,
19859570ffbe31930ab4d678754daaeec0715117a3dsewardj            offsetof(struct rt_sigframe, sig));
19959570ffbe31930ab4d678754daaeec0715117a3dsewardj
20059570ffbe31930ab4d678754daaeec0715117a3dsewardj      VG_(memcpy)(&rsf->info, siginfo, sizeof(vki_siginfo_t));
20159570ffbe31930ab4d678754daaeec0715117a3dsewardj
20259570ffbe31930ab4d678754daaeec0715117a3dsewardj      if(sigNo == VKI_SIGILL && siginfo->si_code > 0) {
20359570ffbe31930ab4d678754daaeec0715117a3dsewardj         rsf->info._sifields._sigfault._addr = (Addr *) (tst)->arch.vex.guest_R12; /* IP */
20459570ffbe31930ab4d678754daaeec0715117a3dsewardj      }
20559570ffbe31930ab4d678754daaeec0715117a3dsewardj      VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, /* ^^^^^ */
20659570ffbe31930ab4d678754daaeec0715117a3dsewardj            (Addr)rsf, offsetof(struct rt_sigframe, sig));
20759570ffbe31930ab4d678754daaeec0715117a3dsewardj
20859570ffbe31930ab4d678754daaeec0715117a3dsewardj      build_sigframe(tst, &rsf->sig, siginfo, siguc,
20959570ffbe31930ab4d678754daaeec0715117a3dsewardj                             handler, flags, mask, restorer);
21059570ffbe31930ab4d678754daaeec0715117a3dsewardj      tst->arch.vex.guest_R1 = (Addr)&rsf->info;
21159570ffbe31930ab4d678754daaeec0715117a3dsewardj      tst->arch.vex.guest_R2 = (Addr)&rsf->sig.uc;
21259570ffbe31930ab4d678754daaeec0715117a3dsewardj   }
2139dcfdffec13e259386e088f9be86ea8b8e2756c0sewardj   else {
21459570ffbe31930ab4d678754daaeec0715117a3dsewardj      build_sigframe(tst, (struct sigframe *)sp, siginfo, siguc,
21559570ffbe31930ab4d678754daaeec0715117a3dsewardj                             handler, flags, mask, restorer);
2169dcfdffec13e259386e088f9be86ea8b8e2756c0sewardj   }
21759570ffbe31930ab4d678754daaeec0715117a3dsewardj
21859570ffbe31930ab4d678754daaeec0715117a3dsewardj   VG_(set_SP)(tid, sp);
21959570ffbe31930ab4d678754daaeec0715117a3dsewardj   VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR,
22059570ffbe31930ab4d678754daaeec0715117a3dsewardj         sizeof(Addr));
2219dcfdffec13e259386e088f9be86ea8b8e2756c0sewardj   tst->arch.vex.guest_R0  = sigNo;
22259570ffbe31930ab4d678754daaeec0715117a3dsewardj
2239dcfdffec13e259386e088f9be86ea8b8e2756c0sewardj   if (flags & VKI_SA_RESTORER)
224bc33be644b29fa5a4a92da20c340b9ccc9b9b925sewardj       tst->arch.vex.guest_R14 = (Addr)restorer;
225bc33be644b29fa5a4a92da20c340b9ccc9b9b925sewardj   else
226bc33be644b29fa5a4a92da20c340b9ccc9b9b925sewardj       tst->arch.vex.guest_R14
227bc33be644b29fa5a4a92da20c340b9ccc9b9b925sewardj          = (flags & VKI_SA_SIGINFO)
228bc33be644b29fa5a4a92da20c340b9ccc9b9b925sewardj            ? (Addr)&VG_(arm_linux_SUBST_FOR_rt_sigreturn)
229bc33be644b29fa5a4a92da20c340b9ccc9b9b925sewardj            : (Addr)&VG_(arm_linux_SUBST_FOR_sigreturn);
23059570ffbe31930ab4d678754daaeec0715117a3dsewardj
2319dcfdffec13e259386e088f9be86ea8b8e2756c0sewardj   tst->arch.vex.guest_R15T = (Addr) handler; /* R15 == PC */
2329bd33018713201d7f6962ccc6e99d1b0d31ee903sewardj
2339bd33018713201d7f6962ccc6e99d1b0d31ee903sewardj   if (VG_(clo_trace_signals))
2349bd33018713201d7f6962ccc6e99d1b0d31ee903sewardj      VG_(message)(Vg_DebugMsg,
235bba930d534f958a792037a413211fb3cf7db364csewardj                   "VG_(sigframe_create): continuing in handler with PC=%#lx\n",
2369bd33018713201d7f6962ccc6e99d1b0d31ee903sewardj                   (Addr)handler);
23759570ffbe31930ab4d678754daaeec0715117a3dsewardj}
23859570ffbe31930ab4d678754daaeec0715117a3dsewardj
23959570ffbe31930ab4d678754daaeec0715117a3dsewardj
24059570ffbe31930ab4d678754daaeec0715117a3dsewardj/*------------------------------------------------------------*/
24159570ffbe31930ab4d678754daaeec0715117a3dsewardj/*--- Destroying signal frames                             ---*/
24259570ffbe31930ab4d678754daaeec0715117a3dsewardj/*------------------------------------------------------------*/
24359570ffbe31930ab4d678754daaeec0715117a3dsewardj
24459570ffbe31930ab4d678754daaeec0715117a3dsewardj/* EXPORTED */
24559570ffbe31930ab4d678754daaeec0715117a3dsewardjvoid VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
24659570ffbe31930ab4d678754daaeec0715117a3dsewardj{
24759570ffbe31930ab4d678754daaeec0715117a3dsewardj   ThreadState *tst;
24859570ffbe31930ab4d678754daaeec0715117a3dsewardj   struct vg_sig_private *priv;
24959570ffbe31930ab4d678754daaeec0715117a3dsewardj   Addr sp;
25059570ffbe31930ab4d678754daaeec0715117a3dsewardj   UInt frame_size;
25159570ffbe31930ab4d678754daaeec0715117a3dsewardj   Int sigNo;
25259570ffbe31930ab4d678754daaeec0715117a3dsewardj   Bool has_siginfo = isRT;
25359570ffbe31930ab4d678754daaeec0715117a3dsewardj
25459570ffbe31930ab4d678754daaeec0715117a3dsewardj   vg_assert(VG_(is_valid_tid)(tid));
25559570ffbe31930ab4d678754daaeec0715117a3dsewardj   tst = VG_(get_ThreadState)(tid);
25659570ffbe31930ab4d678754daaeec0715117a3dsewardj   sp = tst->arch.vex.guest_R13;
25759570ffbe31930ab4d678754daaeec0715117a3dsewardj
25859570ffbe31930ab4d678754daaeec0715117a3dsewardj   if (has_siginfo) {
25959570ffbe31930ab4d678754daaeec0715117a3dsewardj      struct rt_sigframe *frame = (struct rt_sigframe *)sp;
26059570ffbe31930ab4d678754daaeec0715117a3dsewardj      frame_size = sizeof(*frame);
26159570ffbe31930ab4d678754daaeec0715117a3dsewardj      priv = &frame->sig.vp;
26259570ffbe31930ab4d678754daaeec0715117a3dsewardj      vg_assert(priv->magicPI == 0x31415927);
26359570ffbe31930ab4d678754daaeec0715117a3dsewardj      tst->sig_mask = frame->sig.uc.uc_sigmask;
26459570ffbe31930ab4d678754daaeec0715117a3dsewardj   } else {
26559570ffbe31930ab4d678754daaeec0715117a3dsewardj      struct sigframe *frame = (struct sigframe *)sp;
26659570ffbe31930ab4d678754daaeec0715117a3dsewardj      frame_size = sizeof(*frame);
26759570ffbe31930ab4d678754daaeec0715117a3dsewardj      priv = &frame->vp;
26859570ffbe31930ab4d678754daaeec0715117a3dsewardj      vg_assert(priv->magicPI == 0x31415927);
26959570ffbe31930ab4d678754daaeec0715117a3dsewardj      tst->sig_mask = frame->uc.uc_sigmask;
27059570ffbe31930ab4d678754daaeec0715117a3dsewardj      /*tst->sig_mask.sig[0] = frame->uc.uc_mcontext.oldmask;
27159570ffbe31930ab4d678754daaeec0715117a3dsewardj      tst->sig_mask.sig[1] = frame->uc.uc_mcontext._unused[3];
27259570ffbe31930ab4d678754daaeec0715117a3dsewardj      VG_(printf)("Setting signmask to %08x%08x\n",tst->sig_mask[0],tst->sig_mask[1]);
27359570ffbe31930ab4d678754daaeec0715117a3dsewardj*/
27459570ffbe31930ab4d678754daaeec0715117a3dsewardj   }
27559570ffbe31930ab4d678754daaeec0715117a3dsewardj   tst->tmp_sig_mask = tst->sig_mask;
27659570ffbe31930ab4d678754daaeec0715117a3dsewardj
27759570ffbe31930ab4d678754daaeec0715117a3dsewardj   sigNo = priv->sigNo_private;
27859570ffbe31930ab4d678754daaeec0715117a3dsewardj
279486372b98abee6f79261b5b45810900188fba701florian//ZZ     //XXX: restore regs
280486372b98abee6f79261b5b45810900188fba701florian//ZZ #  define REST(reg,REG)  tst->arch.vex.guest_##REG = mc->arm_##reg;
281486372b98abee6f79261b5b45810900188fba701florian//ZZ    REST(r0,R0);
282486372b98abee6f79261b5b45810900188fba701florian//ZZ    REST(r1,R1);
283486372b98abee6f79261b5b45810900188fba701florian//ZZ    REST(r2,R2);
284486372b98abee6f79261b5b45810900188fba701florian//ZZ    REST(r3,R3);
285486372b98abee6f79261b5b45810900188fba701florian//ZZ    REST(r4,R4);
286486372b98abee6f79261b5b45810900188fba701florian//ZZ    REST(r5,R5);
287486372b98abee6f79261b5b45810900188fba701florian//ZZ    REST(r6,R6);
288486372b98abee6f79261b5b45810900188fba701florian//ZZ    REST(r7,R7);
289486372b98abee6f79261b5b45810900188fba701florian//ZZ    REST(r8,R8);
290486372b98abee6f79261b5b45810900188fba701florian//ZZ    REST(r9,R9);
291486372b98abee6f79261b5b45810900188fba701florian//ZZ    REST(r10,R10);
292486372b98abee6f79261b5b45810900188fba701florian//ZZ    REST(fp,R11);
293486372b98abee6f79261b5b45810900188fba701florian//ZZ    REST(ip,R12);
294486372b98abee6f79261b5b45810900188fba701florian//ZZ    REST(sp,R13);
295486372b98abee6f79261b5b45810900188fba701florian//ZZ    REST(lr,R14);
296486372b98abee6f79261b5b45810900188fba701florian//ZZ    REST(pc,R15T);
297486372b98abee6f79261b5b45810900188fba701florian//ZZ #  undef REST
29859570ffbe31930ab4d678754daaeec0715117a3dsewardj
299320dee232d277b1402c429f25e89e2528c230089sewardj   /* Uh, the next line makes all the REST() above pointless. */
300320dee232d277b1402c429f25e89e2528c230089sewardj   tst->arch.vex         = priv->vex;
301320dee232d277b1402c429f25e89e2528c230089sewardj
30259570ffbe31930ab4d678754daaeec0715117a3dsewardj   tst->arch.vex_shadow1 = priv->vex_shadow1;
30359570ffbe31930ab4d678754daaeec0715117a3dsewardj   tst->arch.vex_shadow2 = priv->vex_shadow2;
30459570ffbe31930ab4d678754daaeec0715117a3dsewardj
30559570ffbe31930ab4d678754daaeec0715117a3dsewardj   VG_TRACK( die_mem_stack_signal, sp - VG_STACK_REDZONE_SZB,
30659570ffbe31930ab4d678754daaeec0715117a3dsewardj             frame_size + VG_STACK_REDZONE_SZB );
30759570ffbe31930ab4d678754daaeec0715117a3dsewardj
30859570ffbe31930ab4d678754daaeec0715117a3dsewardj   if (VG_(clo_trace_signals))
30959570ffbe31930ab4d678754daaeec0715117a3dsewardj      VG_(message)(Vg_DebugMsg,
31097f1d337555234c20f3f1d0dd0b22b2a7d571616florian                   "vg_pop_signal_frame (thread %u): "
311320dee232d277b1402c429f25e89e2528c230089sewardj                   "isRT=%d valid magic; PC=%#x\n",
3129dcfdffec13e259386e088f9be86ea8b8e2756c0sewardj                   tid, has_siginfo, tst->arch.vex.guest_R15T);
31359570ffbe31930ab4d678754daaeec0715117a3dsewardj
31459570ffbe31930ab4d678754daaeec0715117a3dsewardj   /* tell the tools */
31559570ffbe31930ab4d678754daaeec0715117a3dsewardj   VG_TRACK( post_deliver_signal, tid, sigNo );
31659570ffbe31930ab4d678754daaeec0715117a3dsewardj}
31759570ffbe31930ab4d678754daaeec0715117a3dsewardj
31859570ffbe31930ab4d678754daaeec0715117a3dsewardj#endif // defined(VGP_arm_linux)
31959570ffbe31930ab4d678754daaeec0715117a3dsewardj
32059570ffbe31930ab4d678754daaeec0715117a3dsewardj/*--------------------------------------------------------------------*/
32159570ffbe31930ab4d678754daaeec0715117a3dsewardj/*--- end                                     sigframe-arm-linux.c ---*/
32259570ffbe31930ab4d678754daaeec0715117a3dsewardj/*--------------------------------------------------------------------*/
323