PERFORCE change 168154 for review
Stanislav Sedov
stas at FreeBSD.org
Fri Sep 4 12:57:59 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=168154
Change 168154 by stas at stas_yandex on 2009/09/04 12:57:35
- Fix signals on x86.
Affected files ...
.. //depot/projects/valgrind/coregrind/m_sigframe/sigframe-x86-freebsd.c#6 edit
.. //depot/projects/valgrind/coregrind/m_trampoline.S#8 edit
Differences ...
==== //depot/projects/valgrind/coregrind/m_sigframe/sigframe-x86-freebsd.c#6 (text+ko) ====
@@ -46,20 +46,8 @@
#include "pub_core_sigframe.h" /* self */
-#warning Needs love!
-
-
/* This module creates and removes signal frames for signal deliveries
on x86-freebsd.
-
- FIXME: sigcontexting is basically broken for the moment. When
- delivering a signal, the integer registers and %eflags are
- correctly written into the sigcontext, however the FP and SSE state
- is not. When returning from a signal, only the integer registers
- are restored from the sigcontext; the rest of the CPU state is
- restored to what it was before the signal.
-
- This should be fixed.
*/
@@ -109,9 +97,18 @@
{
/* Sig handler's return address */
Addr retaddr;
+
Int sigNo;
+ Addr psigInfo; /* code or pointer to sigContext */
+ Addr puContext; /* points to uContext */
+ Addr addr; /* "secret" 4th argument */
+ Addr phandler; /* "action" or "handler" */
+
+ /* pointed to by puContext */
+ struct vki_ucontext uContext;
- struct vki_sigcontext sigContext;
+ vki_siginfo_t sigInfo;
+
struct _vki_fpstate fpstate;
struct vg_sigframe vg;
@@ -123,8 +120,7 @@
/*------------------------------------------------------------*/
/* Create a plausible-looking sigcontext from the thread's
- Vex guest state. NOTE: does not fill in the FP or SSE
- bits of sigcontext at the moment.
+ Vex guest state.
*/
static
void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,
@@ -142,8 +138,6 @@
uc->uc_stack = tst->altstack;
VG_(memcpy)(&sc->fpstate, fpstate, sizeof(*fpstate));
- // FIXME: save_i387(&tst->arch, fpstate);
-
# define SC2(reg,REG) sc->reg = tst->arch.vex.guest_##REG
SC2(gs,GS);
SC2(fs,FS);
@@ -163,9 +157,12 @@
SC2(cs,CS);
sc->eflags = LibVEX_GuestX86_get_eflags(&tst->arch.vex);
SC2(ss,SS);
- /* XXX esp_at_signal */
sc->trapno = trapno;
sc->err = err;
+// sc->addr = (UWord)si->si_addr;
+ sc->fpformat = VKI_FPFMT_NODEV;
+ sc->len = sizeof(*sc);
+ sc->ownedfp = VKI_FPOWNED_NONE;
# undef SC2
// sc->cr2 = (UInt)si->_sifields._sigfault._addr;
@@ -220,6 +217,7 @@
static void build_vg_sigframe(struct vg_sigframe *frame,
ThreadState *tst,
+ const vki_sigset_t *mask,
UInt flags,
Int sigNo)
{
@@ -235,21 +233,19 @@
frame->magicE = 0x27182818;
}
-
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)
+ 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 sigNo = siginfo->si_signo;
UWord trapno;
UWord err;
- struct vki_ucontext uc;
esp -= sizeof(*frame);
esp = VG_ROUNDDN(esp, 16);
@@ -258,37 +254,35 @@
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) );
+ /* retaddr, siginfo, uContext 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;
-
frame->retaddr = (Addr)&VG_(x86_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) {
- trapno = siguc->uc_mcontext.trapno;
- err = siguc->uc_mcontext.err;
- } else {
- trapno = 0;
- err = 0;
- }
+ trapno = siguc->uc_mcontext.trapno;
+ err = siguc->uc_mcontext.err;
- synth_ucontext(tst->tid, siginfo, trapno, err, mask, &uc, &frame->fpstate);
+ synth_ucontext(tst->tid, siginfo, trapno, err, mask,
+ &frame->uContext, &frame->fpstate);
- VG_(memcpy)(&frame->sigContext, &uc.uc_mcontext,
- sizeof(struct vki_sigcontext));
-// frame->sigContext.oldmask = mask->sig[0];
+ if (sigNo == VKI_SIGILL && siginfo->si_code > 0)
+ frame->sigInfo.si_addr = (void*)tst->arch.vex.guest_EIP;
- VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
+ VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid,
esp, offsetof(struct sigframe, vg) );
- build_vg_sigframe(&frame->vg, tst, flags, sigNo);
-
+ build_vg_sigframe(&frame->vg, tst, mask, flags, sigNo);
+
return esp;
}
-
/* EXPORTED */
void VG_(sigframe_create)( ThreadId tid,
Addr esp_top_of_frame,
@@ -302,7 +296,7 @@
Addr esp;
ThreadState* tst = VG_(get_ThreadState)(tid);
- esp = build_sigframe(tst, esp_top_of_frame, siginfo, siguc,
+ esp = build_sigframe(tst, esp_top_of_frame, siginfo, siguc, handler,
flags, mask, restorer);
/* Set the thread so it will next run the handler. */
@@ -310,8 +304,8 @@
VG_(set_SP)(tid, esp);
VG_TRACK( post_reg_write, Vg_CoreSignal, tid, VG_O_STACK_PTR, sizeof(Addr));
- //VG_(printf)("handler = %p\n", handler);
tst->arch.vex.guest_EIP = (Addr) handler;
+// tst->arch.vex.guest_EDI = (ULong) siginfo->si_signo;
/* This thread needs to be marked runnable, but we leave that the
caller to do. */
@@ -335,8 +329,7 @@
if (frame->magicPI != 0x31415927 ||
frame->magicE != 0x27182818) {
VG_(message)(Vg_UserMsg, "Thread %d return signal frame "
- "corrupted. Killing process.\n",
- tst->tid);
+ "corrupted. Killing process.", tst->tid);
VG_(set_default_handler)(VKI_SIGSEGV);
VG_(synth_fault)(tst->tid);
*sigNo = VKI_SIGSEGV;
@@ -355,7 +348,7 @@
static
void restore_sigcontext( ThreadState *tst,
- struct vki_sigcontext *sc,
+ struct vki_mcontext *sc,
struct _vki_fpstate *fpstate )
{
tst->arch.vex.guest_EAX = sc->eax;
@@ -374,8 +367,7 @@
tst->arch.vex.guest_ES = sc->es;
tst->arch.vex.guest_FS = sc->fs;
tst->arch.vex.guest_GS = sc->gs;
-
-//:: restore_i387(&tst->arch, fpstate);
+ VG_(memcpy)(fpstate, &sc->fpstate, sizeof(*fpstate));
}
@@ -384,7 +376,7 @@
struct sigframe *frame, Int *sigNo )
{
if (restore_vg_sigframe(tst, &frame->vg, sigNo))
- restore_sigcontext(tst, &frame->sigContext, &frame->fpstate);
+ restore_sigcontext(tst, &frame->uContext.uc_mcontext, &frame->fpstate);
return sizeof(*frame);
}
@@ -401,6 +393,7 @@
/* Correctly reestablish the frame base address. */
esp = tst->arch.vex.guest_ESP;
+ esp += 8; /* Clean up stack from argument/ret passed to sigreturn(2) */
size = restore_sigframe(tst, (struct sigframe *)esp, &sigNo);
==== //depot/projects/valgrind/coregrind/m_trampoline.S#8 (text+ko) ====
@@ -788,8 +788,6 @@
.global VG_(trampoline_stuff_start)
VG_(trampoline_stuff_start):
-// AAA check for 64 bit correctness here. also, assumes linux style syscall
-// args where sigframe is top-of-stack, not a pointer as an argument
.global VG_(amd64_freebsd_SUBST_FOR_sigreturn)
VG_(amd64_freebsd_SUBST_FOR_sigreturn):
/* This is a very specific sequence which GDB uses to
More information about the p4-projects
mailing list