185665ca6fa29dd64754dabe50eb98f25896e752acerion
285665ca6fa29dd64754dabe50eb98f25896e752acerion/*--------------------------------------------------------------------*/
385665ca6fa29dd64754dabe50eb98f25896e752acerion/*--- Create/destroy signal delivery frames.                       ---*/
485665ca6fa29dd64754dabe50eb98f25896e752acerion/*---                                       sigframe-ppc32-linux.c ---*/
585665ca6fa29dd64754dabe50eb98f25896e752acerion/*--------------------------------------------------------------------*/
685665ca6fa29dd64754dabe50eb98f25896e752acerion
785665ca6fa29dd64754dabe50eb98f25896e752acerion/*
885665ca6fa29dd64754dabe50eb98f25896e752acerion   This file is part of Valgrind, a dynamic binary instrumentation
985665ca6fa29dd64754dabe50eb98f25896e752acerion   framework.
1085665ca6fa29dd64754dabe50eb98f25896e752acerion
11ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes   Copyright (C) 2000-2017 Nicholas Nethercote
12e1c444e0986abaf738764252a9f730cdac49afbasewardj      njn@valgrind.org
13ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes   Copyright (C) 2004-2017 Paul Mackerras
14e1c444e0986abaf738764252a9f730cdac49afbasewardj      paulus@samba.org
1585665ca6fa29dd64754dabe50eb98f25896e752acerion
1685665ca6fa29dd64754dabe50eb98f25896e752acerion   This program is free software; you can redistribute it and/or
1785665ca6fa29dd64754dabe50eb98f25896e752acerion   modify it under the terms of the GNU General Public License as
1885665ca6fa29dd64754dabe50eb98f25896e752acerion   published by the Free Software Foundation; either version 2 of the
1985665ca6fa29dd64754dabe50eb98f25896e752acerion   License, or (at your option) any later version.
2085665ca6fa29dd64754dabe50eb98f25896e752acerion
2185665ca6fa29dd64754dabe50eb98f25896e752acerion   This program is distributed in the hope that it will be useful, but
2285665ca6fa29dd64754dabe50eb98f25896e752acerion   WITHOUT ANY WARRANTY; without even the implied warranty of
2385665ca6fa29dd64754dabe50eb98f25896e752acerion   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
2485665ca6fa29dd64754dabe50eb98f25896e752acerion   General Public License for more details.
2585665ca6fa29dd64754dabe50eb98f25896e752acerion
2685665ca6fa29dd64754dabe50eb98f25896e752acerion   You should have received a copy of the GNU General Public License
2785665ca6fa29dd64754dabe50eb98f25896e752acerion   along with this program; if not, write to the Free Software
2885665ca6fa29dd64754dabe50eb98f25896e752acerion   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
2985665ca6fa29dd64754dabe50eb98f25896e752acerion   02111-1307, USA.
3085665ca6fa29dd64754dabe50eb98f25896e752acerion
3185665ca6fa29dd64754dabe50eb98f25896e752acerion   The GNU General Public License is contained in the file COPYING.
3285665ca6fa29dd64754dabe50eb98f25896e752acerion*/
3385665ca6fa29dd64754dabe50eb98f25896e752acerion
348b68b64759254d514d98328c496cbd88cde4c9a5njn#if defined(VGP_ppc32_linux)
358b68b64759254d514d98328c496cbd88cde4c9a5njn
3685665ca6fa29dd64754dabe50eb98f25896e752acerion#include "pub_core_basics.h"
37c95257a2c231c00f5e44322d046e1f07ee7b42f3sewardj#include "pub_core_vki.h"
38c95257a2c231c00f5e44322d046e1f07ee7b42f3sewardj#include "pub_core_vkiscnums.h"
3985665ca6fa29dd64754dabe50eb98f25896e752acerion#include "pub_core_threadstate.h"
4085665ca6fa29dd64754dabe50eb98f25896e752acerion#include "pub_core_aspacemgr.h"
4185665ca6fa29dd64754dabe50eb98f25896e752acerion#include "pub_core_libcbase.h"
4285665ca6fa29dd64754dabe50eb98f25896e752acerion#include "pub_core_libcassert.h"
4385665ca6fa29dd64754dabe50eb98f25896e752acerion#include "pub_core_libcprint.h"
4485665ca6fa29dd64754dabe50eb98f25896e752acerion#include "pub_core_machine.h"
4585665ca6fa29dd64754dabe50eb98f25896e752acerion#include "pub_core_options.h"
4685665ca6fa29dd64754dabe50eb98f25896e752acerion#include "pub_core_sigframe.h"
4785665ca6fa29dd64754dabe50eb98f25896e752acerion#include "pub_core_signals.h"
4885665ca6fa29dd64754dabe50eb98f25896e752acerion#include "pub_core_tooliface.h"
4985665ca6fa29dd64754dabe50eb98f25896e752acerion#include "pub_core_trampoline.h"
50e1c444e0986abaf738764252a9f730cdac49afbasewardj#include "pub_core_transtab.h"      // VG_(discard_translations)
5101fcf6a890ad645e4ccbf731264f19f850898c5eflorian#include "priv_sigframe.h"
5285665ca6fa29dd64754dabe50eb98f25896e752acerion
5385665ca6fa29dd64754dabe50eb98f25896e752acerion/* This module creates and removes signal frames for signal deliveries
5485665ca6fa29dd64754dabe50eb98f25896e752acerion   on ppc32-linux.
5585665ca6fa29dd64754dabe50eb98f25896e752acerion
5685665ca6fa29dd64754dabe50eb98f25896e752acerion   Note, this file contains kernel-specific knowledge in the form of
5785665ca6fa29dd64754dabe50eb98f25896e752acerion   'struct sigframe' and 'struct rt_sigframe'.  How does that relate
5885665ca6fa29dd64754dabe50eb98f25896e752acerion   to the vki kernel interface stuff?
5985665ca6fa29dd64754dabe50eb98f25896e752acerion
6085665ca6fa29dd64754dabe50eb98f25896e752acerion   Either a 'struct sigframe' or a 'struct rtsigframe' is pushed
6185665ca6fa29dd64754dabe50eb98f25896e752acerion   onto the client's stack.  This contains a subsidiary
6285665ca6fa29dd64754dabe50eb98f25896e752acerion   vki_ucontext.  That holds the vcpu's state across the signal,
6385665ca6fa29dd64754dabe50eb98f25896e752acerion   so that the sighandler can mess with the vcpu state if it
6485665ca6fa29dd64754dabe50eb98f25896e752acerion   really wants.
6585665ca6fa29dd64754dabe50eb98f25896e752acerion
6685665ca6fa29dd64754dabe50eb98f25896e752acerion   FIXME: sigcontexting is basically broken for the moment.  When
6785665ca6fa29dd64754dabe50eb98f25896e752acerion   delivering a signal, the integer registers and %eflags are
6885665ca6fa29dd64754dabe50eb98f25896e752acerion   correctly written into the sigcontext, however the FP and SSE state
6985665ca6fa29dd64754dabe50eb98f25896e752acerion   is not.  When returning from a signal, only the integer registers
7085665ca6fa29dd64754dabe50eb98f25896e752acerion   are restored from the sigcontext; the rest of the CPU state is
7185665ca6fa29dd64754dabe50eb98f25896e752acerion   restored to what it was before the signal.
7285665ca6fa29dd64754dabe50eb98f25896e752acerion
7385665ca6fa29dd64754dabe50eb98f25896e752acerion   This will be fixed.
7485665ca6fa29dd64754dabe50eb98f25896e752acerion*/
7585665ca6fa29dd64754dabe50eb98f25896e752acerion
7685665ca6fa29dd64754dabe50eb98f25896e752acerion
7785665ca6fa29dd64754dabe50eb98f25896e752acerion/*------------------------------------------------------------*/
7885665ca6fa29dd64754dabe50eb98f25896e752acerion/*--- Signal frame layouts                                 ---*/
7985665ca6fa29dd64754dabe50eb98f25896e752acerion/*------------------------------------------------------------*/
8085665ca6fa29dd64754dabe50eb98f25896e752acerion
8185665ca6fa29dd64754dabe50eb98f25896e752acerion// A structure in which to save the application's registers
8285665ca6fa29dd64754dabe50eb98f25896e752acerion// during the execution of signal handlers.
8385665ca6fa29dd64754dabe50eb98f25896e752acerion
8485665ca6fa29dd64754dabe50eb98f25896e752acerion// Linux has 2 signal frame structures: one for normal signal
8585665ca6fa29dd64754dabe50eb98f25896e752acerion// deliveries, and one for SA_SIGINFO deliveries (also known as RT
8685665ca6fa29dd64754dabe50eb98f25896e752acerion// signals).
8785665ca6fa29dd64754dabe50eb98f25896e752acerion//
8885665ca6fa29dd64754dabe50eb98f25896e752acerion// In theory, so long as we get the arguments to the handler function
8985665ca6fa29dd64754dabe50eb98f25896e752acerion// right, it doesn't matter what the exact layout of the rest of the
9085665ca6fa29dd64754dabe50eb98f25896e752acerion// frame is.  Unfortunately, things like gcc's exception unwinding
9185665ca6fa29dd64754dabe50eb98f25896e752acerion// make assumptions about the locations of various parts of the frame,
9285665ca6fa29dd64754dabe50eb98f25896e752acerion// so we need to duplicate it exactly.
9385665ca6fa29dd64754dabe50eb98f25896e752acerion
94e1c444e0986abaf738764252a9f730cdac49afbasewardj/* Structure containing bits of information that we want to save
95e1c444e0986abaf738764252a9f730cdac49afbasewardj   on signal delivery. */
96e1c444e0986abaf738764252a9f730cdac49afbasewardjstruct vg_sig_private {
9785665ca6fa29dd64754dabe50eb98f25896e752acerion   UInt magicPI;
98e1c444e0986abaf738764252a9f730cdac49afbasewardj   UInt sigNo_private;
997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   VexGuestPPC32State vex_shadow1;
1007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   VexGuestPPC32State vex_shadow2;
10185665ca6fa29dd64754dabe50eb98f25896e752acerion};
10285665ca6fa29dd64754dabe50eb98f25896e752acerion
103e1c444e0986abaf738764252a9f730cdac49afbasewardj/* Structure put on stack for signal handlers with SA_SIGINFO clear. */
104e1c444e0986abaf738764252a9f730cdac49afbasewardjstruct nonrt_sigframe {
105e1c444e0986abaf738764252a9f730cdac49afbasewardj   UInt gap1[16];
106e1c444e0986abaf738764252a9f730cdac49afbasewardj   struct vki_sigcontext sigcontext;
107e1c444e0986abaf738764252a9f730cdac49afbasewardj   struct vki_mcontext mcontext;
108e1c444e0986abaf738764252a9f730cdac49afbasewardj   struct vg_sig_private priv;
1097b7d59405204f88cb944155d6bc5114025ebda98florian   unsigned char abigap[224];    // unused
110e1c444e0986abaf738764252a9f730cdac49afbasewardj};
11185665ca6fa29dd64754dabe50eb98f25896e752acerion
112e1c444e0986abaf738764252a9f730cdac49afbasewardj/* Structure put on stack for signal handlers with SA_SIGINFO set. */
113e1c444e0986abaf738764252a9f730cdac49afbasewardjstruct rt_sigframe {
114e1c444e0986abaf738764252a9f730cdac49afbasewardj   UInt gap1[20];
115e1c444e0986abaf738764252a9f730cdac49afbasewardj   vki_siginfo_t siginfo;
116e1c444e0986abaf738764252a9f730cdac49afbasewardj   struct vki_ucontext ucontext;
117e1c444e0986abaf738764252a9f730cdac49afbasewardj   struct vg_sig_private priv;
1187b7d59405204f88cb944155d6bc5114025ebda98florian   unsigned char abigap[224];    // unused
11985665ca6fa29dd64754dabe50eb98f25896e752acerion};
12085665ca6fa29dd64754dabe50eb98f25896e752acerion
121e1c444e0986abaf738764252a9f730cdac49afbasewardj#define SET_SIGNAL_LR(zztst, zzval)                          \
122e1c444e0986abaf738764252a9f730cdac49afbasewardj   do { tst->arch.vex.guest_LR = (zzval);                    \
123e1c444e0986abaf738764252a9f730cdac49afbasewardj      VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid,     \
124e1c444e0986abaf738764252a9f730cdac49afbasewardj                offsetof(VexGuestPPC32State,guest_LR),       \
125e1c444e0986abaf738764252a9f730cdac49afbasewardj                sizeof(UWord) );                             \
126e1c444e0986abaf738764252a9f730cdac49afbasewardj   } while (0)
127e1c444e0986abaf738764252a9f730cdac49afbasewardj
128e1c444e0986abaf738764252a9f730cdac49afbasewardj#define SET_SIGNAL_GPR(zztst, zzn, zzval)                    \
129e1c444e0986abaf738764252a9f730cdac49afbasewardj   do { tst->arch.vex.guest_GPR##zzn = (zzval);              \
130e1c444e0986abaf738764252a9f730cdac49afbasewardj      VG_TRACK( post_reg_write, Vg_CoreSignal, tst->tid,     \
131e1c444e0986abaf738764252a9f730cdac49afbasewardj                offsetof(VexGuestPPC32State,guest_GPR##zzn), \
132e1c444e0986abaf738764252a9f730cdac49afbasewardj                sizeof(UWord) );                             \
133e1c444e0986abaf738764252a9f730cdac49afbasewardj   } while (0)
134e1c444e0986abaf738764252a9f730cdac49afbasewardj
135e1c444e0986abaf738764252a9f730cdac49afbasewardj
136e1c444e0986abaf738764252a9f730cdac49afbasewardjstatic
137e1c444e0986abaf738764252a9f730cdac49afbasewardjvoid stack_mcontext ( struct vki_mcontext *mc,
138e1c444e0986abaf738764252a9f730cdac49afbasewardj                      ThreadState* tst,
139a5940262b61b3bc245ecae5f10d5f8f77a52833bsewardj                      Bool use_rt_sigreturn,
140e1c444e0986abaf738764252a9f730cdac49afbasewardj                      UInt fault_addr )
14185665ca6fa29dd64754dabe50eb98f25896e752acerion{
142e1c444e0986abaf738764252a9f730cdac49afbasewardj   VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcontext",
143e1c444e0986abaf738764252a9f730cdac49afbasewardj             (Addr)mc, sizeof(struct vki_pt_regs) );
144e1c444e0986abaf738764252a9f730cdac49afbasewardj
145e1c444e0986abaf738764252a9f730cdac49afbasewardj#  define DO(gpr)  mc->mc_gregs[VKI_PT_R0+gpr] = tst->arch.vex.guest_GPR##gpr
146e1c444e0986abaf738764252a9f730cdac49afbasewardj   DO(0);  DO(1);  DO(2);  DO(3);  DO(4);  DO(5);  DO(6);  DO(7);
147e1c444e0986abaf738764252a9f730cdac49afbasewardj   DO(8);  DO(9);  DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
148e1c444e0986abaf738764252a9f730cdac49afbasewardj   DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
149e1c444e0986abaf738764252a9f730cdac49afbasewardj   DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
150e1c444e0986abaf738764252a9f730cdac49afbasewardj#  undef DO
151e1c444e0986abaf738764252a9f730cdac49afbasewardj
152e1c444e0986abaf738764252a9f730cdac49afbasewardj   mc->mc_gregs[VKI_PT_NIP]     = tst->arch.vex.guest_CIA;
153e1c444e0986abaf738764252a9f730cdac49afbasewardj   mc->mc_gregs[VKI_PT_MSR]     = 0xf032;   /* pretty arbitrary */
154e1c444e0986abaf738764252a9f730cdac49afbasewardj   mc->mc_gregs[VKI_PT_ORIG_R3] = tst->arch.vex.guest_GPR3;
155e1c444e0986abaf738764252a9f730cdac49afbasewardj   mc->mc_gregs[VKI_PT_CTR]     = tst->arch.vex.guest_CTR;
156e1c444e0986abaf738764252a9f730cdac49afbasewardj   mc->mc_gregs[VKI_PT_LNK]     = tst->arch.vex.guest_LR;
157463b3d94b19ec820c2378dde6d43d2c1f553a8d0sewardj   mc->mc_gregs[VKI_PT_XER]     = LibVEX_GuestPPC32_get_XER(&tst->arch.vex);
158463b3d94b19ec820c2378dde6d43d2c1f553a8d0sewardj   mc->mc_gregs[VKI_PT_CCR]     = LibVEX_GuestPPC32_get_CR(&tst->arch.vex);
159e1c444e0986abaf738764252a9f730cdac49afbasewardj   mc->mc_gregs[VKI_PT_MQ]      = 0;
160e1c444e0986abaf738764252a9f730cdac49afbasewardj   mc->mc_gregs[VKI_PT_TRAP]    = 0;
161e1c444e0986abaf738764252a9f730cdac49afbasewardj   mc->mc_gregs[VKI_PT_DAR]     = fault_addr;
162e1c444e0986abaf738764252a9f730cdac49afbasewardj   mc->mc_gregs[VKI_PT_DSISR]   = 0;
163e1c444e0986abaf738764252a9f730cdac49afbasewardj   mc->mc_gregs[VKI_PT_RESULT]  = 0;
164e1c444e0986abaf738764252a9f730cdac49afbasewardj   VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
165e1c444e0986abaf738764252a9f730cdac49afbasewardj             (Addr)mc, sizeof(struct vki_pt_regs) );
166e1c444e0986abaf738764252a9f730cdac49afbasewardj
167e1c444e0986abaf738764252a9f730cdac49afbasewardj   /* XXX should do FP and vector regs */
168e1c444e0986abaf738764252a9f730cdac49afbasewardj
169e1c444e0986abaf738764252a9f730cdac49afbasewardj   /* set up signal return trampoline */
170a5940262b61b3bc245ecae5f10d5f8f77a52833bsewardj   /* NB.  5 Sept 07.  mc->mc_pad[0..1] used to contain a the code to
171a5940262b61b3bc245ecae5f10d5f8f77a52833bsewardj      which the signal handler returns, and it just did sys_sigreturn
172a5940262b61b3bc245ecae5f10d5f8f77a52833bsewardj      or sys_rt_sigreturn.  But this doesn't work if the stack is
173a5940262b61b3bc245ecae5f10d5f8f77a52833bsewardj      non-executable, and it isn't consistent with the x86-linux and
174a5940262b61b3bc245ecae5f10d5f8f77a52833bsewardj      amd64-linux scheme for removing the stack frame.  So instead be
175a5940262b61b3bc245ecae5f10d5f8f77a52833bsewardj      consistent and use a stub in m_trampoline.  Then it doesn't
176a5940262b61b3bc245ecae5f10d5f8f77a52833bsewardj      matter whether or not the (guest) stack is executable.  This
177a5940262b61b3bc245ecae5f10d5f8f77a52833bsewardj      fixes #149519 and #145837. */
178e1c444e0986abaf738764252a9f730cdac49afbasewardj   VG_TRACK(pre_mem_write, Vg_CoreSignal, tst->tid, "signal frame mcontext",
179e1c444e0986abaf738764252a9f730cdac49afbasewardj            (Addr)&mc->mc_pad, sizeof(mc->mc_pad));
180a5940262b61b3bc245ecae5f10d5f8f77a52833bsewardj   mc->mc_pad[0] = 0; /* invalid */
181a5940262b61b3bc245ecae5f10d5f8f77a52833bsewardj   mc->mc_pad[1] = 0; /* invalid */
182e1c444e0986abaf738764252a9f730cdac49afbasewardj   VG_TRACK( post_mem_write,  Vg_CoreSignal, tst->tid,
183e1c444e0986abaf738764252a9f730cdac49afbasewardj             (Addr)&mc->mc_pad, sizeof(mc->mc_pad) );
184e1c444e0986abaf738764252a9f730cdac49afbasewardj   /* invalidate any translation of this area */
185ddd61ff058f02059064e083a8accaefed23d5548florian   VG_(discard_translations)( (Addr)&mc->mc_pad,
186a48a4939011eb7c09e12d29fe00e792a635b83d6sewardj                              sizeof(mc->mc_pad), "stack_mcontext" );
187e1c444e0986abaf738764252a9f730cdac49afbasewardj
188e1c444e0986abaf738764252a9f730cdac49afbasewardj   /* set the signal handler to return to the trampoline */
189a5940262b61b3bc245ecae5f10d5f8f77a52833bsewardj   SET_SIGNAL_LR(tst, (Addr)(use_rt_sigreturn
190a5940262b61b3bc245ecae5f10d5f8f77a52833bsewardj                               ? (Addr)&VG_(ppc32_linux_SUBST_FOR_rt_sigreturn)
191a5940262b61b3bc245ecae5f10d5f8f77a52833bsewardj                               : (Addr)&VG_(ppc32_linux_SUBST_FOR_sigreturn)
192a5940262b61b3bc245ecae5f10d5f8f77a52833bsewardj                      ));
193e1c444e0986abaf738764252a9f730cdac49afbasewardj}
19485665ca6fa29dd64754dabe50eb98f25896e752acerion
195e1c444e0986abaf738764252a9f730cdac49afbasewardj//:: /* Valgrind-specific parts of the signal frame */
196e1c444e0986abaf738764252a9f730cdac49afbasewardj//:: struct vg_sigframe
197e1c444e0986abaf738764252a9f730cdac49afbasewardj//:: {
198e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    /* Sanity check word. */
199e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    UInt magicPI;
200e1c444e0986abaf738764252a9f730cdac49afbasewardj//::
201e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    UInt handlerflags;	/* flags for signal handler */
202e1c444e0986abaf738764252a9f730cdac49afbasewardj//::
203e1c444e0986abaf738764252a9f730cdac49afbasewardj//::
204e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    /* Safely-saved version of sigNo, as described above. */
205e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    Int  sigNo_private;
206e1c444e0986abaf738764252a9f730cdac49afbasewardj//::
207e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    /* XXX This is wrong.  Surely we should store the shadow values
208e1c444e0986abaf738764252a9f730cdac49afbasewardj//::       into the shadow memory behind the actual values? */
209e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    VexGuestPPC32State vex_shadow;
210e1c444e0986abaf738764252a9f730cdac49afbasewardj//::
211e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    /* HACK ALERT */
212e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    VexGuestPPC32State vex;
213e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    /* end HACK ALERT */
214e1c444e0986abaf738764252a9f730cdac49afbasewardj//::
215e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    /* saved signal mask to be restored when handler returns */
216e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    vki_sigset_t	mask;
217e1c444e0986abaf738764252a9f730cdac49afbasewardj//::
218e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    /* Sanity check word.  Is the highest-addressed word; do not
219e1c444e0986abaf738764252a9f730cdac49afbasewardj//::       move!*/
220e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    UInt magicE;
221e1c444e0986abaf738764252a9f730cdac49afbasewardj//:: };
222e1c444e0986abaf738764252a9f730cdac49afbasewardj//::
223e1c444e0986abaf738764252a9f730cdac49afbasewardj//:: struct sigframe
224e1c444e0986abaf738764252a9f730cdac49afbasewardj//:: {
225e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    /* Sig handler's return address */
226e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    Addr retaddr;
227e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    Int  sigNo;
228e1c444e0986abaf738764252a9f730cdac49afbasewardj//::
229e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    struct vki_sigcontext sigContext;
230e1c444e0986abaf738764252a9f730cdac49afbasewardj//:: //..    struct _vki_fpstate fpstate;
231e1c444e0986abaf738764252a9f730cdac49afbasewardj//::
232e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    struct vg_sigframe vg;
233e1c444e0986abaf738764252a9f730cdac49afbasewardj//:: };
234e1c444e0986abaf738764252a9f730cdac49afbasewardj//::
235e1c444e0986abaf738764252a9f730cdac49afbasewardj//:: struct rt_sigframe
236e1c444e0986abaf738764252a9f730cdac49afbasewardj//:: {
237e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    /* Sig handler's return address */
238e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    Addr retaddr;
239e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    Int  sigNo;
240e1c444e0986abaf738764252a9f730cdac49afbasewardj//::
241e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    /* ptr to siginfo_t. */
242e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    Addr psigInfo;
243e1c444e0986abaf738764252a9f730cdac49afbasewardj//::
244e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    /* ptr to ucontext */
245e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    Addr puContext;
246e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    /* pointed to by psigInfo */
247e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    vki_siginfo_t sigInfo;
248e1c444e0986abaf738764252a9f730cdac49afbasewardj//::
249e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    /* pointed to by puContext */
250e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    struct vki_ucontext uContext;
251e1c444e0986abaf738764252a9f730cdac49afbasewardj//:: //..    struct _vki_fpstate fpstate;
252e1c444e0986abaf738764252a9f730cdac49afbasewardj//::
253e1c444e0986abaf738764252a9f730cdac49afbasewardj//::    struct vg_sigframe vg;
254e1c444e0986abaf738764252a9f730cdac49afbasewardj//:: };
25585665ca6fa29dd64754dabe50eb98f25896e752acerion
25685665ca6fa29dd64754dabe50eb98f25896e752acerion
25785665ca6fa29dd64754dabe50eb98f25896e752acerion//:: /*------------------------------------------------------------*/
25885665ca6fa29dd64754dabe50eb98f25896e752acerion//:: /*--- Signal operations                                    ---*/
25985665ca6fa29dd64754dabe50eb98f25896e752acerion//:: /*------------------------------------------------------------*/
26085665ca6fa29dd64754dabe50eb98f25896e752acerion//::
26185665ca6fa29dd64754dabe50eb98f25896e752acerion//:: /*
26285665ca6fa29dd64754dabe50eb98f25896e752acerion//::    Great gobs of FP state conversion taken wholesale from
26385665ca6fa29dd64754dabe50eb98f25896e752acerion//::    linux/arch/i386/kernel/i387.c
26485665ca6fa29dd64754dabe50eb98f25896e752acerion//::  */
26585665ca6fa29dd64754dabe50eb98f25896e752acerion//::
26685665ca6fa29dd64754dabe50eb98f25896e752acerion//:: /*
26785665ca6fa29dd64754dabe50eb98f25896e752acerion//::  * FXSR floating point environment conversions.
26885665ca6fa29dd64754dabe50eb98f25896e752acerion//::  */
26985665ca6fa29dd64754dabe50eb98f25896e752acerion//:: #define X86_FXSR_MAGIC		0x0000
27085665ca6fa29dd64754dabe50eb98f25896e752acerion//::
27185665ca6fa29dd64754dabe50eb98f25896e752acerion//:: /*
27285665ca6fa29dd64754dabe50eb98f25896e752acerion//::  * FPU tag word conversions.
27385665ca6fa29dd64754dabe50eb98f25896e752acerion//::  */
27485665ca6fa29dd64754dabe50eb98f25896e752acerion//::
27585665ca6fa29dd64754dabe50eb98f25896e752acerion//:: static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
27685665ca6fa29dd64754dabe50eb98f25896e752acerion//:: {
27785665ca6fa29dd64754dabe50eb98f25896e752acerion//::    unsigned int tmp; /* to avoid 16 bit prefixes in the code */
27885665ca6fa29dd64754dabe50eb98f25896e752acerion//::
27985665ca6fa29dd64754dabe50eb98f25896e752acerion//::    /* Transform each pair of bits into 01 (valid) or 00 (empty) */
28085665ca6fa29dd64754dabe50eb98f25896e752acerion//::    tmp = ~twd;
28185665ca6fa29dd64754dabe50eb98f25896e752acerion//::    tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
28285665ca6fa29dd64754dabe50eb98f25896e752acerion//::    /* and move the valid bits to the lower byte. */
28385665ca6fa29dd64754dabe50eb98f25896e752acerion//::    tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
28485665ca6fa29dd64754dabe50eb98f25896e752acerion//::    tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
28585665ca6fa29dd64754dabe50eb98f25896e752acerion//::    tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
28685665ca6fa29dd64754dabe50eb98f25896e752acerion//::    return tmp;
28785665ca6fa29dd64754dabe50eb98f25896e752acerion//:: }
28885665ca6fa29dd64754dabe50eb98f25896e752acerion//::
28985665ca6fa29dd64754dabe50eb98f25896e752acerion//:: static unsigned long twd_fxsr_to_i387( const struct i387_fxsave_struct *fxsave )
29085665ca6fa29dd64754dabe50eb98f25896e752acerion//:: {
29185665ca6fa29dd64754dabe50eb98f25896e752acerion//::    struct _vki_fpxreg *st = NULL;
29285665ca6fa29dd64754dabe50eb98f25896e752acerion//::    unsigned long twd = (unsigned long) fxsave->twd;
29385665ca6fa29dd64754dabe50eb98f25896e752acerion//::    unsigned long tag;
29485665ca6fa29dd64754dabe50eb98f25896e752acerion//::    unsigned long ret = 0xffff0000u;
29585665ca6fa29dd64754dabe50eb98f25896e752acerion//::    int i;
29685665ca6fa29dd64754dabe50eb98f25896e752acerion//::
29785665ca6fa29dd64754dabe50eb98f25896e752acerion//:: #define FPREG_ADDR(f, n)	((char *)&(f)->st_space + (n) * 16);
29885665ca6fa29dd64754dabe50eb98f25896e752acerion//::
29985665ca6fa29dd64754dabe50eb98f25896e752acerion//::    for ( i = 0 ; i < 8 ; i++ ) {
30085665ca6fa29dd64754dabe50eb98f25896e752acerion//::       if ( twd & 0x1 ) {
30185665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	 st = (struct _vki_fpxreg *) FPREG_ADDR( fxsave, i );
30285665ca6fa29dd64754dabe50eb98f25896e752acerion//::
30385665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	 switch ( st->exponent & 0x7fff ) {
30485665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	 case 0x7fff:
30585665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	    tag = 2;		/* Special */
30685665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	    break;
30785665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	 case 0x0000:
30885665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	    if ( !st->significand[0] &&
30985665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 		 !st->significand[1] &&
31085665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 		 !st->significand[2] &&
31185665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 		 !st->significand[3] ) {
31285665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	       tag = 1;	/* Zero */
31385665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	    } else {
31485665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	       tag = 2;	/* Special */
31585665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	    }
31685665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	    break;
31785665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	 default:
31885665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	    if ( st->significand[3] & 0x8000 ) {
31985665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	       tag = 0;	/* Valid */
32085665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	    } else {
32185665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	       tag = 2;	/* Special */
32285665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	    }
32385665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	    break;
32485665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	 }
32585665ca6fa29dd64754dabe50eb98f25896e752acerion//::       } else {
32685665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	 tag = 3;			/* Empty */
32785665ca6fa29dd64754dabe50eb98f25896e752acerion//::       }
32885665ca6fa29dd64754dabe50eb98f25896e752acerion//::       ret |= (tag << (2 * i));
32985665ca6fa29dd64754dabe50eb98f25896e752acerion//::       twd = twd >> 1;
33085665ca6fa29dd64754dabe50eb98f25896e752acerion//::    }
33185665ca6fa29dd64754dabe50eb98f25896e752acerion//::    return ret;
33285665ca6fa29dd64754dabe50eb98f25896e752acerion//:: }
33385665ca6fa29dd64754dabe50eb98f25896e752acerion//::
33485665ca6fa29dd64754dabe50eb98f25896e752acerion//:: static void convert_fxsr_to_user( struct _vki_fpstate *buf,
33585665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 				  const struct i387_fxsave_struct *fxsave )
33685665ca6fa29dd64754dabe50eb98f25896e752acerion//:: {
33785665ca6fa29dd64754dabe50eb98f25896e752acerion//::    unsigned long env[7];
33885665ca6fa29dd64754dabe50eb98f25896e752acerion//::    struct _vki_fpreg *to;
33985665ca6fa29dd64754dabe50eb98f25896e752acerion//::    struct _vki_fpxreg *from;
34085665ca6fa29dd64754dabe50eb98f25896e752acerion//::    int i;
34185665ca6fa29dd64754dabe50eb98f25896e752acerion//::
34285665ca6fa29dd64754dabe50eb98f25896e752acerion//::    env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul;
34385665ca6fa29dd64754dabe50eb98f25896e752acerion//::    env[1] = (unsigned long)fxsave->swd | 0xffff0000ul;
34485665ca6fa29dd64754dabe50eb98f25896e752acerion//::    env[2] = twd_fxsr_to_i387(fxsave);
34585665ca6fa29dd64754dabe50eb98f25896e752acerion//::    env[3] = fxsave->fip;
34685665ca6fa29dd64754dabe50eb98f25896e752acerion//::    env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
34785665ca6fa29dd64754dabe50eb98f25896e752acerion//::    env[5] = fxsave->foo;
34885665ca6fa29dd64754dabe50eb98f25896e752acerion//::    env[6] = fxsave->fos;
34985665ca6fa29dd64754dabe50eb98f25896e752acerion//::
35085665ca6fa29dd64754dabe50eb98f25896e752acerion//::    VG_(memcpy)(buf, env, 7 * sizeof(unsigned long));
35185665ca6fa29dd64754dabe50eb98f25896e752acerion//::
35285665ca6fa29dd64754dabe50eb98f25896e752acerion//::    to = &buf->_st[0];
35385665ca6fa29dd64754dabe50eb98f25896e752acerion//::    from = (struct _vki_fpxreg *) &fxsave->st_space[0];
35485665ca6fa29dd64754dabe50eb98f25896e752acerion//::    for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
35585665ca6fa29dd64754dabe50eb98f25896e752acerion//::       unsigned long __user *t = (unsigned long __user *)to;
35685665ca6fa29dd64754dabe50eb98f25896e752acerion//::       unsigned long *f = (unsigned long *)from;
35785665ca6fa29dd64754dabe50eb98f25896e752acerion//::
35885665ca6fa29dd64754dabe50eb98f25896e752acerion//::       t[0] = f[0];
35985665ca6fa29dd64754dabe50eb98f25896e752acerion//::       t[1] = f[1];
36085665ca6fa29dd64754dabe50eb98f25896e752acerion//::       to->exponent = from->exponent;
36185665ca6fa29dd64754dabe50eb98f25896e752acerion//::    }
36285665ca6fa29dd64754dabe50eb98f25896e752acerion//:: }
36385665ca6fa29dd64754dabe50eb98f25896e752acerion//::
36485665ca6fa29dd64754dabe50eb98f25896e752acerion//:: static void convert_fxsr_from_user( struct i387_fxsave_struct *fxsave,
36585665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 				    const struct _vki_fpstate *buf )
36685665ca6fa29dd64754dabe50eb98f25896e752acerion//:: {
36785665ca6fa29dd64754dabe50eb98f25896e752acerion//::    unsigned long env[7];
36885665ca6fa29dd64754dabe50eb98f25896e752acerion//::    struct _vki_fpxreg *to;
36985665ca6fa29dd64754dabe50eb98f25896e752acerion//::    const struct _vki_fpreg *from;
37085665ca6fa29dd64754dabe50eb98f25896e752acerion//::    int i;
37185665ca6fa29dd64754dabe50eb98f25896e752acerion//::
37285665ca6fa29dd64754dabe50eb98f25896e752acerion//::    VG_(memcpy)(env, buf, 7 * sizeof(long));
37385665ca6fa29dd64754dabe50eb98f25896e752acerion//::
37485665ca6fa29dd64754dabe50eb98f25896e752acerion//::    fxsave->cwd = (unsigned short)(env[0] & 0xffff);
37585665ca6fa29dd64754dabe50eb98f25896e752acerion//::    fxsave->swd = (unsigned short)(env[1] & 0xffff);
37685665ca6fa29dd64754dabe50eb98f25896e752acerion//::    fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
37785665ca6fa29dd64754dabe50eb98f25896e752acerion//::    fxsave->fip = env[3];
37885665ca6fa29dd64754dabe50eb98f25896e752acerion//::    fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16);
37985665ca6fa29dd64754dabe50eb98f25896e752acerion//::    fxsave->fcs = (env[4] & 0xffff);
38085665ca6fa29dd64754dabe50eb98f25896e752acerion//::    fxsave->foo = env[5];
38185665ca6fa29dd64754dabe50eb98f25896e752acerion//::    fxsave->fos = env[6];
38285665ca6fa29dd64754dabe50eb98f25896e752acerion//::
38385665ca6fa29dd64754dabe50eb98f25896e752acerion//::    to = (struct _vki_fpxreg *) &fxsave->st_space[0];
38485665ca6fa29dd64754dabe50eb98f25896e752acerion//::    from = &buf->_st[0];
38585665ca6fa29dd64754dabe50eb98f25896e752acerion//::    for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
38685665ca6fa29dd64754dabe50eb98f25896e752acerion//::       unsigned long *t = (unsigned long *)to;
38785665ca6fa29dd64754dabe50eb98f25896e752acerion//::       unsigned long __user *f = (unsigned long __user *)from;
38885665ca6fa29dd64754dabe50eb98f25896e752acerion//::
38985665ca6fa29dd64754dabe50eb98f25896e752acerion//::       t[0] = f[0];
39085665ca6fa29dd64754dabe50eb98f25896e752acerion//::       t[1] = f[1];
39185665ca6fa29dd64754dabe50eb98f25896e752acerion//::       to->exponent = from->exponent;
39285665ca6fa29dd64754dabe50eb98f25896e752acerion//::    }
39385665ca6fa29dd64754dabe50eb98f25896e752acerion//:: }
39485665ca6fa29dd64754dabe50eb98f25896e752acerion//::
39585665ca6fa29dd64754dabe50eb98f25896e752acerion//:: static inline void save_i387_fsave( arch_thread_t *regs, struct _vki_fpstate *buf )
39685665ca6fa29dd64754dabe50eb98f25896e752acerion//:: {
39785665ca6fa29dd64754dabe50eb98f25896e752acerion//::    struct i387_fsave_struct *fs = &regs->m_sse.fsave;
39885665ca6fa29dd64754dabe50eb98f25896e752acerion//::
39985665ca6fa29dd64754dabe50eb98f25896e752acerion//::    fs->status = fs->swd;
40085665ca6fa29dd64754dabe50eb98f25896e752acerion//::    VG_(memcpy)(buf, fs, sizeof(*fs));
40185665ca6fa29dd64754dabe50eb98f25896e752acerion//:: }
40285665ca6fa29dd64754dabe50eb98f25896e752acerion//::
40385665ca6fa29dd64754dabe50eb98f25896e752acerion//:: static void save_i387_fxsave( arch_thread_t *regs, struct _vki_fpstate *buf )
40485665ca6fa29dd64754dabe50eb98f25896e752acerion//:: {
40585665ca6fa29dd64754dabe50eb98f25896e752acerion//::    const struct i387_fxsave_struct *fx = &regs->m_sse.fxsave;
40685665ca6fa29dd64754dabe50eb98f25896e752acerion//::    convert_fxsr_to_user( buf, fx );
40785665ca6fa29dd64754dabe50eb98f25896e752acerion//::
40885665ca6fa29dd64754dabe50eb98f25896e752acerion//::    buf->status = fx->swd;
40985665ca6fa29dd64754dabe50eb98f25896e752acerion//::    buf->magic = X86_FXSR_MAGIC;
41085665ca6fa29dd64754dabe50eb98f25896e752acerion//::    VG_(memcpy)(buf->_fxsr_env, fx, sizeof(struct i387_fxsave_struct));
41185665ca6fa29dd64754dabe50eb98f25896e752acerion//:: }
41285665ca6fa29dd64754dabe50eb98f25896e752acerion//::
41385665ca6fa29dd64754dabe50eb98f25896e752acerion//:: static void save_i387( arch_thread_t *regs, struct _vki_fpstate *buf )
41485665ca6fa29dd64754dabe50eb98f25896e752acerion//:: {
41585665ca6fa29dd64754dabe50eb98f25896e752acerion//::    if ( VG_(have_ssestate) )
41685665ca6fa29dd64754dabe50eb98f25896e752acerion//::       save_i387_fxsave( regs, buf );
41785665ca6fa29dd64754dabe50eb98f25896e752acerion//::    else
41885665ca6fa29dd64754dabe50eb98f25896e752acerion//::       save_i387_fsave( regs, buf );
41985665ca6fa29dd64754dabe50eb98f25896e752acerion//:: }
42085665ca6fa29dd64754dabe50eb98f25896e752acerion//::
42185665ca6fa29dd64754dabe50eb98f25896e752acerion//:: static inline void restore_i387_fsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
42285665ca6fa29dd64754dabe50eb98f25896e752acerion//:: {
42385665ca6fa29dd64754dabe50eb98f25896e752acerion//::    VG_(memcpy)( &regs->m_sse.fsave, buf, sizeof(struct i387_fsave_struct) );
42485665ca6fa29dd64754dabe50eb98f25896e752acerion//:: }
42585665ca6fa29dd64754dabe50eb98f25896e752acerion//::
42685665ca6fa29dd64754dabe50eb98f25896e752acerion//:: static void restore_i387_fxsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
42785665ca6fa29dd64754dabe50eb98f25896e752acerion//:: {
42885665ca6fa29dd64754dabe50eb98f25896e752acerion//::    VG_(memcpy)(&regs->m_sse.fxsave, &buf->_fxsr_env[0],
42985665ca6fa29dd64754dabe50eb98f25896e752acerion//:: 	       sizeof(struct i387_fxsave_struct) );
43085665ca6fa29dd64754dabe50eb98f25896e752acerion//::    /* mxcsr reserved bits must be masked to zero for security reasons */
43185665ca6fa29dd64754dabe50eb98f25896e752acerion//::    regs->m_sse.fxsave.mxcsr &= 0xffbf;
43285665ca6fa29dd64754dabe50eb98f25896e752acerion//::    convert_fxsr_from_user( &regs->m_sse.fxsave, buf );
43385665ca6fa29dd64754dabe50eb98f25896e752acerion//:: }
43485665ca6fa29dd64754dabe50eb98f25896e752acerion//::
43585665ca6fa29dd64754dabe50eb98f25896e752acerion//:: static void restore_i387( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
43685665ca6fa29dd64754dabe50eb98f25896e752acerion//:: {
43785665ca6fa29dd64754dabe50eb98f25896e752acerion//::    if ( VG_(have_ssestate) ) {
43885665ca6fa29dd64754dabe50eb98f25896e752acerion//::       restore_i387_fxsave( regs, buf );
43985665ca6fa29dd64754dabe50eb98f25896e752acerion//::    } else {
44085665ca6fa29dd64754dabe50eb98f25896e752acerion//::       restore_i387_fsave( regs, buf );
44185665ca6fa29dd64754dabe50eb98f25896e752acerion//::    }
44285665ca6fa29dd64754dabe50eb98f25896e752acerion//:: }
44385665ca6fa29dd64754dabe50eb98f25896e752acerion
44485665ca6fa29dd64754dabe50eb98f25896e752acerion
44585665ca6fa29dd64754dabe50eb98f25896e752acerion
44685665ca6fa29dd64754dabe50eb98f25896e752acerion
44785665ca6fa29dd64754dabe50eb98f25896e752acerion/*------------------------------------------------------------*/
44885665ca6fa29dd64754dabe50eb98f25896e752acerion/*--- Creating signal frames                               ---*/
44985665ca6fa29dd64754dabe50eb98f25896e752acerion/*------------------------------------------------------------*/
45085665ca6fa29dd64754dabe50eb98f25896e752acerion
45185665ca6fa29dd64754dabe50eb98f25896e752acerion//.. /* Create a plausible-looking sigcontext from the thread's
45285665ca6fa29dd64754dabe50eb98f25896e752acerion//..    Vex guest state.  NOTE: does not fill in the FP or SSE
45385665ca6fa29dd64754dabe50eb98f25896e752acerion//..    bits of sigcontext at the moment.
45485665ca6fa29dd64754dabe50eb98f25896e752acerion//.. */
45585665ca6fa29dd64754dabe50eb98f25896e752acerion//.. static
45685665ca6fa29dd64754dabe50eb98f25896e752acerion//.. void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,
45785665ca6fa29dd64754dabe50eb98f25896e752acerion//..                     const vki_sigset_t *set, struct vki_ucontext *uc)
45885665ca6fa29dd64754dabe50eb98f25896e752acerion//.. {
45985665ca6fa29dd64754dabe50eb98f25896e752acerion//..    ThreadState *tst = VG_(get_ThreadState)(tid);
46085665ca6fa29dd64754dabe50eb98f25896e752acerion//..    struct vki_sigcontext *sc = &uc->uc_mcontext;
46185665ca6fa29dd64754dabe50eb98f25896e752acerion//..
46285665ca6fa29dd64754dabe50eb98f25896e752acerion//..    VG_(memset)(uc, 0, sizeof(*uc));
46385665ca6fa29dd64754dabe50eb98f25896e752acerion//..
46485665ca6fa29dd64754dabe50eb98f25896e752acerion//..    uc->uc_flags = 0;
46585665ca6fa29dd64754dabe50eb98f25896e752acerion//..    uc->uc_link = 0;
46685665ca6fa29dd64754dabe50eb98f25896e752acerion//..    uc->uc_sigmask = *set;
46785665ca6fa29dd64754dabe50eb98f25896e752acerion//..    uc->uc_stack = tst->altstack;
46885665ca6fa29dd64754dabe50eb98f25896e752acerion//..    sc->fpstate = fpstate;
46985665ca6fa29dd64754dabe50eb98f25896e752acerion//..
47085665ca6fa29dd64754dabe50eb98f25896e752acerion//..    // FIXME: save_i387(&tst->arch, fpstate);
47185665ca6fa29dd64754dabe50eb98f25896e752acerion//..
47285665ca6fa29dd64754dabe50eb98f25896e752acerion//.. #  define SC2(reg,REG)  sc->reg = tst->arch.vex.guest_##REG
47385665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SC2(gs,GS);
47485665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SC2(fs,FS);
47585665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SC2(es,ES);
47685665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SC2(ds,DS);
47785665ca6fa29dd64754dabe50eb98f25896e752acerion//..
47885665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SC2(edi,EDI);
47985665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SC2(esi,ESI);
48085665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SC2(ebp,EBP);
48185665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SC2(esp,ESP);
48285665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SC2(ebx,EBX);
48385665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SC2(edx,EDX);
48485665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SC2(ecx,ECX);
48585665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SC2(eax,EAX);
48685665ca6fa29dd64754dabe50eb98f25896e752acerion//..
48785665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SC2(eip,EIP);
48885665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SC2(cs,CS);
48985665ca6fa29dd64754dabe50eb98f25896e752acerion//..    sc->eflags = LibVEX_GuestX86_get_eflags(&tst->arch.vex);
49085665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SC2(ss,SS);
49185665ca6fa29dd64754dabe50eb98f25896e752acerion//..    /* XXX esp_at_signal */
49285665ca6fa29dd64754dabe50eb98f25896e752acerion//..    /* XXX trapno */
49385665ca6fa29dd64754dabe50eb98f25896e752acerion//..    /* XXX err */
49485665ca6fa29dd64754dabe50eb98f25896e752acerion//.. #  undef SC2
49585665ca6fa29dd64754dabe50eb98f25896e752acerion//..
49685665ca6fa29dd64754dabe50eb98f25896e752acerion//..    sc->cr2 = (UInt)si->_sifields._sigfault._addr;
49785665ca6fa29dd64754dabe50eb98f25896e752acerion//.. }
49885665ca6fa29dd64754dabe50eb98f25896e752acerion/*
49985665ca6fa29dd64754dabe50eb98f25896e752acerion//.. #define SET_SIGNAL_ESP(zztid, zzval) \
50085665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SET_THREAD_REG(zztid, zzval, STACK_PTR, post_reg_write, \
501af839f52d74df156d655201a889954133ab01be7njn//..                   Vg_CoreSignal, zztid, VG_O_STACK_PTR, sizeof(Addr))
50285665ca6fa29dd64754dabe50eb98f25896e752acerion*/
50385665ca6fa29dd64754dabe50eb98f25896e752acerion
50485665ca6fa29dd64754dabe50eb98f25896e752acerion
50585665ca6fa29dd64754dabe50eb98f25896e752acerion//.. /* Build the Valgrind-specific part of a signal frame. */
50685665ca6fa29dd64754dabe50eb98f25896e752acerion//..
50785665ca6fa29dd64754dabe50eb98f25896e752acerion//.. static void build_vg_sigframe(struct vg_sigframe *frame,
50885665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 			      ThreadState *tst,
50985665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 			      const vki_sigset_t *mask,
51085665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 			      UInt flags,
51185665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 			      Int sigNo)
51285665ca6fa29dd64754dabe50eb98f25896e752acerion//.. {
51385665ca6fa29dd64754dabe50eb98f25896e752acerion//..    frame->sigNo_private = sigNo;
51485665ca6fa29dd64754dabe50eb98f25896e752acerion//..    frame->magicPI       = 0x31415927;
51585665ca6fa29dd64754dabe50eb98f25896e752acerion//..    frame->vex_shadow    = tst->arch.vex_shadow;
51685665ca6fa29dd64754dabe50eb98f25896e752acerion//..    /* HACK ALERT */
51785665ca6fa29dd64754dabe50eb98f25896e752acerion//..    frame->vex           = tst->arch.vex;
51885665ca6fa29dd64754dabe50eb98f25896e752acerion//..    /* end HACK ALERT */
51985665ca6fa29dd64754dabe50eb98f25896e752acerion//..    frame->mask          = tst->sig_mask;
52085665ca6fa29dd64754dabe50eb98f25896e752acerion//..    frame->handlerflags  = flags;
52185665ca6fa29dd64754dabe50eb98f25896e752acerion//..    frame->magicE        = 0x27182818;
52285665ca6fa29dd64754dabe50eb98f25896e752acerion//.. }
52385665ca6fa29dd64754dabe50eb98f25896e752acerion
52485665ca6fa29dd64754dabe50eb98f25896e752acerion
52585665ca6fa29dd64754dabe50eb98f25896e752acerion//.. static Addr build_sigframe(ThreadState *tst,
52685665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 			   Addr esp_top_of_frame,
52785665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 			   const vki_siginfo_t *siginfo,
52885665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 			   void *handler, UInt flags,
52985665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 			   const vki_sigset_t *mask,
53085665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 			   void *restorer)
53185665ca6fa29dd64754dabe50eb98f25896e752acerion//.. {
53285665ca6fa29dd64754dabe50eb98f25896e752acerion//..    struct sigframe *frame;
53385665ca6fa29dd64754dabe50eb98f25896e752acerion//..    Addr esp = esp_top_of_frame;
53485665ca6fa29dd64754dabe50eb98f25896e752acerion//..    Int	sigNo = siginfo->si_signo;
53585665ca6fa29dd64754dabe50eb98f25896e752acerion//..    struct vki_ucontext uc;
53685665ca6fa29dd64754dabe50eb98f25896e752acerion//..
53785665ca6fa29dd64754dabe50eb98f25896e752acerion//..    vg_assert((flags & VKI_SA_SIGINFO) == 0);
53885665ca6fa29dd64754dabe50eb98f25896e752acerion//..
53985665ca6fa29dd64754dabe50eb98f25896e752acerion//..    esp -= sizeof(*frame);
54085665ca6fa29dd64754dabe50eb98f25896e752acerion//..    esp = ROUNDDN(esp, 16);
54185665ca6fa29dd64754dabe50eb98f25896e752acerion//..    frame = (struct sigframe *)esp;
54285665ca6fa29dd64754dabe50eb98f25896e752acerion//..
54385665ca6fa29dd64754dabe50eb98f25896e752acerion//..    if (!extend(tst, esp, sizeof(*frame)))
54485665ca6fa29dd64754dabe50eb98f25896e752acerion//..       return esp_top_of_frame;
54585665ca6fa29dd64754dabe50eb98f25896e752acerion//..
54685665ca6fa29dd64754dabe50eb98f25896e752acerion//..    /* retaddr, sigNo, siguContext fields are to be written */
54785665ca6fa29dd64754dabe50eb98f25896e752acerion//..    VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame",
54885665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 	     esp, offsetof(struct sigframe, vg) );
54985665ca6fa29dd64754dabe50eb98f25896e752acerion//..
55085665ca6fa29dd64754dabe50eb98f25896e752acerion//..    frame->sigNo = sigNo;
55185665ca6fa29dd64754dabe50eb98f25896e752acerion//..
55285665ca6fa29dd64754dabe50eb98f25896e752acerion//..    if (flags & VKI_SA_RESTORER)
55385665ca6fa29dd64754dabe50eb98f25896e752acerion//..       frame->retaddr = (Addr)restorer;
55485665ca6fa29dd64754dabe50eb98f25896e752acerion//..    else
55585665ca6fa29dd64754dabe50eb98f25896e752acerion//..       frame->retaddr
55685665ca6fa29dd64754dabe50eb98f25896e752acerion//..          = VG_(client_trampoline_code)+VG_(tramp_sigreturn_offset);
55785665ca6fa29dd64754dabe50eb98f25896e752acerion//..
55885665ca6fa29dd64754dabe50eb98f25896e752acerion//..    synth_ucontext(tst->tid, siginfo, mask, &uc, &frame->fpstate);
55985665ca6fa29dd64754dabe50eb98f25896e752acerion//..
56085665ca6fa29dd64754dabe50eb98f25896e752acerion//..    VG_(memcpy)(&frame->sigContext, &uc.uc_mcontext,
56185665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 	       sizeof(struct vki_sigcontext));
56285665ca6fa29dd64754dabe50eb98f25896e752acerion//..    frame->sigContext.oldmask = mask->sig[0];
56385665ca6fa29dd64754dabe50eb98f25896e752acerion//..
56485665ca6fa29dd64754dabe50eb98f25896e752acerion//..    VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
56585665ca6fa29dd64754dabe50eb98f25896e752acerion//..              esp, offsetof(struct sigframe, vg) );
56685665ca6fa29dd64754dabe50eb98f25896e752acerion//..
56785665ca6fa29dd64754dabe50eb98f25896e752acerion//..    build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
56885665ca6fa29dd64754dabe50eb98f25896e752acerion//..
56985665ca6fa29dd64754dabe50eb98f25896e752acerion//..    return esp;
57085665ca6fa29dd64754dabe50eb98f25896e752acerion//.. }
57185665ca6fa29dd64754dabe50eb98f25896e752acerion
57285665ca6fa29dd64754dabe50eb98f25896e752acerion
57385665ca6fa29dd64754dabe50eb98f25896e752acerion//.. static Addr build_rt_sigframe(ThreadState *tst,
57485665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 			      Addr esp_top_of_frame,
57585665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 			      const vki_siginfo_t *siginfo,
57685665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 			      void *handler, UInt flags,
57785665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 			      const vki_sigset_t *mask,
57885665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 			      void *restorer)
57985665ca6fa29dd64754dabe50eb98f25896e752acerion//.. {
58085665ca6fa29dd64754dabe50eb98f25896e752acerion//..    struct rt_sigframe *frame;
58185665ca6fa29dd64754dabe50eb98f25896e752acerion//..    Addr esp = esp_top_of_frame;
58285665ca6fa29dd64754dabe50eb98f25896e752acerion//..    Int	sigNo = siginfo->si_signo;
58385665ca6fa29dd64754dabe50eb98f25896e752acerion//..
58485665ca6fa29dd64754dabe50eb98f25896e752acerion//..    vg_assert((flags & VKI_SA_SIGINFO) != 0);
58585665ca6fa29dd64754dabe50eb98f25896e752acerion//..
58685665ca6fa29dd64754dabe50eb98f25896e752acerion//..    esp -= sizeof(*frame);
58785665ca6fa29dd64754dabe50eb98f25896e752acerion//..    esp = ROUNDDN(esp, 16);
58885665ca6fa29dd64754dabe50eb98f25896e752acerion//..    frame = (struct rt_sigframe *)esp;
58985665ca6fa29dd64754dabe50eb98f25896e752acerion//..
59085665ca6fa29dd64754dabe50eb98f25896e752acerion//..    if (!extend(tst, esp, sizeof(*frame)))
59185665ca6fa29dd64754dabe50eb98f25896e752acerion//..       return esp_top_of_frame;
59285665ca6fa29dd64754dabe50eb98f25896e752acerion//..
59385665ca6fa29dd64754dabe50eb98f25896e752acerion//..    /* retaddr, sigNo, pSiginfo, puContext fields are to be written */
59485665ca6fa29dd64754dabe50eb98f25896e752acerion//..    VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "rt signal handler frame",
59585665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 	     esp, offsetof(struct rt_sigframe, vg) );
59685665ca6fa29dd64754dabe50eb98f25896e752acerion//..
59785665ca6fa29dd64754dabe50eb98f25896e752acerion//..    frame->sigNo = sigNo;
59885665ca6fa29dd64754dabe50eb98f25896e752acerion//..
59985665ca6fa29dd64754dabe50eb98f25896e752acerion//..    if (flags & VKI_SA_RESTORER)
60085665ca6fa29dd64754dabe50eb98f25896e752acerion//..       frame->retaddr = (Addr)restorer;
60185665ca6fa29dd64754dabe50eb98f25896e752acerion//..    else
60285665ca6fa29dd64754dabe50eb98f25896e752acerion//..       frame->retaddr
60385665ca6fa29dd64754dabe50eb98f25896e752acerion//..          = VG_(client_trampoline_code)+VG_(tramp_rt_sigreturn_offset);
60485665ca6fa29dd64754dabe50eb98f25896e752acerion//..
60585665ca6fa29dd64754dabe50eb98f25896e752acerion//..    frame->psigInfo = (Addr)&frame->sigInfo;
60685665ca6fa29dd64754dabe50eb98f25896e752acerion//..    frame->puContext = (Addr)&frame->uContext;
60785665ca6fa29dd64754dabe50eb98f25896e752acerion//..    VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
60885665ca6fa29dd64754dabe50eb98f25896e752acerion//..
60985665ca6fa29dd64754dabe50eb98f25896e752acerion//..    /* SIGILL defines addr to be the faulting address */
61085665ca6fa29dd64754dabe50eb98f25896e752acerion//..    if (sigNo == VKI_SIGILL && siginfo->si_code > 0)
61185665ca6fa29dd64754dabe50eb98f25896e752acerion//..       frame->sigInfo._sifields._sigfault._addr
61285665ca6fa29dd64754dabe50eb98f25896e752acerion//..          = (void*)tst->arch.vex.guest_CIA;
61385665ca6fa29dd64754dabe50eb98f25896e752acerion//..
61485665ca6fa29dd64754dabe50eb98f25896e752acerion//..    synth_ucontext(tst->tid, siginfo, mask, &frame->uContext, &frame->fpstate);
61585665ca6fa29dd64754dabe50eb98f25896e752acerion//..
61685665ca6fa29dd64754dabe50eb98f25896e752acerion//..    VG_TRACK( post_mem_write,  Vg_CoreSignal, tst->tid,
61785665ca6fa29dd64754dabe50eb98f25896e752acerion//..              esp, offsetof(struct rt_sigframe, vg) );
61885665ca6fa29dd64754dabe50eb98f25896e752acerion//..
61985665ca6fa29dd64754dabe50eb98f25896e752acerion//..    build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
62085665ca6fa29dd64754dabe50eb98f25896e752acerion//..
62185665ca6fa29dd64754dabe50eb98f25896e752acerion//..    return esp;
62285665ca6fa29dd64754dabe50eb98f25896e752acerion//.. }
62385665ca6fa29dd64754dabe50eb98f25896e752acerion
62485665ca6fa29dd64754dabe50eb98f25896e752acerion
62585665ca6fa29dd64754dabe50eb98f25896e752acerion/* EXPORTED */
62685665ca6fa29dd64754dabe50eb98f25896e752acerionvoid VG_(sigframe_create)( ThreadId tid,
6278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj                           Bool on_altstack,
62885665ca6fa29dd64754dabe50eb98f25896e752acerion                           Addr sp_top_of_frame,
62985665ca6fa29dd64754dabe50eb98f25896e752acerion                           const vki_siginfo_t *siginfo,
630adacaf928b87b3921af283cf9e0eca55ccaaad96tom                           const struct vki_ucontext *siguc,
63185665ca6fa29dd64754dabe50eb98f25896e752acerion                           void *handler,
63285665ca6fa29dd64754dabe50eb98f25896e752acerion                           UInt flags,
63385665ca6fa29dd64754dabe50eb98f25896e752acerion                           const vki_sigset_t *mask,
63485665ca6fa29dd64754dabe50eb98f25896e752acerion		           void *restorer )
63585665ca6fa29dd64754dabe50eb98f25896e752acerion{
636e1c444e0986abaf738764252a9f730cdac49afbasewardj   struct vg_sig_private *priv;
637e1c444e0986abaf738764252a9f730cdac49afbasewardj   Addr sp;
638e1c444e0986abaf738764252a9f730cdac49afbasewardj   ThreadState *tst;
639e1c444e0986abaf738764252a9f730cdac49afbasewardj   Int sigNo = siginfo->si_signo;
640e1c444e0986abaf738764252a9f730cdac49afbasewardj   Addr faultaddr;
641e1c444e0986abaf738764252a9f730cdac49afbasewardj
642e1c444e0986abaf738764252a9f730cdac49afbasewardj   /* Stack must be 16-byte aligned */
643e1c444e0986abaf738764252a9f730cdac49afbasewardj   sp_top_of_frame &= ~0xf;
644e1c444e0986abaf738764252a9f730cdac49afbasewardj
645e1c444e0986abaf738764252a9f730cdac49afbasewardj   if (flags & VKI_SA_SIGINFO) {
646e1c444e0986abaf738764252a9f730cdac49afbasewardj      sp = sp_top_of_frame - sizeof(struct rt_sigframe);
647e1c444e0986abaf738764252a9f730cdac49afbasewardj   } else {
648e1c444e0986abaf738764252a9f730cdac49afbasewardj      sp = sp_top_of_frame - sizeof(struct nonrt_sigframe);
649e1c444e0986abaf738764252a9f730cdac49afbasewardj   }
650e1c444e0986abaf738764252a9f730cdac49afbasewardj
651e1c444e0986abaf738764252a9f730cdac49afbasewardj   tst = VG_(get_ThreadState)(tid);
652e1c444e0986abaf738764252a9f730cdac49afbasewardj
6537d4a28b986eaf98814c530a2074e117145b14d1fflorian   if (! ML_(sf_maybe_extend_stack)(tst, sp, sp_top_of_frame - sp, flags))
654e1c444e0986abaf738764252a9f730cdac49afbasewardj      return;
655e1c444e0986abaf738764252a9f730cdac49afbasewardj
656e1c444e0986abaf738764252a9f730cdac49afbasewardj   vg_assert(VG_IS_16_ALIGNED(sp));
657e1c444e0986abaf738764252a9f730cdac49afbasewardj
658e1c444e0986abaf738764252a9f730cdac49afbasewardj   /* Set up the stack chain pointer */
659e1c444e0986abaf738764252a9f730cdac49afbasewardj   VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame",
660e1c444e0986abaf738764252a9f730cdac49afbasewardj             sp, sizeof(UWord) );
661e1c444e0986abaf738764252a9f730cdac49afbasewardj   *(Addr *)sp = tst->arch.vex.guest_GPR1;
662e1c444e0986abaf738764252a9f730cdac49afbasewardj   VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
663e1c444e0986abaf738764252a9f730cdac49afbasewardj             sp, sizeof(UWord) );
664e1c444e0986abaf738764252a9f730cdac49afbasewardj
665e1c444e0986abaf738764252a9f730cdac49afbasewardj   faultaddr = (Addr)siginfo->_sifields._sigfault._addr;
666e1c444e0986abaf738764252a9f730cdac49afbasewardj   if (sigNo == VKI_SIGILL && siginfo->si_code > 0)
667e1c444e0986abaf738764252a9f730cdac49afbasewardj      faultaddr = tst->arch.vex.guest_CIA;
668e1c444e0986abaf738764252a9f730cdac49afbasewardj
669e1c444e0986abaf738764252a9f730cdac49afbasewardj   if (flags & VKI_SA_SIGINFO) {
670e1c444e0986abaf738764252a9f730cdac49afbasewardj      struct rt_sigframe *frame = (struct rt_sigframe *) sp;
671e1c444e0986abaf738764252a9f730cdac49afbasewardj      struct vki_ucontext *ucp = &frame->ucontext;
672e1c444e0986abaf738764252a9f730cdac49afbasewardj
673e1c444e0986abaf738764252a9f730cdac49afbasewardj      VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame siginfo",
674e1c444e0986abaf738764252a9f730cdac49afbasewardj                (Addr)&frame->siginfo, sizeof(frame->siginfo) );
675e1c444e0986abaf738764252a9f730cdac49afbasewardj      VG_(memcpy)(&frame->siginfo, siginfo, sizeof(*siginfo));
676e1c444e0986abaf738764252a9f730cdac49afbasewardj      VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
677e1c444e0986abaf738764252a9f730cdac49afbasewardj                (Addr)&frame->siginfo, sizeof(frame->siginfo) );
678e1c444e0986abaf738764252a9f730cdac49afbasewardj
679e1c444e0986abaf738764252a9f730cdac49afbasewardj      VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext",
680e1c444e0986abaf738764252a9f730cdac49afbasewardj                (Addr)ucp, offsetof(struct vki_ucontext, uc_pad) );
681e1c444e0986abaf738764252a9f730cdac49afbasewardj      ucp->uc_flags = 0;
682e1c444e0986abaf738764252a9f730cdac49afbasewardj      ucp->uc_link = 0;
683e1c444e0986abaf738764252a9f730cdac49afbasewardj      ucp->uc_stack = tst->altstack;
684e1c444e0986abaf738764252a9f730cdac49afbasewardj      VG_TRACK( post_mem_write, Vg_CoreSignal, tid, (Addr)ucp,
685e1c444e0986abaf738764252a9f730cdac49afbasewardj                offsetof(struct vki_ucontext, uc_pad) );
686e1c444e0986abaf738764252a9f730cdac49afbasewardj
687e1c444e0986abaf738764252a9f730cdac49afbasewardj      VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame ucontext",
688e1c444e0986abaf738764252a9f730cdac49afbasewardj                (Addr)&ucp->uc_regs,
689e1c444e0986abaf738764252a9f730cdac49afbasewardj                sizeof(ucp->uc_regs) + sizeof(ucp->uc_sigmask) );
690e1c444e0986abaf738764252a9f730cdac49afbasewardj      ucp->uc_regs = &ucp->uc_mcontext;
691e1c444e0986abaf738764252a9f730cdac49afbasewardj      ucp->uc_sigmask = tst->sig_mask;
692e1c444e0986abaf738764252a9f730cdac49afbasewardj      VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
693e1c444e0986abaf738764252a9f730cdac49afbasewardj                (Addr)&ucp->uc_regs,
694e1c444e0986abaf738764252a9f730cdac49afbasewardj                sizeof(ucp->uc_regs) + sizeof(ucp->uc_sigmask) );
695e1c444e0986abaf738764252a9f730cdac49afbasewardj
696a5940262b61b3bc245ecae5f10d5f8f77a52833bsewardj      stack_mcontext(&ucp->uc_mcontext, tst, True/*use_rt_sigreturn*/, faultaddr);
697e1c444e0986abaf738764252a9f730cdac49afbasewardj      priv = &frame->priv;
698e1c444e0986abaf738764252a9f730cdac49afbasewardj
699e1c444e0986abaf738764252a9f730cdac49afbasewardj      SET_SIGNAL_GPR(tid, 4, (Addr) &frame->siginfo);
700e1c444e0986abaf738764252a9f730cdac49afbasewardj      SET_SIGNAL_GPR(tid, 5, (Addr) ucp);
701e1c444e0986abaf738764252a9f730cdac49afbasewardj      /* the kernel sets this, though it doesn't seem to be in the ABI */
702e1c444e0986abaf738764252a9f730cdac49afbasewardj      SET_SIGNAL_GPR(tid, 6, (Addr) &frame->siginfo);
703e1c444e0986abaf738764252a9f730cdac49afbasewardj
704e1c444e0986abaf738764252a9f730cdac49afbasewardj   } else {
705e1c444e0986abaf738764252a9f730cdac49afbasewardj      /* non-RT signal delivery */
706e1c444e0986abaf738764252a9f730cdac49afbasewardj      struct nonrt_sigframe *frame = (struct nonrt_sigframe *) sp;
707e1c444e0986abaf738764252a9f730cdac49afbasewardj      struct vki_sigcontext *scp = &frame->sigcontext;
708e1c444e0986abaf738764252a9f730cdac49afbasewardj
709e1c444e0986abaf738764252a9f730cdac49afbasewardj      VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal frame sigcontext",
710e1c444e0986abaf738764252a9f730cdac49afbasewardj                (Addr)&scp->_unused[3], sizeof(*scp) - 3 * sizeof(UInt) );
711e1c444e0986abaf738764252a9f730cdac49afbasewardj      scp->signal = sigNo;
712e1c444e0986abaf738764252a9f730cdac49afbasewardj      scp->handler = (Addr) handler;
713e1c444e0986abaf738764252a9f730cdac49afbasewardj      scp->oldmask = tst->sig_mask.sig[0];
714e1c444e0986abaf738764252a9f730cdac49afbasewardj      scp->_unused[3] = tst->sig_mask.sig[1];
715e1c444e0986abaf738764252a9f730cdac49afbasewardj      VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
716e1c444e0986abaf738764252a9f730cdac49afbasewardj                (Addr)&scp->_unused[3], sizeof(*scp) - 3 * sizeof(UInt) );
717e1c444e0986abaf738764252a9f730cdac49afbasewardj
718a5940262b61b3bc245ecae5f10d5f8f77a52833bsewardj      stack_mcontext(&frame->mcontext, tst, False/*!use_rt_sigreturn*/, faultaddr);
719e1c444e0986abaf738764252a9f730cdac49afbasewardj      priv = &frame->priv;
720e1c444e0986abaf738764252a9f730cdac49afbasewardj
721e1c444e0986abaf738764252a9f730cdac49afbasewardj      SET_SIGNAL_GPR(tid, 4, (Addr) scp);
722e1c444e0986abaf738764252a9f730cdac49afbasewardj   }
723e1c444e0986abaf738764252a9f730cdac49afbasewardj
724e1c444e0986abaf738764252a9f730cdac49afbasewardj   priv->magicPI       = 0x31415927;
725e1c444e0986abaf738764252a9f730cdac49afbasewardj   priv->sigNo_private = sigNo;
7267cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   priv->vex_shadow1   = tst->arch.vex_shadow1;
7277cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   priv->vex_shadow2   = tst->arch.vex_shadow2;
728e1c444e0986abaf738764252a9f730cdac49afbasewardj
729e1c444e0986abaf738764252a9f730cdac49afbasewardj   SET_SIGNAL_GPR(tid, 1, sp);
730e1c444e0986abaf738764252a9f730cdac49afbasewardj   SET_SIGNAL_GPR(tid, 3, sigNo);
731e1c444e0986abaf738764252a9f730cdac49afbasewardj   tst->arch.vex.guest_CIA = (Addr) handler;
73285665ca6fa29dd64754dabe50eb98f25896e752acerion
73385665ca6fa29dd64754dabe50eb98f25896e752acerion//..    Addr		esp;
73485665ca6fa29dd64754dabe50eb98f25896e752acerion//..    ThreadState* tst = VG_(get_ThreadState)(tid);
73585665ca6fa29dd64754dabe50eb98f25896e752acerion//..
73685665ca6fa29dd64754dabe50eb98f25896e752acerion//..    if (flags & VKI_SA_SIGINFO)
73785665ca6fa29dd64754dabe50eb98f25896e752acerion//..       esp = build_rt_sigframe(tst, esp_top_of_frame, siginfo,
73885665ca6fa29dd64754dabe50eb98f25896e752acerion//..                                    handler, flags, mask, restorer);
73985665ca6fa29dd64754dabe50eb98f25896e752acerion//..    else
74085665ca6fa29dd64754dabe50eb98f25896e752acerion//..       esp = build_sigframe(tst, esp_top_of_frame,
74185665ca6fa29dd64754dabe50eb98f25896e752acerion//..                                 siginfo, handler, flags, mask, restorer);
74285665ca6fa29dd64754dabe50eb98f25896e752acerion//..
74385665ca6fa29dd64754dabe50eb98f25896e752acerion//..    /* Set the thread so it will next run the handler. */
74485665ca6fa29dd64754dabe50eb98f25896e752acerion//..    /* tst->m_esp  = esp; */
74585665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SET_SIGNAL_ESP(tid, esp);
74685665ca6fa29dd64754dabe50eb98f25896e752acerion//..
74785665ca6fa29dd64754dabe50eb98f25896e752acerion//..    //VG_(printf)("handler = %p\n", handler);
74885665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->arch.vex.guest_CIA = (Addr) handler;
74985665ca6fa29dd64754dabe50eb98f25896e752acerion//..    /* This thread needs to be marked runnable, but we leave that the
75085665ca6fa29dd64754dabe50eb98f25896e752acerion//..       caller to do. */
751e1c444e0986abaf738764252a9f730cdac49afbasewardj
752e1c444e0986abaf738764252a9f730cdac49afbasewardj   if (0)
753a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart      VG_(printf)("pushed signal frame; %%R1 now = %#lx, "
754a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart                  "next %%CIA = %#x, status=%d\n",
75597f1d337555234c20f3f1d0dd0b22b2a7d571616florian		  sp, tst->arch.vex.guest_CIA, (Int)tst->status);
75685665ca6fa29dd64754dabe50eb98f25896e752acerion}
75785665ca6fa29dd64754dabe50eb98f25896e752acerion
758e1c444e0986abaf738764252a9f730cdac49afbasewardj
75985665ca6fa29dd64754dabe50eb98f25896e752acerion/*------------------------------------------------------------*/
76085665ca6fa29dd64754dabe50eb98f25896e752acerion/*--- Destroying signal frames                             ---*/
76185665ca6fa29dd64754dabe50eb98f25896e752acerion/*------------------------------------------------------------*/
76285665ca6fa29dd64754dabe50eb98f25896e752acerion
76385665ca6fa29dd64754dabe50eb98f25896e752acerion//.. /* Return False and don't do anything, just set the client to take a
76485665ca6fa29dd64754dabe50eb98f25896e752acerion//..    segfault, if it looks like the frame is corrupted. */
76585665ca6fa29dd64754dabe50eb98f25896e752acerion//.. static
76685665ca6fa29dd64754dabe50eb98f25896e752acerion//.. Bool restore_vg_sigframe ( ThreadState *tst,
76785665ca6fa29dd64754dabe50eb98f25896e752acerion//..                            struct vg_sigframe *frame, Int *sigNo )
76885665ca6fa29dd64754dabe50eb98f25896e752acerion//.. {
76985665ca6fa29dd64754dabe50eb98f25896e752acerion//..    if (frame->magicPI != 0x31415927 ||
77085665ca6fa29dd64754dabe50eb98f25896e752acerion//..        frame->magicE  != 0x27182818) {
77185665ca6fa29dd64754dabe50eb98f25896e752acerion//..       VG_(message)(Vg_UserMsg, "Thread %d return signal frame "
77285665ca6fa29dd64754dabe50eb98f25896e752acerion//..                                "corrupted.  Killing process.",
77385665ca6fa29dd64754dabe50eb98f25896e752acerion//.. 		   tst->tid);
77485665ca6fa29dd64754dabe50eb98f25896e752acerion//..       VG_(set_default_handler)(VKI_SIGSEGV);
77585665ca6fa29dd64754dabe50eb98f25896e752acerion//..       VG_(synth_fault)(tst->tid);
77685665ca6fa29dd64754dabe50eb98f25896e752acerion//..       *sigNo = VKI_SIGSEGV;
77785665ca6fa29dd64754dabe50eb98f25896e752acerion//..       return False;
77885665ca6fa29dd64754dabe50eb98f25896e752acerion//..    }
77985665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->sig_mask        = frame->mask;
78085665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->tmp_sig_mask    = frame->mask;
78185665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->arch.vex_shadow = frame->vex_shadow;
78285665ca6fa29dd64754dabe50eb98f25896e752acerion//..    /* HACK ALERT */
78385665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->arch.vex        = frame->vex;
78485665ca6fa29dd64754dabe50eb98f25896e752acerion//..    /* end HACK ALERT */
78585665ca6fa29dd64754dabe50eb98f25896e752acerion//..    *sigNo               = frame->sigNo_private;
78685665ca6fa29dd64754dabe50eb98f25896e752acerion//..    return True;
78785665ca6fa29dd64754dabe50eb98f25896e752acerion//.. }
78885665ca6fa29dd64754dabe50eb98f25896e752acerion
78985665ca6fa29dd64754dabe50eb98f25896e752acerion//.. static
79085665ca6fa29dd64754dabe50eb98f25896e752acerion//.. void restore_sigcontext( ThreadState *tst,
79185665ca6fa29dd64754dabe50eb98f25896e752acerion//..                          struct vki_sigcontext *sc )
79285665ca6fa29dd64754dabe50eb98f25896e752acerion//.. //..                          struct vki_sigcontext *sc, struct _vki_fpstate *fpstate )
79385665ca6fa29dd64754dabe50eb98f25896e752acerion//.. {
79485665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->arch.vex.guest_EAX     = sc->eax;
79585665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->arch.vex.guest_ECX     = sc->ecx;
79685665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->arch.vex.guest_EDX     = sc->edx;
79785665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->arch.vex.guest_EBX     = sc->ebx;
79885665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->arch.vex.guest_EBP     = sc->ebp;
79985665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->arch.vex.guest_ESP     = sc->esp;
80085665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->arch.vex.guest_ESI     = sc->esi;
80185665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->arch.vex.guest_EDI     = sc->edi;
80285665ca6fa29dd64754dabe50eb98f25896e752acerion//.. //::    tst->arch.vex.guest_eflags  = sc->eflags;
80385665ca6fa29dd64754dabe50eb98f25896e752acerion//.. //::    tst->arch.vex.guest_EIP     = sc->eip;
80485665ca6fa29dd64754dabe50eb98f25896e752acerion//..
80585665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->arch.vex.guest_CS      = sc->cs;
80685665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->arch.vex.guest_SS      = sc->ss;
80785665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->arch.vex.guest_DS      = sc->ds;
80885665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->arch.vex.guest_ES      = sc->es;
80985665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->arch.vex.guest_FS      = sc->fs;
81085665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst->arch.vex.guest_GS      = sc->gs;
81185665ca6fa29dd64754dabe50eb98f25896e752acerion//..
81285665ca6fa29dd64754dabe50eb98f25896e752acerion//.. //::    restore_i387(&tst->arch, fpstate);
81385665ca6fa29dd64754dabe50eb98f25896e752acerion//.. }
81485665ca6fa29dd64754dabe50eb98f25896e752acerion
81585665ca6fa29dd64754dabe50eb98f25896e752acerion
81685665ca6fa29dd64754dabe50eb98f25896e752acerion//.. static
81785665ca6fa29dd64754dabe50eb98f25896e752acerion//.. SizeT restore_sigframe ( ThreadState *tst,
81885665ca6fa29dd64754dabe50eb98f25896e752acerion//..                          struct sigframe *frame, Int *sigNo )
81985665ca6fa29dd64754dabe50eb98f25896e752acerion//.. {
82085665ca6fa29dd64754dabe50eb98f25896e752acerion//..    if (restore_vg_sigframe(tst, &frame->vg, sigNo))
82185665ca6fa29dd64754dabe50eb98f25896e752acerion//..       restore_sigcontext(tst, &frame->sigContext, &frame->fpstate);
82285665ca6fa29dd64754dabe50eb98f25896e752acerion//..    return sizeof(*frame);
82385665ca6fa29dd64754dabe50eb98f25896e752acerion//.. }
82485665ca6fa29dd64754dabe50eb98f25896e752acerion
82585665ca6fa29dd64754dabe50eb98f25896e752acerion//.. static
82685665ca6fa29dd64754dabe50eb98f25896e752acerion//.. SizeT restore_rt_sigframe ( ThreadState *tst,
82785665ca6fa29dd64754dabe50eb98f25896e752acerion//..                             struct rt_sigframe *frame, Int *sigNo )
82885665ca6fa29dd64754dabe50eb98f25896e752acerion//.. {
82985665ca6fa29dd64754dabe50eb98f25896e752acerion//..    if (restore_vg_sigframe(tst, &frame->vg, sigNo))
83085665ca6fa29dd64754dabe50eb98f25896e752acerion//..       restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate);
83185665ca6fa29dd64754dabe50eb98f25896e752acerion//..    return sizeof(*frame);
83285665ca6fa29dd64754dabe50eb98f25896e752acerion//.. }
83385665ca6fa29dd64754dabe50eb98f25896e752acerion
83485665ca6fa29dd64754dabe50eb98f25896e752acerion
835e1c444e0986abaf738764252a9f730cdac49afbasewardj/* EXPORTED */
836e1c444e0986abaf738764252a9f730cdac49afbasewardjvoid VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
837e1c444e0986abaf738764252a9f730cdac49afbasewardj{
838e1c444e0986abaf738764252a9f730cdac49afbasewardj   ThreadState *tst;
839e1c444e0986abaf738764252a9f730cdac49afbasewardj   struct vg_sig_private *priv;
840e1c444e0986abaf738764252a9f730cdac49afbasewardj   Addr sp;
841e1c444e0986abaf738764252a9f730cdac49afbasewardj   UInt frame_size;
842e1c444e0986abaf738764252a9f730cdac49afbasewardj   struct vki_mcontext *mc;
843e1c444e0986abaf738764252a9f730cdac49afbasewardj   Int sigNo;
844e1c444e0986abaf738764252a9f730cdac49afbasewardj   Bool has_siginfo = isRT;
845e1c444e0986abaf738764252a9f730cdac49afbasewardj
846e1c444e0986abaf738764252a9f730cdac49afbasewardj   vg_assert(VG_(is_valid_tid)(tid));
847e1c444e0986abaf738764252a9f730cdac49afbasewardj   tst = VG_(get_ThreadState)(tid);
848e1c444e0986abaf738764252a9f730cdac49afbasewardj
849e1c444e0986abaf738764252a9f730cdac49afbasewardj   /* Check that the stack frame looks valid */
850e1c444e0986abaf738764252a9f730cdac49afbasewardj   sp = tst->arch.vex.guest_GPR1;
851e1c444e0986abaf738764252a9f730cdac49afbasewardj   vg_assert(VG_IS_16_ALIGNED(sp));
8528e732389ade08ba2b36f49c018a90170177e6489sewardj   /* JRS 17 Nov 05: This code used to check that *sp -- which should
8538e732389ade08ba2b36f49c018a90170177e6489sewardj      have been set by the stwu at the start of the handler -- points
8548e732389ade08ba2b36f49c018a90170177e6489sewardj      to just above the frame (ie, the previous frame).  However, that
8558e732389ade08ba2b36f49c018a90170177e6489sewardj      isn't valid when delivering signals on alt stacks.  So I removed
8568e732389ade08ba2b36f49c018a90170177e6489sewardj      it.  The frame is still sanity-checked using the priv->magicPI
8578e732389ade08ba2b36f49c018a90170177e6489sewardj      field. */
858e1c444e0986abaf738764252a9f730cdac49afbasewardj
859e1c444e0986abaf738764252a9f730cdac49afbasewardj   if (has_siginfo) {
860e1c444e0986abaf738764252a9f730cdac49afbasewardj      struct rt_sigframe *frame = (struct rt_sigframe *)sp;
8618e732389ade08ba2b36f49c018a90170177e6489sewardj      frame_size = sizeof(*frame);
862e1c444e0986abaf738764252a9f730cdac49afbasewardj      mc = &frame->ucontext.uc_mcontext;
863e1c444e0986abaf738764252a9f730cdac49afbasewardj      priv = &frame->priv;
8648e732389ade08ba2b36f49c018a90170177e6489sewardj      vg_assert(priv->magicPI == 0x31415927);
865e1c444e0986abaf738764252a9f730cdac49afbasewardj      tst->sig_mask = frame->ucontext.uc_sigmask;
866e1c444e0986abaf738764252a9f730cdac49afbasewardj   } else {
867e1c444e0986abaf738764252a9f730cdac49afbasewardj      struct nonrt_sigframe *frame = (struct nonrt_sigframe *)sp;
8688e732389ade08ba2b36f49c018a90170177e6489sewardj      frame_size = sizeof(*frame);
869e1c444e0986abaf738764252a9f730cdac49afbasewardj      mc = &frame->mcontext;
870e1c444e0986abaf738764252a9f730cdac49afbasewardj      priv = &frame->priv;
8718e732389ade08ba2b36f49c018a90170177e6489sewardj      vg_assert(priv->magicPI == 0x31415927);
872e1c444e0986abaf738764252a9f730cdac49afbasewardj      tst->sig_mask.sig[0] = frame->sigcontext.oldmask;
873e1c444e0986abaf738764252a9f730cdac49afbasewardj      tst->sig_mask.sig[1] = frame->sigcontext._unused[3];
874e1c444e0986abaf738764252a9f730cdac49afbasewardj   }
875e1c444e0986abaf738764252a9f730cdac49afbasewardj   tst->tmp_sig_mask = tst->sig_mask;
876e1c444e0986abaf738764252a9f730cdac49afbasewardj
877e1c444e0986abaf738764252a9f730cdac49afbasewardj   sigNo = priv->sigNo_private;
878e1c444e0986abaf738764252a9f730cdac49afbasewardj
879e1c444e0986abaf738764252a9f730cdac49afbasewardj#  define DO(gpr)  tst->arch.vex.guest_GPR##gpr = mc->mc_gregs[VKI_PT_R0+gpr]
880e1c444e0986abaf738764252a9f730cdac49afbasewardj   DO(0);  DO(1);  DO(2);  DO(3);  DO(4);  DO(5);  DO(6);  DO(7);
881e1c444e0986abaf738764252a9f730cdac49afbasewardj   DO(8);  DO(9);  DO(10); DO(11); DO(12); DO(13); DO(14); DO(15);
882e1c444e0986abaf738764252a9f730cdac49afbasewardj   DO(16); DO(17); DO(18); DO(19); DO(20); DO(21); DO(22); DO(23);
883e1c444e0986abaf738764252a9f730cdac49afbasewardj   DO(24); DO(25); DO(26); DO(27); DO(28); DO(29); DO(30); DO(31);
884e1c444e0986abaf738764252a9f730cdac49afbasewardj#  undef DO
885e1c444e0986abaf738764252a9f730cdac49afbasewardj
886e1c444e0986abaf738764252a9f730cdac49afbasewardj   tst->arch.vex.guest_CIA = mc->mc_gregs[VKI_PT_NIP];
887e1c444e0986abaf738764252a9f730cdac49afbasewardj
888e1c444e0986abaf738764252a9f730cdac49afbasewardj   // Umm ... ? (jrs 2005 July 8)
889e1c444e0986abaf738764252a9f730cdac49afbasewardj   // tst->arch.m_orig_gpr3 = mc->mc_gregs[VKI_PT_ORIG_R3];
890e1c444e0986abaf738764252a9f730cdac49afbasewardj
891463b3d94b19ec820c2378dde6d43d2c1f553a8d0sewardj   LibVEX_GuestPPC32_put_CR( mc->mc_gregs[VKI_PT_CCR], &tst->arch.vex );
892e1c444e0986abaf738764252a9f730cdac49afbasewardj
893e1c444e0986abaf738764252a9f730cdac49afbasewardj   tst->arch.vex.guest_LR  = mc->mc_gregs[VKI_PT_LNK];
894e1c444e0986abaf738764252a9f730cdac49afbasewardj   tst->arch.vex.guest_CTR = mc->mc_gregs[VKI_PT_CTR];
895463b3d94b19ec820c2378dde6d43d2c1f553a8d0sewardj   LibVEX_GuestPPC32_put_XER( mc->mc_gregs[VKI_PT_XER], &tst->arch.vex );
896e1c444e0986abaf738764252a9f730cdac49afbasewardj
8977cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   tst->arch.vex_shadow1 = priv->vex_shadow1;
8987cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj   tst->arch.vex_shadow2 = priv->vex_shadow2;
899e1c444e0986abaf738764252a9f730cdac49afbasewardj
900e1c444e0986abaf738764252a9f730cdac49afbasewardj   VG_TRACK(die_mem_stack_signal, sp, frame_size);
901e1c444e0986abaf738764252a9f730cdac49afbasewardj
902e1c444e0986abaf738764252a9f730cdac49afbasewardj   if (VG_(clo_trace_signals))
903e1c444e0986abaf738764252a9f730cdac49afbasewardj      VG_(message)(Vg_DebugMsg,
90497f1d337555234c20f3f1d0dd0b22b2a7d571616florian                   "vg_pop_signal_frame (thread %u): "
905738856f99eea33d86ce91dcb1d6cd5b151e307casewardj                   "isRT=%d valid magic; EIP=%#x\n",
906e1c444e0986abaf738764252a9f730cdac49afbasewardj                   tid, has_siginfo, tst->arch.vex.guest_CIA);
907e1c444e0986abaf738764252a9f730cdac49afbasewardj
908e1c444e0986abaf738764252a9f730cdac49afbasewardj   /* tell the tools */
909e1c444e0986abaf738764252a9f730cdac49afbasewardj   VG_TRACK( post_deliver_signal, tid, sigNo );
910e1c444e0986abaf738764252a9f730cdac49afbasewardj
91185665ca6fa29dd64754dabe50eb98f25896e752acerion//..    Addr          esp;
91285665ca6fa29dd64754dabe50eb98f25896e752acerion//..    ThreadState*  tst;
91385665ca6fa29dd64754dabe50eb98f25896e752acerion//..    SizeT	 size;
91485665ca6fa29dd64754dabe50eb98f25896e752acerion//..    Int		 sigNo;
91585665ca6fa29dd64754dabe50eb98f25896e752acerion//..
91685665ca6fa29dd64754dabe50eb98f25896e752acerion//..    tst = VG_(get_ThreadState)(tid);
91785665ca6fa29dd64754dabe50eb98f25896e752acerion//..
91885665ca6fa29dd64754dabe50eb98f25896e752acerion//..    /* Correctly reestablish the frame base address. */
91985665ca6fa29dd64754dabe50eb98f25896e752acerion//..    esp   = tst->arch.vex.guest_ESP;
92085665ca6fa29dd64754dabe50eb98f25896e752acerion//..
92185665ca6fa29dd64754dabe50eb98f25896e752acerion//..    if (!isRT)
92285665ca6fa29dd64754dabe50eb98f25896e752acerion//..       size = restore_sigframe(tst, (struct sigframe *)esp, &sigNo);
92385665ca6fa29dd64754dabe50eb98f25896e752acerion//..    else
92485665ca6fa29dd64754dabe50eb98f25896e752acerion//..       size = restore_rt_sigframe(tst, (struct rt_sigframe *)esp, &sigNo);
92585665ca6fa29dd64754dabe50eb98f25896e752acerion//..
92685665ca6fa29dd64754dabe50eb98f25896e752acerion//..    VG_TRACK( die_mem_stack_signal, esp, size );
92785665ca6fa29dd64754dabe50eb98f25896e752acerion//..
92885665ca6fa29dd64754dabe50eb98f25896e752acerion//..    if (VG_(clo_trace_signals))
92985665ca6fa29dd64754dabe50eb98f25896e752acerion//..       VG_(message)(
93085665ca6fa29dd64754dabe50eb98f25896e752acerion//..          Vg_DebugMsg,
93197f1d337555234c20f3f1d0dd0b22b2a7d571616florian//..          "VG_(signal_return) (thread %u): isRT=%d valid magic; EIP=%p",
93285665ca6fa29dd64754dabe50eb98f25896e752acerion//..          tid, isRT, tst->arch.vex.guest_EIP);
93385665ca6fa29dd64754dabe50eb98f25896e752acerion//..
93485665ca6fa29dd64754dabe50eb98f25896e752acerion//..    /* tell the tools */
93585665ca6fa29dd64754dabe50eb98f25896e752acerion//..    VG_TRACK( post_deliver_signal, tid, sigNo );
936e1c444e0986abaf738764252a9f730cdac49afbasewardj}
93785665ca6fa29dd64754dabe50eb98f25896e752acerion
9388b68b64759254d514d98328c496cbd88cde4c9a5njn#endif // defined(VGP_ppc32_linux)
9398b68b64759254d514d98328c496cbd88cde4c9a5njn
94085665ca6fa29dd64754dabe50eb98f25896e752acerion/*--------------------------------------------------------------------*/
9418b68b64759254d514d98328c496cbd88cde4c9a5njn/*--- end                                                          ---*/
94285665ca6fa29dd64754dabe50eb98f25896e752acerion/*--------------------------------------------------------------------*/
943