1 
2 /*--------------------------------------------------------------------*/
3 /*--- Create/destroy signal delivery frames.                       ---*/
4 /*---                                     sigframe-amd64-dragonfly.c ---*/
5 /*--------------------------------------------------------------------*/
6 
7 /*
8    This file is part of Valgrind, a dynamic binary instrumentation
9    framework.
10 
11    Copyright (C) 2000-2009 Nicholas Nethercote
12       njn@valgrind.org
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_amd64_dragonfly)
33 
34 #include "pub_core_basics.h"
35 #include "pub_core_vki.h"
36 #include "pub_core_libcsetjmp.h"    // to keep _threadstate.h happy
37 #include "pub_core_threadstate.h"
38 #include "pub_core_aspacemgr.h"
39 #include "pub_core_libcbase.h"
40 #include "pub_core_libcassert.h"
41 #include "pub_core_libcprint.h"
42 #include "pub_core_machine.h"
43 #include "pub_core_options.h"
44 #include "pub_core_signals.h"
45 #include "pub_core_tooliface.h"
46 #include "pub_core_trampoline.h"
47 #include "pub_core_sigframe.h"   /* self */
48 
49 /* This module creates and removes signal frames for signal deliveries
50    on amd64-dragonfly.
51 */
52 
53 
54 /*------------------------------------------------------------*/
55 /*--- Signal frame layouts                                 ---*/
56 /*------------------------------------------------------------*/
57 
58 // A structure in which to save the application's registers
59 // during the execution of signal handlers.
60 
61 // In theory, so long as we get the arguments to the handler function
62 // right, it doesn't matter what the exact layout of the rest of the
63 // frame is.  Unfortunately, things like gcc's exception unwinding
64 // make assumptions about the locations of various parts of the frame,
65 // so we need to duplicate it exactly.
66 
67 /* Valgrind-specific parts of the signal frame */
68 struct vg_sigframe
69 {
70    /* Sanity check word. */
71    UInt magicPI;
72 
73    UInt handlerflags;	/* flags for signal handler */
74 
75 
76    /* Safely-saved version of sigNo, as described above. */
77    Int  sigNo_private;
78 
79    /* XXX This is wrong.  Surely we should store the shadow values
80       into the shadow memory behind the actual values? */
81    VexGuestAMD64State vex_shadow1;
82    VexGuestAMD64State vex_shadow2;
83 
84    /* HACK ALERT */
85    VexGuestAMD64State vex;
86    /* end HACK ALERT */
87 
88    /* saved signal mask to be restored when handler returns */
89    vki_sigset_t	mask;
90 
91    /* Sanity check word.  Is the highest-addressed word; do not
92       move!*/
93    UInt magicE;
94 };
95 
96 struct sigframe
97 {
98    /* Sig handler's return address */
99    Addr retaddr;
100 
101    Int  sigNo;
102    Addr psigInfo;      /* code or pointer to sigContext */
103    Addr puContext;     /* points to uContext */
104    Addr addr;          /* "secret" 4th argument */
105    Addr phandler;      /* "action" or "handler" */
106 
107    /* pointed to by puContext */
108    struct vki_ucontext uContext;
109 
110    vki_siginfo_t sigInfo;
111 
112    struct _vki_fpstate fpstate;
113 
114    struct vg_sigframe vg;
115 };
116 
117 /*------------------------------------------------------------*/
118 /*--- Creating signal frames                               ---*/
119 /*------------------------------------------------------------*/
120 
121 /* Create a plausible-looking sigcontext from the thread's
122    Vex guest state.
123 */
124 static
synth_ucontext(ThreadId tid,const vki_siginfo_t * si,UWord trapno,UWord err,const vki_sigset_t * set,struct vki_ucontext * uc,struct _vki_fpstate * fpstate)125 void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,
126                     UWord trapno, UWord err, const vki_sigset_t *set,
127                     struct vki_ucontext *uc, struct _vki_fpstate *fpstate)
128 {
129    ThreadState *tst = VG_(get_ThreadState)(tid);
130    struct vki_mcontext *sc = &uc->uc_mcontext;
131 
132    VG_(memset)(uc, 0, sizeof(*uc));
133 
134    uc->uc_flags = 0;
135    uc->uc_link = 0;
136    uc->uc_sigmask = *set;
137    uc->uc_stack = tst->altstack;
138    VG_(memcpy)(&sc->fpstate, fpstate, sizeof(*fpstate));
139 
140 #  define SC2(reg,REG)  sc->reg = tst->arch.vex.guest_##REG
141    SC2(r8,R8);
142    SC2(r9,R9);
143    SC2(r10,R10);
144    SC2(r11,R11);
145    SC2(r12,R12);
146    SC2(r13,R13);
147    SC2(r14,R14);
148    SC2(r15,R15);
149    SC2(rdi,RDI);
150    SC2(rsi,RSI);
151    SC2(rbp,RBP);
152    SC2(rbx,RBX);
153    SC2(rdx,RDX);
154    SC2(rax,RAX);
155    SC2(rcx,RCX);
156    SC2(rsp,RSP);
157 /*
158    SC2(cs,CS);
159    SC2(gs,SS);
160    XXX
161 */
162    SC2(rip,RIP);
163    sc->addr = (UWord)si->si_addr;
164    sc->err = err;
165    sc->fpformat = VKI_FPFMT_NODEV;
166    sc->len = sizeof(*sc);
167    sc->ownedfp = VKI_FPOWNED_NONE;
168    sc->rflags = LibVEX_GuestAMD64_get_rflags(&tst->arch.vex);
169    sc->trapno = trapno;
170 #  undef SC2
171 }
172 
173 
174 /* Extend the stack segment downwards if needed so as to ensure the
175    new signal frames are mapped to something.  Return a Bool
176    indicating whether or not the operation was successful.
177 */
extend(ThreadState * tst,Addr addr,SizeT size)178 static Bool extend ( ThreadState *tst, Addr addr, SizeT size )
179 {
180    ThreadId        tid = tst->tid;
181    NSegment const* stackseg = NULL;
182 
183    if (VG_(extend_stack)(tid, addr)) {
184       stackseg = VG_(am_find_nsegment)(addr);
185       if (0 && stackseg)
186 	 VG_(printf)("frame=%#lx seg=%#lx-%#lx\n",
187 		     addr, stackseg->start, stackseg->end);
188    }
189 
190    if (stackseg == NULL || !stackseg->hasR || !stackseg->hasW) {
191       VG_(message)(
192          Vg_UserMsg,
193          "Can't extend stack to %#lx during signal delivery for thread %d:\n",
194          addr, tid);
195       if (stackseg == NULL)
196          VG_(message)(Vg_UserMsg, "  no stack segment\n");
197       else
198          VG_(message)(Vg_UserMsg, "  too small or bad protection modes\n");
199 
200       /* set SIGSEGV to default handler */
201       VG_(set_default_handler)(VKI_SIGSEGV);
202       VG_(synth_fault_mapping)(tid, addr);
203 
204       /* The whole process should be about to die, since the default
205 	 action of SIGSEGV to kill the whole process. */
206       return False;
207    }
208 
209    /* For tracking memory events, indicate the entire frame has been
210       allocated. */
211    VG_TRACK( new_mem_stack_signal, addr - VG_STACK_REDZONE_SZB,
212              size + VG_STACK_REDZONE_SZB, tid );
213 
214    return True;
215 }
216 
217 
218 /* Build the Valgrind-specific part of a signal frame. */
219 
build_vg_sigframe(struct vg_sigframe * frame,ThreadState * tst,const vki_sigset_t * mask,UInt flags,Int sigNo)220 static void build_vg_sigframe(struct vg_sigframe *frame,
221 			      ThreadState *tst,
222 			      const vki_sigset_t *mask,
223 			      UInt flags,
224 			      Int sigNo)
225 {
226    frame->sigNo_private = sigNo;
227    frame->magicPI       = 0x31415927;
228    frame->vex_shadow1   = tst->arch.vex_shadow1;
229    frame->vex_shadow2   = tst->arch.vex_shadow2;
230    /* HACK ALERT */
231    frame->vex           = tst->arch.vex;
232    /* end HACK ALERT */
233    frame->mask          = tst->sig_mask;
234    frame->handlerflags  = flags;
235    frame->magicE        = 0x27182818;
236 }
237 
build_sigframe(ThreadState * tst,Addr rsp_top_of_frame,const vki_siginfo_t * siginfo,const struct vki_ucontext * siguc,void * handler,UInt flags,const vki_sigset_t * mask,void * restorer)238 static Addr build_sigframe(ThreadState *tst,
239                               Addr rsp_top_of_frame,
240                               const vki_siginfo_t *siginfo,
241                               const struct vki_ucontext *siguc,
242                               void *handler, UInt flags,
243                               const vki_sigset_t *mask,
244                               void *restorer)
245 {
246    struct sigframe *frame;
247    Addr rsp = rsp_top_of_frame;
248    Int  sigNo = siginfo->si_signo;
249    UWord trapno;
250    UWord err;
251 
252    rsp -= sizeof(*frame);
253    rsp = VG_ROUNDDN(rsp, 16) - 8;
254    frame = (struct sigframe *)rsp;
255 
256    if (!extend(tst, rsp, sizeof(*frame)))
257       return rsp_top_of_frame;
258 
259    /* retaddr, siginfo, uContext fields are to be written */
260    VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame",
261              rsp, offsetof(struct sigframe, vg) );
262 
263    frame->sigNo = sigNo;
264    frame->retaddr = (Addr)&VG_(amd64_dragonfly_SUBST_FOR_sigreturn);
265    if ((flags & VKI_SA_SIGINFO) == 0)
266       frame->psigInfo = (Addr)siginfo->si_code;
267    else
268       frame->psigInfo = (Addr)&frame->sigInfo;
269    VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
270 
271    if (siguc != NULL) {
272       trapno = siguc->uc_mcontext.trapno;
273       err = siguc->uc_mcontext.err;
274    } else {
275       trapno = 0;
276       err = 0;
277    }
278 
279    synth_ucontext(tst->tid, siginfo, trapno, err, mask,
280                   &frame->uContext, &frame->fpstate);
281 
282    if (sigNo == VKI_SIGILL && siginfo->si_code > 0)
283       frame->sigInfo.si_addr = (void*)tst->arch.vex.guest_RIP;
284 
285    VG_TRACK( post_mem_write,  Vg_CoreSignal, tst->tid,
286              rsp, offsetof(struct sigframe, vg) );
287 
288    build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
289 
290    return rsp;
291 }
292 
293 
VG_(sigframe_create)294 void VG_(sigframe_create)( ThreadId tid,
295                             Bool on_altstack,
296                             Addr rsp_top_of_frame,
297                             const vki_siginfo_t *siginfo,
298                             const struct vki_ucontext *siguc,
299                             void *handler,
300                             UInt flags,
301                             const vki_sigset_t *mask,
302                             void *restorer )
303 {
304    Addr rsp;
305    struct sigframe *frame;
306    ThreadState* tst = VG_(get_ThreadState)(tid);
307 
308    rsp = build_sigframe(tst, rsp_top_of_frame, siginfo, siguc, handler,
309       flags, mask, restorer);
310    frame = (struct sigframe *)rsp;
311 
312    /* Set the thread so it will next run the handler. */
313    /* tst->m_rsp  = rsp;  also notify the tool we've updated RSP */
314    VG_(set_SP)(tid, rsp);
315    VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr));
316 
317    //VG_(printf)("handler = %p\n", handler);
318    tst->arch.vex.guest_RIP = (Addr) handler;
319    tst->arch.vex.guest_RDI = (ULong) siginfo->si_signo;
320    tst->arch.vex.guest_RSI = (Addr) &frame->sigInfo;
321    tst->arch.vex.guest_RDX = (Addr) &frame->uContext;
322    /* This thread needs to be marked runnable, but we leave that the
323       caller to do. */
324 }
325 
326 
327 /*------------------------------------------------------------*/
328 /*--- Destroying signal frames                             ---*/
329 /*------------------------------------------------------------*/
330 
331 /* Return False and don't do anything, just set the client to take a
332    segfault, if it looks like the frame is corrupted. */
333 static
restore_vg_sigframe(ThreadState * tst,struct vg_sigframe * frame,Int * sigNo)334 Bool restore_vg_sigframe ( ThreadState *tst,
335                            struct vg_sigframe *frame, Int *sigNo )
336 {
337    if (frame->magicPI != 0x31415927 ||
338        frame->magicE  != 0x27182818) {
339       VG_(message)(Vg_UserMsg, "Thread %d return signal frame "
340                                "corrupted.  Killing process.\n",
341 		   tst->tid);
342       VG_(set_default_handler)(VKI_SIGSEGV);
343       VG_(synth_fault)(tst->tid);
344       *sigNo = VKI_SIGSEGV;
345       return False;
346    }
347    tst->sig_mask         = frame->mask;
348    tst->tmp_sig_mask     = frame->mask;
349    tst->arch.vex_shadow1 = frame->vex_shadow1;
350    tst->arch.vex_shadow2 = frame->vex_shadow2;
351    /* HACK ALERT */
352    tst->arch.vex         = frame->vex;
353    /* end HACK ALERT */
354    *sigNo                = frame->sigNo_private;
355    return True;
356 }
357 
358 static
restore_sigcontext(ThreadState * tst,struct vki_mcontext * sc,struct _vki_fpstate * fpstate)359 void restore_sigcontext( ThreadState *tst,
360                          struct vki_mcontext *sc,
361                          struct _vki_fpstate *fpstate )
362 {
363    tst->arch.vex.guest_RAX     = sc->rax;
364    tst->arch.vex.guest_RCX     = sc->rcx;
365    tst->arch.vex.guest_RDX     = sc->rdx;
366    tst->arch.vex.guest_RBX     = sc->rbx;
367    tst->arch.vex.guest_RBP     = sc->rbp;
368    tst->arch.vex.guest_RSP     = sc->rsp;
369    tst->arch.vex.guest_RSI     = sc->rsi;
370    tst->arch.vex.guest_RDI     = sc->rdi;
371    tst->arch.vex.guest_R8      = sc->r8;
372    tst->arch.vex.guest_R9      = sc->r9;
373    tst->arch.vex.guest_R10     = sc->r10;
374    tst->arch.vex.guest_R11     = sc->r11;
375    tst->arch.vex.guest_R12     = sc->r12;
376    tst->arch.vex.guest_R13     = sc->r13;
377    tst->arch.vex.guest_R14     = sc->r14;
378    tst->arch.vex.guest_R15     = sc->r15;
379 /*
380    XXX:
381    tst->arch.vex.guest_rflags  = sc->rflags;
382 */
383    tst->arch.vex.guest_RIP     = sc->rip;
384 /*
385    XXX
386    tst->arch.vex.guest_CS      = sc->cs;
387    tst->arch.vex.guest_SS      = sc->ss;
388 */
389    VG_(memcpy)(fpstate, &sc->fpstate, sizeof(*fpstate));
390 }
391 
392 static
restore_sigframe(ThreadState * tst,struct sigframe * frame,Int * sigNo)393 SizeT restore_sigframe ( ThreadState *tst,
394    struct sigframe *frame, Int *sigNo )
395 {
396    if (restore_vg_sigframe(tst, &frame->vg, sigNo))
397       restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate);
398 
399    return sizeof(*frame);
400 }
401 
VG_(sigframe_destroy)402 void VG_(sigframe_destroy)( ThreadId tid )
403 {
404    Addr          rsp;
405    ThreadState*  tst;
406    SizeT	 size;
407    Int		 sigNo;
408 
409    tst = VG_(get_ThreadState)(tid);
410 
411    /* Correctly reestablish the frame base address. */
412    rsp   = tst->arch.vex.guest_RSP;
413 
414    size = restore_sigframe(tst, (struct sigframe *)rsp, &sigNo);
415 
416    VG_TRACK( die_mem_stack_signal, rsp - VG_STACK_REDZONE_SZB,
417              size + VG_STACK_REDZONE_SZB );
418 
419    if (VG_(clo_trace_signals))
420       VG_(message)(
421          Vg_DebugMsg,
422          "VG_(signal_return) (thread %d): valid magic; RIP=%#llx\n",
423          tid, tst->arch.vex.guest_RIP);
424 
425    /* tell the tools */
426    VG_TRACK( post_deliver_signal, tid, sigNo );
427 }
428 
429 #endif // defined(VGP_amd64_dragonfly)
430 
431 /*--------------------------------------------------------------------*/
432 /*--- end                                                          ---*/
433 /*--------------------------------------------------------------------*/
434