bits of sigcontext at the moment.
*/
static
-void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,
+void synth_ucontext(ThreadId tid, const vki_siginfo_t *si, Int trapno,
const vki_sigset_t *set,
struct vki_ucontext *uc, struct _vki_fpstate *fpstate)
{
// FIXME: SC2(gs,GS);
// FIXME: SC2(fs,FS);
/* XXX err */
- /* XXX trapno */
+ sc->trapno = trapno;
# undef SC2
sc->cr2 = (UWord)si->_sifields._sigfault._addr;
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;
+ Int trapno;
rsp -= sizeof(*frame);
rsp = VG_ROUNDDN(rsp, 16);
else
frame->retaddr = (Addr)&VG_(amd64_linux_SUBST_FOR_rt_sigreturn);
+ if (siguc)
+ trapno = siguc->uc_mcontext.trapno;
+ else
+ trapno = 0;
+
VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
/* SIGILL defines addr to be the faulting address */
frame->sigInfo._sifields._sigfault._addr
= (void*)tst->arch.vex.guest_RIP;
- synth_ucontext(tst->tid, siginfo, mask, &frame->uContext, &frame->fpstate);
+ synth_ucontext(tst->tid, siginfo, trapno, mask, &frame->uContext, &frame->fpstate);
VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
rsp, offsetof(struct rt_sigframe, vg) );
void VG_(sigframe_create)( ThreadId tid,
Addr rsp_top_of_frame,
const vki_siginfo_t *siginfo,
+ const struct vki_ucontext *siguc,
void *handler,
UInt flags,
const vki_sigset_t *mask,
struct rt_sigframe *frame;
ThreadState* tst = VG_(get_ThreadState)(tid);
- rsp = build_rt_sigframe(tst, rsp_top_of_frame, siginfo,
+ rsp = build_rt_sigframe(tst, rsp_top_of_frame, siginfo, siguc,
handler, flags, mask, restorer);
frame = (struct rt_sigframe *)rsp;
void VG_(sigframe_create) ( ThreadId tid,
Addr sp_top_of_frame,
const vki_siginfo_t *siginfo,
+ const struct vki_ucontext *siguc,
void *handler,
UInt flags,
const vki_sigset_t *mask,
void VG_(sigframe_create)( ThreadId tid,
Addr sp_top_of_frame,
const vki_siginfo_t *siginfo,
+ const struct vki_ucontext *siguc,
void *handler,
UInt flags,
const vki_sigset_t *mask,
void VG_(sigframe_create) ( ThreadId tid,
Addr sp_top_of_frame,
const vki_siginfo_t *siginfo,
+ const struct vki_ucontext *siguc,
void *handler,
UInt flags,
const vki_sigset_t *mask,
void VG_(sigframe_create)( ThreadId tid,
Addr sp_top_of_frame,
const vki_siginfo_t *siginfo,
+ const struct vki_ucontext *siguc,
void *handler,
UInt flags,
const vki_sigset_t *mask,
bits of sigcontext at the moment.
*/
static
-void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,
+void synth_ucontext(ThreadId tid, const vki_siginfo_t *si, Int trapno,
const vki_sigset_t *set,
struct vki_ucontext *uc, struct _vki_fpstate *fpstate)
{
sc->eflags = LibVEX_GuestX86_get_eflags(&tst->arch.vex);
SC2(ss,SS);
/* XXX esp_at_signal */
- /* XXX trapno */
+ sc->trapno = trapno;
/* XXX err */
# undef SC2
static Addr build_sigframe(ThreadState *tst,
Addr esp_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 esp = esp_top_of_frame;
Int sigNo = siginfo->si_signo;
+ Int trapno;
struct vki_ucontext uc;
vg_assert((flags & VKI_SA_SIGINFO) == 0);
else
frame->retaddr = (Addr)&VG_(x86_linux_SUBST_FOR_sigreturn);
- synth_ucontext(tst->tid, siginfo, mask, &uc, &frame->fpstate);
+ if (siguc)
+ trapno = siguc->uc_mcontext.trapno;
+ else
+ trapno = 0;
+
+ synth_ucontext(tst->tid, siginfo, trapno, mask, &uc, &frame->fpstate);
VG_(memcpy)(&frame->sigContext, &uc.uc_mcontext,
sizeof(struct vki_sigcontext));
static Addr build_rt_sigframe(ThreadState *tst,
Addr esp_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 esp = esp_top_of_frame;
Int sigNo = siginfo->si_signo;
+ Int trapno;
vg_assert((flags & VKI_SA_SIGINFO) != 0);
else
frame->retaddr = (Addr)&VG_(x86_linux_SUBST_FOR_rt_sigreturn);
+ if (siguc)
+ trapno = siguc->uc_mcontext.trapno;
+ else
+ trapno = 0;
+
frame->psigInfo = (Addr)&frame->sigInfo;
frame->puContext = (Addr)&frame->uContext;
VG_(memcpy)(&frame->sigInfo, siginfo, sizeof(vki_siginfo_t));
frame->sigInfo._sifields._sigfault._addr
= (void*)tst->arch.vex.guest_EIP;
- synth_ucontext(tst->tid, siginfo, mask, &frame->uContext, &frame->fpstate);
+ synth_ucontext(tst->tid, siginfo, trapno, mask, &frame->uContext, &frame->fpstate);
VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
esp, offsetof(struct rt_sigframe, vg) );
void VG_(sigframe_create)( ThreadId tid,
Addr esp_top_of_frame,
const vki_siginfo_t *siginfo,
+ const struct vki_ucontext *siguc,
void *handler,
UInt flags,
const vki_sigset_t *mask,
ThreadState* tst = VG_(get_ThreadState)(tid);
if (flags & VKI_SA_SIGINFO)
- esp = build_rt_sigframe(tst, esp_top_of_frame, siginfo,
+ esp = build_rt_sigframe(tst, esp_top_of_frame, siginfo, siguc,
handler, flags, mask, restorer);
else
- esp = build_sigframe(tst, esp_top_of_frame,
- siginfo, handler, flags, mask, restorer);
+ esp = build_sigframe(tst, esp_top_of_frame, siginfo, siguc,
+ handler, flags, mask, restorer);
/* Set the thread so it will next run the handler. */
/* tst->m_esp = esp; also notify the tool we've updated ESP */
/* Set up a stack frame (VgSigContext) for the client's signal
handler. */
static
-void push_signal_frame ( ThreadId tid, const vki_siginfo_t *siginfo )
+void push_signal_frame ( ThreadId tid, const vki_siginfo_t *siginfo, const struct vki_ucontext *uc )
{
Addr esp_top_of_frame;
ThreadState* tst;
/* This may fail if the client stack is busted; if that happens,
the whole process will exit rather than simply calling the
signal handler. */
- VG_(sigframe_create) (tid, esp_top_of_frame, siginfo,
+ VG_(sigframe_create) (tid, esp_top_of_frame, siginfo, uc,
scss.scss_per_sig[sigNo].scss_handler,
scss.scss_per_sig[sigNo].scss_flags,
&tst->sig_mask,
This updates the thread state, but it does not set it to be
Runnable.
*/
-static void deliver_signal ( ThreadId tid, const vki_siginfo_t *info )
+static void deliver_signal ( ThreadId tid, const vki_siginfo_t *info, const struct vki_ucontext *uc )
{
Int sigNo = info->si_signo;
SCSS_Per_Signal *handler = &scss.scss_per_sig[sigNo];
*/
vg_assert(VG_(is_valid_tid)(tid));
- push_signal_frame ( tid, info );
+ push_signal_frame ( tid, info, uc );
if (handler->scss_flags & VKI_SA_ONESHOT) {
/* Do the ONESHOT thing. */
if (VG_(sigismember)(&VG_(threads)[tid].sig_mask, VKI_SIGSEGV))
VG_(set_default_handler)(VKI_SIGSEGV);
- deliver_signal(tid, &info);
+ deliver_signal(tid, &info, NULL);
}
// Synthesize a fault where the address is OK, but the page
info.VKI_SIGINFO_si_addr = (void*)addr;
resume_scheduler(tid);
- deliver_signal(tid, &info);
+ deliver_signal(tid, &info, NULL);
}
// Synthesise a SIGTRAP.
void VG_(synth_sigtrap)(ThreadId tid)
{
vki_siginfo_t info;
+ struct vki_ucontext uc;
vg_assert(VG_(threads)[tid].status == VgTs_Runnable);
info.si_signo = VKI_SIGTRAP;
- info.si_code = VKI_TRAP_TRACE; /* jrs: no idea what this should be */
+ info.si_code = VKI_TRAP_BRKPT; /* tjh: only ever called for a brkpt ins */
+#if defined(VGA_x86) || defined(VGA_amd64)
+ uc.uc_mcontext.trapno = 3; /* tjh: this is the x86 trap number
+ for a breakpoint trap... */
+#endif
resume_scheduler(tid);
- deliver_signal(tid, &info);
+ deliver_signal(tid, &info, &uc);
}
/* Make a signal pending for a thread, for later delivery.
/* Set up the thread's state to deliver a signal */
if (!is_sig_ign(info->si_signo))
- deliver_signal(tid, info);
+ deliver_signal(tid, info, uc);
/* longjmp back to the thread's main loop to start executing the
handler. */
/* It's a fatal signal, so we force the default handler. */
VG_(set_default_handler)(sigNo);
- deliver_signal(tid, info);
+ deliver_signal(tid, info, uc);
resume_scheduler(tid);
VG_(exit)(99); /* If we can't resume, then just exit */
}
if (VG_(in_generated_code)) {
/* Can't continue; must longjmp back to the scheduler and thus
enter the sighandler immediately. */
- deliver_signal(tid, info);
+ deliver_signal(tid, info, uc);
resume_scheduler(tid);
}
VG_(message)(Vg_DebugMsg, "Polling found signal %d for tid %d",
sip->si_signo, tid);
if (!is_sig_ign(sip->si_signo))
- deliver_signal(tid, sip);
+ deliver_signal(tid, sip, NULL);
else if (VG_(clo_trace_signals))
VG_(message)(Vg_DebugMsg, " signal %d ignored", sip->si_signo);
void VG_(sigframe_create) ( ThreadId tid,
Addr sp_top_of_frame,
const vki_siginfo_t *siginfo,
+ const struct vki_ucontext *uc,
void *handler,
UInt flags,
const vki_sigset_t *mask,