1f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
2f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/*--------------------------------------------------------------------*/
3f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/*--- Create/destroy signal delivery frames.                       ---*/
4f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/*---                                        sigframe-x86-darwin.c ---*/
5f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/*--------------------------------------------------------------------*/
6f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
7f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/*
8f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   This file is part of Valgrind, a dynamic binary instrumentation
9f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   framework.
10f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
11b3a1e4bffbdbbf38304f216af405009868f43628sewardj   Copyright (C) 2006-2015 OpenWorks Ltd
12f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      info@open-works.co.uk
13f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
14f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   This program is free software; you can redistribute it and/or
15f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   modify it under the terms of the GNU General Public License as
16f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   published by the Free Software Foundation; either version 2 of the
17f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   License, or (at your option) any later version.
18f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
19f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   This program is distributed in the hope that it will be useful, but
20f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   WITHOUT ANY WARRANTY; without even the implied warranty of
21f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   General Public License for more details.
23f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
24f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   You should have received a copy of the GNU General Public License
25f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   along with this program; if not, write to the Free Software
26f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   02111-1307, USA.
28f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
29f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   The GNU General Public License is contained in the file COPYING.
30f76d27a697a7b0bf3b84490baf60623fc96a23afnjn*/
31f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
328b68b64759254d514d98328c496cbd88cde4c9a5njn#if defined(VGP_x86_darwin)
338b68b64759254d514d98328c496cbd88cde4c9a5njn
34f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_basics.h"
35f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_vki.h"
36f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_vkiscnums.h"
37f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_threadstate.h"
38f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_aspacemgr.h"
39f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_libcbase.h"
40f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_libcassert.h"
41f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_libcprint.h"
42f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_machine.h"
43f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_options.h"
44f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_signals.h"
45f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_tooliface.h"
46f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_trampoline.h"
47f76d27a697a7b0bf3b84490baf60623fc96a23afnjn#include "pub_core_sigframe.h"      /* self */
480dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd#include "priv_sigframe.h"
49f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
50f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
510dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd/* Originally copied from ppc32-aix5 code.
520dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   Produce a frame with layout entirely of our own choosing.
53f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
540dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   This module creates and removes signal frames for signal deliveries
550dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   on x86-darwin.  The machine state is saved in a ucontext and retrieved
560dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   from it later, so the handler can modify it and return.
57f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
58f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   Frame should have a 16-aligned size, just in case that turns out to
59f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   be important for Darwin.  (be conservative)
60f76d27a697a7b0bf3b84490baf60623fc96a23afnjn*/
61f76d27a697a7b0bf3b84490baf60623fc96a23afnjnstruct hacky_sigframe {
62f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   /* first four words look like a call to a 3-arg x86 function */
63f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   UInt             returnAddr;
64f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   UInt             a1_signo;
65f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   UInt             a2_siginfo;
66f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   UInt             a3_ucontext;
67f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   UChar            lower_guardzone[512];  // put nothing here
68a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   VexGuestX86State vex;
69a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   VexGuestX86State vex_shadow1;
70a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   VexGuestX86State vex_shadow2;
71f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   vki_siginfo_t    fake_siginfo;
72f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   struct vki_ucontext fake_ucontext;
73f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   UInt             magicPI;
74f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   UInt             sigNo_private;
75f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   vki_sigset_t     mask; // saved sigmask; restore when hdlr returns
760dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   UInt             __pad[3];
77f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   UChar            upper_guardzone[512]; // put nothing here
78ea2d6fd6aaf98d261df9fdf580542ebf01b7fba4njn   // and don't zero it, since that might overwrite the client's
79ea2d6fd6aaf98d261df9fdf580542ebf01b7fba4njn   // stack redzone, at least on archs which have one
80f76d27a697a7b0bf3b84490baf60623fc96a23afnjn};
81f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
820dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd/* Create a plausible-looking sigcontext from the thread's
830dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   Vex guest state.  NOTE: does not fill in the FP or SSE
840dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   bits of sigcontext at the moment.
850dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd */
860dc35261140f7612f1e516a9fa2a977f4e30e04erhyskiddstatic void synthesize_ucontext(ThreadState *tst,
870dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd				struct vki_ucontext *uc,
880dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd				const struct vki_ucontext *siguc)
890dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd{
900dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   VG_(memset)(uc, 0, sizeof(*uc));
910dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd
920dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   if (siguc) uc->uc_sigmask = siguc->uc_sigmask;
930dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   uc->uc_stack = tst->altstack;
940dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   uc->uc_mcontext = &uc->__mcontext_data;
950dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd
960dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd#  define SC2(reg,REG)  uc->__mcontext_data.__ss.reg = tst->arch.vex.guest_##REG
970dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(__edi,EDI);
980dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(__esi,ESI);
990dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(__ebp,EBP);
1000dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(__ebx,EBX);
1010dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(__edx,EDX);
1020dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(__eax,EAX);
1030dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(__ecx,ECX);
1040dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(__esp,ESP);
1050dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(__eip,EIP);
1060dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   uc->__mcontext_data.__ss.__eflags = LibVEX_GuestX86_get_eflags(&tst->arch.vex);
1070dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd
1080dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   if (siguc)
1090dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd      uc->__mcontext_data.__es = siguc->__mcontext_data.__es;
1100dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd#  undef SC2
1110dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd}
1120dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd
1130dc35261140f7612f1e516a9fa2a977f4e30e04erhyskiddstatic void restore_from_ucontext(ThreadState *tst,
1140dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd				  const struct vki_ucontext *uc)
1150dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd{
1160dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd#  define SC2(REG,reg)  tst->arch.vex.guest_##REG = uc->__mcontext_data.__ss.reg
1170dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(EDI,__edi);
1180dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(ESI,__esi);
1190dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(EBP,__ebp);
1200dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(EBX,__ebx);
1210dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(EDX,__edx);
1220dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(EAX,__eax);
1230dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(ECX,__ecx);
1240dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(ESP,__esp);
1250dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   SC2(EIP,__eip);
1260dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   /* There doesn't seem to be an easy way to restore eflags */
1270dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd#  undef SC2
1280dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd}
129f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
130f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* Create a signal frame for thread 'tid'.  Make a 3-arg frame
131f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   regardless of whether the client originally requested a 1-arg
132f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   version (no SA_SIGINFO) or a 3-arg one (SA_SIGINFO) since in the
133f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   former case, the x86 calling conventions will simply cause the
134f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   extra 2 args to be ignored (inside the handler). */
135f76d27a697a7b0bf3b84490baf60623fc96a23afnjnvoid VG_(sigframe_create) ( ThreadId tid,
1368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj                            Bool on_altstack,
137f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                            Addr sp_top_of_frame,
138f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                            const vki_siginfo_t *siginfo,
139f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                            const struct vki_ucontext *siguc,
140f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                            void *handler,
141f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                            UInt flags,
142f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                            const vki_sigset_t *mask,
143f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                            void *restorer )
144f76d27a697a7b0bf3b84490baf60623fc96a23afnjn{
145f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   ThreadState* tst;
146f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   Addr esp;
147f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   struct hacky_sigframe* frame;
148f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   Int sigNo = siginfo->si_signo;
149f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
150f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   vg_assert(VG_IS_16_ALIGNED(sizeof(struct hacky_sigframe)));
151f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
152f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   sp_top_of_frame &= ~0xf;
153f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   esp = sp_top_of_frame - sizeof(struct hacky_sigframe);
154341038321790743b2ecf4ce9a410fc14fb0bb719sewardj   esp -= 4; /* ELF ABI says that esp+4 must be 16 aligned on
155341038321790743b2ecf4ce9a410fc14fb0bb719sewardj                entry to a function. */
156f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
157f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   tst = VG_(get_ThreadState)(tid);
1587d4a28b986eaf98814c530a2074e117145b14d1fflorian   if (! ML_(sf_maybe_extend_stack)(tst, esp, sp_top_of_frame - esp, flags))
159f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      return;
160f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
161341038321790743b2ecf4ce9a410fc14fb0bb719sewardj   vg_assert(VG_IS_16_ALIGNED(esp+4));
162f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
163f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   frame = (struct hacky_sigframe *) esp;
164f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
1650dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   /* clear it (very conservatively) */
166e1aff6df9f15197f4791cdb56874e0d9ba74737bflorian   VG_(memset)(&frame->lower_guardzone, 0, sizeof frame->lower_guardzone);
167a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   VG_(memset)(&frame->vex,      0, sizeof(VexGuestX86State));
168a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   VG_(memset)(&frame->vex_shadow1, 0, sizeof(VexGuestX86State));
169a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   VG_(memset)(&frame->vex_shadow2, 0, sizeof(VexGuestX86State));
170f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   VG_(memset)(&frame->fake_siginfo,  0, sizeof(frame->fake_siginfo));
171f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   VG_(memset)(&frame->fake_ucontext, 0, sizeof(frame->fake_ucontext));
172f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
173f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   /* save stuff in frame */
174a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   frame->vex           = tst->arch.vex;
175a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   frame->vex_shadow1   = tst->arch.vex_shadow1;
176a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   frame->vex_shadow2   = tst->arch.vex_shadow2;
177f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   frame->sigNo_private = sigNo;
178f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   frame->mask          = tst->sig_mask;
179f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   frame->magicPI       = 0x31415927;
180f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
1810dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   /* Fill in the siginfo and ucontext.  */
1820dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   synthesize_ucontext(tst, &frame->fake_ucontext, siguc);
1830dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   frame->fake_siginfo = *siginfo;
184f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
185f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   /* Set up stack pointer */
186f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   vg_assert(esp == (Addr)&frame->returnAddr);
187f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   VG_(set_SP)(tid, esp);
188f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(UInt));
189f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
190f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   /* Set up program counter */
191f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   VG_(set_IP)(tid, (UInt)handler);
192f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_INSTR_PTR, sizeof(UInt));
193f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
194f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   /* Set up RA and args for the frame */
195f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame",
196f76d27a697a7b0bf3b84490baf60623fc96a23afnjn             (Addr)frame, 4*sizeof(UInt) );
197f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   frame->returnAddr  = (UInt)&VG_(x86_darwin_SUBST_FOR_sigreturn);
198a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd
199a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   frame->a1_signo    =         sigNo;
200a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   frame->a2_siginfo  = (UInt)  &frame->fake_siginfo;
201a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   frame->a3_ucontext = (UInt)  &frame->fake_ucontext;
202a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd
203f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
204f76d27a697a7b0bf3b84490baf60623fc96a23afnjn             (Addr)frame, 4*sizeof(UInt) );
205f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
206f76d27a697a7b0bf3b84490baf60623fc96a23afnjn             (Addr)&frame->fake_siginfo, sizeof(frame->fake_siginfo));
207f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   VG_TRACK( post_mem_write, Vg_CoreSignal, tid,
208f76d27a697a7b0bf3b84490baf60623fc96a23afnjn             (Addr)&frame->fake_ucontext, sizeof(frame->fake_ucontext));
209f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
210f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   if (VG_(clo_trace_signals))
211f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      VG_(message)(Vg_DebugMsg,
21297f1d337555234c20f3f1d0dd0b22b2a7d571616florian                   "sigframe_create (thread %u): "
213341038321790743b2ecf4ce9a410fc14fb0bb719sewardj                   "next EIP=%#lx, next ESP=%#lx\n",
214f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                   tid, (Addr)handler, (Addr)frame );
215f76d27a697a7b0bf3b84490baf60623fc96a23afnjn}
216f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
217f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
218f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/* Remove a signal frame from thread 'tid's stack, and restore the CPU
219f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   state from it.  Note, isRT is irrelevant here. */
220f76d27a697a7b0bf3b84490baf60623fc96a23afnjnvoid VG_(sigframe_destroy)( ThreadId tid, Bool isRT )
221f76d27a697a7b0bf3b84490baf60623fc96a23afnjn{
222f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   ThreadState *tst;
223f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   Addr esp;
224f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   Int sigNo;
225f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   struct hacky_sigframe* frame;
226f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
227f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   vg_assert(VG_(is_valid_tid)(tid));
228f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   tst = VG_(get_ThreadState)(tid);
229f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
230f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   /* Check that the stack frame looks valid */
231f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   esp = VG_(get_SP)(tid);
232f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
233f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   /* why -4 ? because the signal handler's return will have popped
234341038321790743b2ecf4ce9a410fc14fb0bb719sewardj      the return address off the stack; and the return address is the
235f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      lowest-addressed element of hacky_sigframe. */
236f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   frame = (struct hacky_sigframe*)(esp - 4);
237f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   vg_assert(frame->magicPI == 0x31415927);
238341038321790743b2ecf4ce9a410fc14fb0bb719sewardj
239a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   /* This +4 is because of the -4 referred to in the ELF ABI comment
240341038321790743b2ecf4ce9a410fc14fb0bb719sewardj      in VG_(sigframe_create) just above. */
241341038321790743b2ecf4ce9a410fc14fb0bb719sewardj   vg_assert(VG_IS_16_ALIGNED((Addr)frame + 4));
242f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
243a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   /* restore the entire guest state, and shadows, from the frame. */
244a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   tst->arch.vex            = frame->vex;
245a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   tst->arch.vex_shadow1    = frame->vex_shadow1;
246a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   tst->arch.vex_shadow2    = frame->vex_shadow2;
2470dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd   restore_from_ucontext(tst, &frame->fake_ucontext);
2480dc35261140f7612f1e516a9fa2a977f4e30e04erhyskidd
249a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   tst->sig_mask            = frame->mask;
250a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   tst->tmp_sig_mask        = frame->mask;
251a59627a4e1c3235533534ce5c1dddedc1027195brhyskidd   sigNo                    = frame->sigNo_private;
252f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
253f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   if (VG_(clo_trace_signals))
254f76d27a697a7b0bf3b84490baf60623fc96a23afnjn      VG_(message)(Vg_DebugMsg,
25597f1d337555234c20f3f1d0dd0b22b2a7d571616florian                   "sigframe_destroy (thread %u): "
256341038321790743b2ecf4ce9a410fc14fb0bb719sewardj                   "valid magic; next EIP=%#x\n",
257f76d27a697a7b0bf3b84490baf60623fc96a23afnjn                   tid, tst->arch.vex.guest_EIP);
258f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
259f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   VG_TRACK( die_mem_stack_signal,
260ea2d6fd6aaf98d261df9fdf580542ebf01b7fba4njn             (Addr)frame - VG_STACK_REDZONE_SZB,
261ea2d6fd6aaf98d261df9fdf580542ebf01b7fba4njn             sizeof(struct hacky_sigframe) );
262f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
263f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   /* tell the tools */
264f76d27a697a7b0bf3b84490baf60623fc96a23afnjn   VG_TRACK( post_deliver_signal, tid, sigNo );
265f76d27a697a7b0bf3b84490baf60623fc96a23afnjn}
266f76d27a697a7b0bf3b84490baf60623fc96a23afnjn
2678b68b64759254d514d98328c496cbd88cde4c9a5njn#endif // defined(VGP_x86_darwin)
2688b68b64759254d514d98328c496cbd88cde4c9a5njn
269f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/*--------------------------------------------------------------------*/
2708b68b64759254d514d98328c496cbd88cde4c9a5njn/*--- end                                                          ---*/
271f76d27a697a7b0bf3b84490baf60623fc96a23afnjn/*--------------------------------------------------------------------*/
272