static Addr build_sigframe(ThreadState *tst, Addr sp_top_of_frame, const vki_siginfo_t *siginfo, const struct vki_ucontext *siguc, UInt flags, const vki_sigset_t *mask, void *restorer) { struct sigframe *frame; Addr sp = sp_top_of_frame; vg_assert((flags & VKI_SA_SIGINFO) == 0); vg_assert((sizeof(*frame) & 7) == 0); vg_assert((sp & 7) == 0); sp -= sizeof(*frame); frame = (struct sigframe *)sp; if (! ML_(sf_maybe_extend_stack)(tst, sp, sizeof(*frame), flags)) return sp_top_of_frame; /* retcode, sigNo, sc, sregs fields are to be written */ VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame", sp, offsetof(struct sigframe, vg) ); save_sigregs(tst, &frame->sregs); frame->sigNo = siginfo->si_signo; frame->sc.sregs = &frame->sregs; VG_(memcpy)(frame->sc.oldmask, mask->sig, sizeof(frame->sc.oldmask)); if (flags & VKI_SA_RESTORER) { SET_SIGNAL_GPR(tst, 14, restorer); } else { frame->retcode[0] = 0x0a; frame->retcode[1] = __NR_sigreturn; /* This normally should be &frame->recode. but since there might be problems with non-exec stack and we must discard the translation for the on-stack sigreturn we just use the trampoline like x86,ppc. We still fill in the retcode, lets just hope that nobody actually jumps here */ SET_SIGNAL_GPR(tst, 14, (Addr)&VG_(s390x_linux_SUBST_FOR_sigreturn)); } SET_SIGNAL_GPR(tst, 2, siginfo->si_signo); SET_SIGNAL_GPR(tst, 3, &frame->sc); /* fixs390: we dont fill in trapno and prot_addr in r4 and r5*/ /* Set up backchain. */ *((Addr *) sp) = sp_top_of_frame; VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, sp, offsetof(struct sigframe, vg) ); build_vg_sigframe(&frame->vg, tst, flags, siginfo->si_signo); return sp; }
static Addr build_sigframe(ThreadState *tst, Addr esp_top_of_frame, const vki_siginfo_t *siginfo, const struct vki_ucontext *siguc, UInt flags, const vki_sigset_t *mask, void *restorer) { struct sigframe *frame; Addr esp = esp_top_of_frame; Int sigNo = siginfo->si_signo; UWord trapno; UWord err; struct vki_ucontext uc; vg_assert((flags & VKI_SA_SIGINFO) == 0); esp -= sizeof(*frame); esp = VG_ROUNDDN(esp, 16); frame = (struct sigframe *)esp; if (!extend(tst, esp, sizeof(*frame))) return esp_top_of_frame; /* retaddr, sigNo, siguContext fields are to be written */ VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame", esp, offsetof(struct sigframe, vg) ); frame->sigNo = sigNo; if (flags & VKI_SA_RESTORER) frame->retaddr = (Addr)restorer; else frame->retaddr = (Addr)&VG_(x86_linux_SUBST_FOR_sigreturn); if (siguc) { trapno = siguc->uc_mcontext.trapno; err = siguc->uc_mcontext.err; } else { trapno = 0; err = 0; } synth_ucontext(tst->tid, siginfo, trapno, err, mask, &uc, &frame->fpstate); VG_(memcpy)(&frame->sigContext, &uc.uc_mcontext, sizeof(struct vki_sigcontext)); frame->sigContext.oldmask = mask->sig[0]; VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, esp, offsetof(struct sigframe, vg) ); build_vg_sigframe(&frame->vg, tst, flags, sigNo); return esp; }
static Addr build_rt_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) { struct rt_sigframe *frame; Addr rsp = rsp_top_of_frame; Int sigNo = siginfo->si_signo; UWord trapno; UWord err; rsp -= sizeof(*frame); rsp = VG_ROUNDDN(rsp, 16) - 8; frame = (struct rt_sigframe *)rsp; if (!extend(tst, rsp, sizeof(*frame))) return rsp_top_of_frame; /* retaddr, siginfo, uContext fields are to be written */ VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "rt signal handler frame", rsp, offsetof(struct rt_sigframe, vg) ); if (flags & VKI_SA_RESTORER) frame->retaddr = (Addr)restorer; else frame->retaddr = (Addr)&VG_(amd64_linux_SUBST_FOR_rt_sigreturn); if (siguc) { trapno = siguc->uc_mcontext.trapno; err = siguc->uc_mcontext.err; } else { trapno = 0; err = 0; } VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t)); /* SIGILL defines addr to be the faulting address */ if (sigNo == VKI_SIGILL && siginfo->si_code > 0) frame->sigInfo._sifields._sigfault._addr = (void*)tst->arch.vex.guest_RIP; synth_ucontext(tst->tid, siginfo, trapno, err, mask, &frame->uContext, &frame->fpstate); VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, rsp, offsetof(struct rt_sigframe, vg) ); build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo); return rsp; }
static Addr 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) { struct sigframe *frame; Addr rsp = rsp_top_of_frame; Int sigNo = siginfo->si_signo; UWord trapno; UWord err; rsp -= sizeof(*frame); rsp = VG_ROUNDDN(rsp, 16); frame = (struct sigframe *)rsp; if (!extend(tst, rsp, sizeof(*frame))) return rsp_top_of_frame; /* retaddr, siginfo, uContext fields are to be written */ VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame", rsp, offsetof(struct sigframe, vg) ); frame->sigNo = sigNo; frame->retaddr = (Addr)&VG_(amd64_freebsd_SUBST_FOR_sigreturn); if ((flags & VKI_SA_SIGINFO) == 0) frame->psigInfo = (Addr)siginfo->si_code; else frame->psigInfo = (Addr)&frame->sigInfo; VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t)); if (siguc != NULL) { trapno = siguc->uc_mcontext.trapno; err = siguc->uc_mcontext.err; } else { trapno = 0; err = 0; } synth_ucontext(tst->tid, siginfo, trapno, err, mask, &frame->uContext, &frame->fpstate); if (sigNo == VKI_SIGILL && siginfo->si_code > 0) frame->sigInfo.si_addr = (void*)tst->arch.vex.guest_RIP; VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, rsp, offsetof(struct sigframe, vg) ); build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo); return rsp; }
static Addr build_rt_sigframe(ThreadState *tst, Addr esp_top_of_frame, const vki_siginfo_t *siginfo, void *handler, UInt flags, const vki_sigset_t *mask, void *restorer) { struct rt_sigframe *frame; Addr esp = esp_top_of_frame; Int sigNo = siginfo->si_signo; vg_assert((flags & VKI_SA_SIGINFO) != 0); esp -= sizeof(*frame); esp = VG_ROUNDDN(esp, 16); frame = (struct rt_sigframe *)esp; if (!extend(tst, esp, sizeof(*frame))) return esp_top_of_frame; /* retaddr, sigNo, pSiginfo, puContext fields are to be written */ VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "rt signal handler frame", esp, offsetof(struct rt_sigframe, vg) ); frame->sigNo = sigNo; if (flags & VKI_SA_RESTORER) frame->retaddr = (Addr)restorer; else frame->retaddr = VG_(client_trampoline_code)+VG_(tramp_rt_sigreturn_offset); frame->psigInfo = (Addr)&frame->sigInfo; frame->puContext = (Addr)&frame->uContext; VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t)); /* SIGILL defines addr to be the faulting address */ if (sigNo == VKI_SIGILL && siginfo->si_code > 0) frame->sigInfo._sifields._sigfault._addr = (void*)tst->arch.vex.guest_EIP; synth_ucontext(tst->tid, siginfo, mask, &frame->uContext, &frame->fpstate); VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, esp, offsetof(struct rt_sigframe, vg) ); build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo); return esp; }
static Addr build_sigframe(ThreadState *tst, Addr esp_top_of_frame, const vki_siginfo_t *siginfo, void *handler, UInt flags, const vki_sigset_t *mask, void *restorer) { struct sigframe *frame; Addr esp = esp_top_of_frame; Int sigNo = siginfo->si_signo; struct vki_ucontext uc; vg_assert((flags & VKI_SA_SIGINFO) == 0); esp -= sizeof(*frame); esp = VG_ROUNDDN(esp, 16); frame = (struct sigframe *)esp; if (!extend(tst, esp, sizeof(*frame))) return esp_top_of_frame; /* retaddr, sigNo, siguContext fields are to be written */ VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame", esp, offsetof(struct sigframe, vg) ); frame->sigNo = sigNo; if (flags & VKI_SA_RESTORER) frame->retaddr = (Addr)restorer; else frame->retaddr = VG_(client_trampoline_code)+VG_(tramp_sigreturn_offset); synth_ucontext(tst->tid, siginfo, mask, &uc, &frame->fpstate); VG_(memcpy)(&frame->sigContext, &uc.uc_mcontext, sizeof(struct vki_sigcontext)); frame->sigContext.oldmask = mask->sig[0]; VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, esp, offsetof(struct sigframe, vg) ); build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo); return esp; }
static Addr build_rt_sigframe(ThreadState *tst, Addr esp_top_of_frame, const vki_siginfo_t *siginfo, const struct vki_ucontext *siguc, UInt flags, const vki_sigset_t *mask, void *restorer) { struct rt_sigframe *frame; Addr esp = esp_top_of_frame; Int sigNo = siginfo->si_signo; UWord trapno; UWord err; vg_assert((flags & VKI_SA_SIGINFO) != 0); esp -= sizeof(*frame); esp = VG_ROUNDDN(esp, 16); frame = (struct rt_sigframe *)esp; if (!extend(tst, esp, sizeof(*frame))) return esp_top_of_frame; /* retaddr, sigNo, pSiginfo, puContext fields are to be written */ VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "rt signal handler frame", esp, offsetof(struct rt_sigframe, vg) ); frame->sigNo = sigNo; if (flags & VKI_SA_RESTORER) frame->retaddr = (Addr)restorer; else frame->retaddr = (Addr)&VG_(x86_linux_SUBST_FOR_rt_sigreturn); if (siguc) { trapno = siguc->uc_mcontext.trapno; err = siguc->uc_mcontext.err; } else { trapno = 0; err = 0; } frame->psigInfo = (Addr)&frame->sigInfo; frame->puContext = (Addr)&frame->uContext; VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t)); if (sigNo == VKI_SIGILL && siginfo->si_code > 0) frame->sigInfo._sifields._sigfault._addr = (void*)tst->arch.vex.guest_EIP; synth_ucontext(tst->tid, siginfo, trapno, err, mask, &frame->uContext, &frame->fpstate); VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, esp, offsetof(struct rt_sigframe, vg) ); build_vg_sigframe(&frame->vg, tst, flags, sigNo); return esp; }