1 2/*--------------------------------------------------------------------*/ 3/*--- Create/destroy signal delivery frames. ---*/ 4/*--- sigframe-arm64-linux.c ---*/ 5/*--------------------------------------------------------------------*/ 6 7/* 8 This file is part of Valgrind, a dynamic binary instrumentation 9 framework. 10 11 Copyright (C) 2013-2013 OpenWorks 12 info@open-works.net 13 14 This program is free software; you can redistribute it and/or 15 modify it under the terms of the GNU General Public License as 16 published by the Free Software Foundation; either version 2 of the 17 License, or (at your option) any later version. 18 19 This program is distributed in the hope that it will be useful, but 20 WITHOUT ANY WARRANTY; without even the implied warranty of 21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 General Public License for more details. 23 24 You should have received a copy of the GNU General Public License 25 along with this program; if not, write to the Free Software 26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27 02111-1307, USA. 28 29 The GNU General Public License is contained in the file COPYING. 30*/ 31 32#if defined(VGP_arm64_linux) 33 34#include "pub_core_basics.h" 35#include "pub_core_vki.h" 36//ZZ #include "pub_core_vkiscnums.h" 37#include "pub_core_libcsetjmp.h" // to keep _threadstate.h happy 38#include "pub_core_threadstate.h" 39#include "pub_core_aspacemgr.h" 40#include "pub_core_libcbase.h" 41#include "pub_core_libcassert.h" 42#include "pub_core_libcprint.h" 43#include "pub_core_machine.h" 44#include "pub_core_options.h" 45#include "pub_core_sigframe.h" 46#include "pub_core_signals.h" 47#include "pub_core_tooliface.h" 48#include "pub_core_trampoline.h" 49//ZZ #include "pub_core_transtab.h" // VG_(discard_translations) 50 51 52/* This uses the hack of dumping the vex guest state along with both 53 shadows in the frame, and restoring it afterwards from there, 54 rather than pulling it out of the ucontext. That means that signal 55 handlers which modify the ucontext and then return, expecting their 56 modifications to take effect, will have those modifications 57 ignored. This could be fixed properly with an hour or so more 58 effort. */ 59 60/* This also always does the 'has siginfo' behaviour whether or 61 not it is requested. */ 62 63struct vg_sig_private { 64 UInt magicPI; 65 UInt sigNo_private; 66 VexGuestARM64State vex; 67 VexGuestARM64State vex_shadow1; 68 VexGuestARM64State vex_shadow2; 69}; 70 71struct sigframe { 72 struct vki_ucontext uc; 73 unsigned long retcode[2]; 74 struct vg_sig_private vp; 75}; 76 77struct rt_sigframe { 78 vki_siginfo_t info; 79 struct sigframe sig; 80}; 81 82static Bool extend ( ThreadState *tst, Addr addr, SizeT size ) 83{ 84 ThreadId tid = tst->tid; 85 NSegment const* stackseg = NULL; 86 87 if (VG_(extend_stack)(addr, tst->client_stack_szB)) { 88 stackseg = VG_(am_find_nsegment)(addr); 89 if (0 && stackseg) 90 VG_(printf)("frame=%#lx seg=%#lx-%#lx\n", 91 addr, stackseg->start, stackseg->end); 92 } 93 94 if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) { 95 VG_(message)( 96 Vg_UserMsg, 97 "Can't extend stack to %#lx during signal delivery for thread %d:", 98 addr, tid); 99 if (stackseg == NULL) 100 VG_(message)(Vg_UserMsg, " no stack segment"); 101 else 102 VG_(message)(Vg_UserMsg, " too small or bad protection modes"); 103 104 /* set SIGSEGV to default handler */ 105 VG_(set_default_handler)(VKI_SIGSEGV); 106 VG_(synth_fault_mapping)(tid, addr); 107 108 /* The whole process should be about to die, since the default 109 action of SIGSEGV to kill the whole process. */ 110 return False; 111 } 112 113 /* For tracking memory events, indicate the entire frame has been 114 allocated. */ 115 VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB, 116 size + VG_STACK_REDZONE_SZB, tid ); 117 118 return True; 119} 120 121static void synth_ucontext( ThreadId tid, const vki_siginfo_t *si, 122 UWord trapno, UWord err, const vki_sigset_t *set, 123 struct vki_ucontext *uc) 124{ 125 126 ThreadState *tst = VG_(get_ThreadState)(tid); 127 struct vki_sigcontext *sc = &uc->uc_mcontext; 128 129 VG_(memset)(uc, 0, sizeof(*uc)); 130 131 uc->uc_flags = 0; 132 uc->uc_link = 0; 133 uc->uc_sigmask = *set; 134 uc->uc_stack = tst->altstack; 135 136# define SC2(reg) sc->regs[reg] = tst->arch.vex.guest_X##reg 137 SC2(0); SC2(1); SC2(2); SC2(3); 138 SC2(4); SC2(5); SC2(6); SC2(7); 139 SC2(8); SC2(9); SC2(10); SC2(11); 140 SC2(12); SC2(13); SC2(14); SC2(15); 141 SC2(16); SC2(17); SC2(18); SC2(19); 142 SC2(20); SC2(21); SC2(22); SC2(23); 143 SC2(24); SC2(25); SC2(26); SC2(27); 144 SC2(28); SC2(29); SC2(30); 145# undef SC2 146 sc->sp = tst->arch.vex.guest_XSP; 147 sc->pc = tst->arch.vex.guest_PC; 148 sc->pstate = 0; /* slack .. could do better */ 149 150 //sc->trap_no = trapno; 151 //sc->error_code = err; 152 sc->fault_address = (ULong)si->_sifields._sigfault._addr; 153} 154 155 156static void build_sigframe(ThreadState *tst, 157 struct sigframe *frame, 158 const vki_siginfo_t *siginfo, 159 const struct vki_ucontext *siguc, 160 void *handler, UInt flags, 161 const vki_sigset_t *mask, 162 void *restorer) 163{ 164 UWord trapno; 165 UWord err; 166 Int sigNo = siginfo->si_signo; 167 struct vg_sig_private *priv = &frame->vp; 168 169 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame", 170 (Addr)frame, offsetof(struct sigframe, vp)); 171 172 if (siguc) { 173 trapno = 0; //siguc->uc_mcontext.trap_no; 174 err = 0; //siguc->uc_mcontext.error_code; 175 } else { 176 trapno = 0; 177 err = 0; 178 } 179 180 synth_ucontext(tst->tid, siginfo, trapno, err, mask, &frame->uc); 181 182 VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, 183 (Addr)frame, offsetof(struct sigframe, vp)); 184 185 priv->magicPI = 0x31415927; 186 priv->sigNo_private = sigNo; 187 priv->vex = tst->arch.vex; 188 priv->vex_shadow1 = tst->arch.vex_shadow1; 189 priv->vex_shadow2 = tst->arch.vex_shadow2; 190} 191 192 193/* EXPORTED */ 194void VG_(sigframe_create)( ThreadId tid, 195 Addr sp_top_of_frame, 196 const vki_siginfo_t *siginfo, 197 const struct vki_ucontext *siguc, 198 void *handler, 199 UInt flags, 200 const vki_sigset_t *mask, 201 void *restorer ) 202{ 203 ThreadState *tst; 204 Addr sp = sp_top_of_frame; 205 Int sigNo = siginfo->si_signo; 206 UInt size; 207 208 tst = VG_(get_ThreadState)(tid); 209 210 size = sizeof(struct rt_sigframe); 211 212 sp -= size; 213 sp = VG_ROUNDDN(sp, 16); 214 215 if (!extend(tst, sp, size)) 216 return; // Give up. No idea if this is correct 217 218 struct rt_sigframe *rsf = (struct rt_sigframe *)sp; 219 220 /* Track our writes to siginfo */ 221 VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, /* VVVVV */ 222 "signal handler siginfo", (Addr)rsf, 223 offsetof(struct rt_sigframe, sig)); 224 225 VG_(memcpy)(&rsf->info, siginfo, sizeof(vki_siginfo_t)); 226 227 if (sigNo == VKI_SIGILL && siginfo->si_code > 0) { 228 rsf->info._sifields._sigfault._addr 229 = (Addr*)(tst)->arch.vex.guest_PC; 230 } 231 VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, /* ^^^^^ */ 232 (Addr)rsf, offsetof(struct rt_sigframe, sig)); 233 234 build_sigframe(tst, &rsf->sig, siginfo, siguc, 235 handler, flags, mask, restorer); 236 tst->arch.vex.guest_X1 = (Addr)&rsf->info; 237 tst->arch.vex.guest_X2 = (Addr)&rsf->sig.uc; 238 239 VG_(set_SP)(tid, sp); 240 VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, 241 sizeof(Addr)); 242 tst->arch.vex.guest_X0 = sigNo; 243 244 if (flags & VKI_SA_RESTORER) 245 tst->arch.vex.guest_X30 = (Addr)restorer; 246 else 247 tst->arch.vex.guest_X30 248 = (Addr)&VG_(arm64_linux_SUBST_FOR_rt_sigreturn); 249 250 tst->arch.vex.guest_PC = (Addr)handler; 251} 252 253 254/*------------------------------------------------------------*/ 255/*--- Destroying signal frames ---*/ 256/*------------------------------------------------------------*/ 257 258/* EXPORTED */ 259void VG_(sigframe_destroy)( ThreadId tid, Bool isRT ) 260{ 261 ThreadState *tst; 262 struct vg_sig_private *priv; 263 Addr sp; 264 UInt frame_size; 265//ZZ struct vki_sigcontext *mc; 266 Int sigNo; 267 Bool has_siginfo = isRT; 268 269 vg_assert(VG_(is_valid_tid)(tid)); 270 tst = VG_(get_ThreadState)(tid); 271 sp = tst->arch.vex.guest_XSP; 272 273//ZZ if (has_siginfo) { 274 struct rt_sigframe *frame = (struct rt_sigframe *)sp; 275 frame_size = sizeof(*frame); 276 //mc = &frame->sig.uc.uc_mcontext; 277 priv = &frame->sig.vp; 278 vg_assert(priv->magicPI == 0x31415927); 279 tst->sig_mask = frame->sig.uc.uc_sigmask; 280//ZZ } else { 281//ZZ struct sigframe *frame = (struct sigframe *)sp; 282//ZZ frame_size = sizeof(*frame); 283//ZZ mc = &frame->uc.uc_mcontext; 284//ZZ priv = &frame->vp; 285//ZZ vg_assert(priv->magicPI == 0x31415927); 286//ZZ tst->sig_mask = frame->uc.uc_sigmask; 287//ZZ //VG_(printf)("Setting signmask to %08x%08x\n", 288//ZZ // tst->sig_mask[0],tst->sig_mask[1]); 289//ZZ } 290 tst->tmp_sig_mask = tst->sig_mask; 291 292 sigNo = priv->sigNo_private; 293 294//ZZ //XXX: restore regs 295//ZZ # define REST(reg,REG) tst->arch.vex.guest_##REG = mc->arm_##reg; 296//ZZ REST(r0,R0); 297//ZZ REST(r1,R1); 298//ZZ REST(r2,R2); 299//ZZ REST(r3,R3); 300//ZZ REST(r4,R4); 301//ZZ REST(r5,R5); 302//ZZ REST(r6,R6); 303//ZZ REST(r7,R7); 304//ZZ REST(r8,R8); 305//ZZ REST(r9,R9); 306//ZZ REST(r10,R10); 307//ZZ REST(fp,R11); 308//ZZ REST(ip,R12); 309//ZZ REST(sp,R13); 310//ZZ REST(lr,R14); 311//ZZ REST(pc,R15T); 312//ZZ # undef REST 313 314 /* Uh, the next line makes all the REST() above pointless. */ 315 tst->arch.vex = priv->vex; 316 317 tst->arch.vex_shadow1 = priv->vex_shadow1; 318 tst->arch.vex_shadow2 = priv->vex_shadow2; 319 320 VG_TRACK( die_mem_stack_signal, sp - VG_STACK_REDZONE_SZB, 321 frame_size + VG_STACK_REDZONE_SZB ); 322 323 if (VG_(clo_trace_signals)) 324 VG_(message)(Vg_DebugMsg, 325 "vg_pop_signal_frame (thread %d): " 326 "isRT=%d valid magic; PC=%#llx\n", 327 tid, has_siginfo, tst->arch.vex.guest_PC); 328 329 /* tell the tools */ 330 VG_TRACK( post_deliver_signal, tid, sigNo ); 331} 332 333#endif // defined(VGP_arm_linux) 334 335/*--------------------------------------------------------------------*/ 336/*--- end sigframe-arm64-linux.c ---*/ 337/*--------------------------------------------------------------------*/ 338