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