|
From: Jeremy F. <je...@go...> - 2005-01-15 03:26:39
|
CVS commit by fitzhardinge:
Allow the VCPU state to be examined and manipulated from within a signal
handler. Integer state is pretty easy, but FP state requires a lot of
fiddley conversion between the CPU's state and the structure passed to
the signal handler.
A none/tests/sigcontext.c 1.1 [no copyright]
A none/tests/sigcontext.stderr.exp 1.1
A none/tests/sigcontext.stdout.exp 1.1
A none/tests/sigcontext.vgtest 1.1
M +6 -12 coregrind/vg_scheduler.c 1.204
M +114 -97 coregrind/vg_signals.c 1.106
M +35 -1 coregrind/x86/core_arch.h 1.17
M +238 -67 coregrind/x86/signal.c 1.7
M +2 -2 coregrind/x86/state.c 1.14
M +5 -2 none/tests/Makefile.am 1.55
--- valgrind/coregrind/vg_signals.c #1.105:1.106
@@ -728,8 +728,7 @@ void vg_push_signal_frame ( ThreadId tid
/* Clear the signal frame created by vg_push_signal_frame, restore the
- simulated machine state, and return the signal number that the
- frame was for. */
+ simulated machine state. */
static
-Int vg_pop_signal_frame ( ThreadId tid )
+void vg_pop_signal_frame ( ThreadId tid )
{
Int sigNo = VGA_(pop_signal_frame)(tid);
@@ -737,6 +736,4 @@ Int vg_pop_signal_frame ( ThreadId tid )
/* Notify tools */
VG_TRACK( post_deliver_signal, tid, sigNo );
-
- return sigNo;
}
@@ -749,11 +746,7 @@ Int vg_pop_signal_frame ( ThreadId tid )
void VG_(signal_returns) ( ThreadId tid )
{
- Int sigNo;
-
/* Pop the signal frame and restore tid's status to what it was
before the signal was delivered. */
- sigNo = vg_pop_signal_frame(tid);
-
- vg_assert(sigNo >= 1 && sigNo <= _VKI_NSIG);
+ vg_pop_signal_frame(tid);
}
@@ -1151,7 +1144,12 @@ static void make_coredump(ThreadId tid,
continue;
- vg_assert(VG_(lseek)(core_fd, 0, VKI_SEEK_CUR) == phdrs[i].p_offset);
- if (phdrs[i].p_filesz > 0)
- VG_(write)(core_fd, (void *)seg->addr, seg->len);
+ if (phdrs[i].p_filesz > 0) {
+ Int ret;
+
+ vg_assert(VG_(lseek)(core_fd, phdrs[i].p_offset, VKI_SEEK_SET) == phdrs[i].p_offset);
+
+ vg_assert(seg->len >= phdrs[i].p_filesz);
+ ret = VG_(write)(core_fd, (void *)seg->addr, phdrs[i].p_filesz);
+ }
}
@@ -1170,6 +1168,8 @@ static void vg_default_action(const vki_
{
Int sigNo = info->si_signo;
- Bool terminate = False;
- Bool core = False;
+ Bool terminate = False; /* kills process */
+ Bool core = False; /* kills process w/ core */
+ struct vki_rlimit corelim;
+ Bool could_core;
vg_assert(VG_(is_running_thread)(tid));
@@ -1210,10 +1210,11 @@ static void vg_default_action(const vki_
if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg, "delivering %d to default handler %s%s",
- sigNo, terminate ? "terminate" : "", core ? "+core" : "");
+ VG_(message)(Vg_DebugMsg, "delivering %d (code %d) to default handler %s%s",
+ sigNo, info->si_code, terminate ? "terminate" : "", core ? "+core" : "");
- if (terminate) {
- struct vki_rlimit corelim;
- Bool could_core = core;
+ if (!terminate)
+ return; /* nothing to do */
+
+ could_core = core;
if (core) {
@@ -1235,4 +1236,5 @@ static void vg_default_action(const vki_
if (info->si_code > VKI_SI_USER) {
const Char *event = NULL;
+ Bool haveaddr = True;
switch(sigNo) {
@@ -1241,4 +1243,16 @@ static void vg_default_action(const vki_
case 1: event = "Access not within mapped region"; break;
case 2: event = "Bad permissions for mapped region"; break;
+ case 128:
+ /* General Protection Fault: The CPU/kernel
+ isn't telling us anything useful, but this
+ is commonly the result of exceeding a
+ segment limit, such as the one imposed by
+ --pointercheck=yes. */
+ if (VG_(clo_pointercheck))
+ event = "GPF (Pointer out of bounds?)";
+ else
+ event = "General Protection Fault";
+ haveaddr = False;
+ break;
}
break;
@@ -1279,7 +1293,11 @@ static void vg_default_action(const vki_
}
- if (event != NULL)
+ if (event != NULL) {
+ if (haveaddr)
VG_(message)(Vg_UserMsg, " %s at address %p",
event, info->_sifields._sigfault._addr);
+ else
+ VG_(message)(Vg_UserMsg, " %s", event);
+ }
}
@@ -1311,5 +1329,4 @@ static void vg_default_action(const vki_
VG_(threads)[tid].exitreason = VgSrc_FatalSig;
VG_(threads)[tid].os_state.fatalsig = sigNo;
- }
}
@@ -1534,5 +1551,5 @@ void vg_sync_signalhandler ( Int sigNo,
if (VG_(clo_trace_signals))
VG_(message)(Vg_DebugMsg,
- " -> extended stack base to %p\n", base);
+ " -> extended stack base to %p", base);
return; // extension succeeded, restart instruction
} else
--- valgrind/coregrind/vg_scheduler.c #1.203:1.204
@@ -659,4 +659,6 @@ static void handle_syscall(ThreadId tid)
SCHEDSETJMP(tid, sigcode, VG_(client_syscall)(tid));
+ vg_assert(VG_(is_running_thread)(tid));
+
switch(sigcode) {
case VgSig_None:
@@ -665,22 +667,15 @@ static void handle_syscall(ThreadId tid)
case VgSig_Exiting:
vg_assert(VG_(is_exiting)(tid));
- if (tst->status != VgTs_Runnable) {
- vg_assert(tst->status == VgTs_WaitSys);
- VG_(set_running)(tid);
- }
break;
case VgSig_AsyncSig:
case VgSig_FatalSig:
- if (tst->status != VgTs_Runnable) {
- vg_assert(tst->status == VgTs_WaitSys);
- VG_(set_running)(tid);
- }
-
if (sigcode == VgSig_FatalSig) {
/* was fatal, we're exiting */
- tst->exitreason = VgSrc_FatalSig;
+ vg_assert(VG_(is_exiting)(tid));
}
+ VG_(sigprocmask)(VKI_SIG_SETMASK, &VG_(blocked_mask), NULL);
+
tst->siginfo.si_signo = 0; /* don't care about signal state */
break;
@@ -693,5 +688,4 @@ static void handle_syscall(ThreadId tid)
vg_assert(tst->siginfo.si_signo == 0);
- vg_assert(VG_(is_running_thread)(tid));
}
--- valgrind/coregrind/x86/core_arch.h #1.16:1.17
@@ -242,4 +242,34 @@ typedef struct _LDT_ENTRY {
#define VG_SIZE_OF_SSESTATE_W ((VG_SIZE_OF_SSESTATE+3)/4)
+#define X86_FXSR_MAGIC 0x0000
+
+struct i387_fsave_struct {
+ long cwd;
+ long swd;
+ long twd;
+ long fip;
+ long fcs;
+ long foo;
+ long fos;
+ long st_space[20]; /* 8*10 bytes for each FP-reg = 80 bytes */
+ long status; /* software status information */
+};
+
+struct i387_fxsave_struct {
+ unsigned short cwd;
+ unsigned short swd;
+ unsigned short twd;
+ unsigned short fop;
+ long fip;
+ long fcs;
+ long foo;
+ long fos;
+ long mxcsr;
+ long mxcsr_mask;
+ long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
+ long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
+ long padding[56];
+} __attribute__ ((aligned (16)));
+
// Architecture-specific part of a ThreadState
@@ -292,5 +322,9 @@ typedef struct {
fxsave/fxrestore. So we have to do it "by hand".
*/
- UInt m_sse[VG_SIZE_OF_SSESTATE_W];
+ union {
+ UInt state[VG_SIZE_OF_SSESTATE_W];
+ struct i387_fsave_struct fsave;
+ struct i387_fxsave_struct fxsave;
+ } m_sse;
UInt sh_eax;
--- valgrind/coregrind/x86/signal.c #1.6:1.7
@@ -49,5 +49,5 @@ typedef
they're the return address and the signal number. */
- /* Sig handler's (bogus) return address */
+ /* Sig handler's return address */
Addr retaddr;
/* The arg to the sig handler. We need to inspect this after
@@ -73,25 +73,18 @@ typedef
/* Sanity check word. */
UInt magicPI;
+
+ UInt handlerflags; /* flags for signal handler */
+
/* pointed to by psigInfo */
vki_siginfo_t sigInfo;
/* pointed to by puContext */
struct vki_ucontext uContext;
+ struct _vki_fpstate fpstate;
/* Safely-saved version of sigNo, as described above. */
Int sigNo_private;
- /* Saved processor state. */
- UInt m_sse[VG_SIZE_OF_SSESTATE_W];
-
- UInt m_eax;
- UInt m_ecx;
- UInt m_edx;
- UInt m_ebx;
- UInt m_ebp;
- UInt m_esp;
- UInt m_esi;
- UInt m_edi;
- UInt m_eflags;
- Addr m_eip;
+ /* XXX This is wrong. Surely we should store the shadow values
+ into the shadow memory behind the actual values? */
UInt sh_eax;
UInt sh_ebx;
@@ -107,8 +100,4 @@ typedef
vki_sigset_t mask;
- /* Scheduler-private stuff: what was the thread's status prior to
- delivering this signal? */
- ThreadStatus status;
-
/* Sanity check word. Is the highest-addressed word; do not
move!*/
@@ -121,7 +110,192 @@ typedef
/*------------------------------------------------------------*/
+/*
+ Great gobs of FP state conversion taken wholesale from
+ linux/arch/i386/kernel/i387.c
+ */
+
+/*
+ * FXSR floating point environment conversions.
+ */
+#define X86_FXSR_MAGIC 0x0000
+
+/*
+ * FPU tag word conversions.
+ */
+
+static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
+{
+ unsigned int tmp; /* to avoid 16 bit prefixes in the code */
+
+ /* Transform each pair of bits into 01 (valid) or 00 (empty) */
+ tmp = ~twd;
+ tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
+ /* and move the valid bits to the lower byte. */
+ tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
+ tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
+ tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
+ return tmp;
+}
+
+static unsigned long twd_fxsr_to_i387( const struct i387_fxsave_struct *fxsave )
+{
+ struct _vki_fpxreg *st = NULL;
+ unsigned long twd = (unsigned long) fxsave->twd;
+ unsigned long tag;
+ unsigned long ret = 0xffff0000u;
+ int i;
+
+#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
+
+ for ( i = 0 ; i < 8 ; i++ ) {
+ if ( twd & 0x1 ) {
+ st = (struct _vki_fpxreg *) FPREG_ADDR( fxsave, i );
+
+ switch ( st->exponent & 0x7fff ) {
+ case 0x7fff:
+ tag = 2; /* Special */
+ break;
+ case 0x0000:
+ if ( !st->significand[0] &&
+ !st->significand[1] &&
+ !st->significand[2] &&
+ !st->significand[3] ) {
+ tag = 1; /* Zero */
+ } else {
+ tag = 2; /* Special */
+ }
+ break;
+ default:
+ if ( st->significand[3] & 0x8000 ) {
+ tag = 0; /* Valid */
+ } else {
+ tag = 2; /* Special */
+ }
+ break;
+ }
+ } else {
+ tag = 3; /* Empty */
+ }
+ ret |= (tag << (2 * i));
+ twd = twd >> 1;
+ }
+ return ret;
+}
+
+static void convert_fxsr_to_user( struct _vki_fpstate *buf,
+ const struct i387_fxsave_struct *fxsave )
+{
+ unsigned long env[7];
+ struct _vki_fpreg *to;
+ struct _vki_fpxreg *from;
+ int i;
+
+ env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul;
+ env[1] = (unsigned long)fxsave->swd | 0xffff0000ul;
+ env[2] = twd_fxsr_to_i387(fxsave);
+ env[3] = fxsave->fip;
+ env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
+ env[5] = fxsave->foo;
+ env[6] = fxsave->fos;
+
+ VG_(memcpy)(buf, env, 7 * sizeof(unsigned long));
+
+ to = &buf->_st[0];
+ from = (struct _vki_fpxreg *) &fxsave->st_space[0];
+ for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
+ unsigned long __user *t = (unsigned long __user *)to;
+ unsigned long *f = (unsigned long *)from;
+
+ t[0] = f[0];
+ t[1] = f[1];
+ to->exponent = from->exponent;
+ }
+}
+
+static void convert_fxsr_from_user( struct i387_fxsave_struct *fxsave,
+ const struct _vki_fpstate *buf )
+{
+ unsigned long env[7];
+ struct _vki_fpxreg *to;
+ const struct _vki_fpreg *from;
+ int i;
+
+ VG_(memcpy)(env, buf, 7 * sizeof(long));
+
+ fxsave->cwd = (unsigned short)(env[0] & 0xffff);
+ fxsave->swd = (unsigned short)(env[1] & 0xffff);
+ fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
+ fxsave->fip = env[3];
+ fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16);
+ fxsave->fcs = (env[4] & 0xffff);
+ fxsave->foo = env[5];
+ fxsave->fos = env[6];
+
+ to = (struct _vki_fpxreg *) &fxsave->st_space[0];
+ from = &buf->_st[0];
+ for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
+ unsigned long *t = (unsigned long *)to;
+ unsigned long __user *f = (unsigned long __user *)from;
+
+ t[0] = f[0];
+ t[1] = f[1];
+ to->exponent = from->exponent;
+ }
+}
+
+static inline void save_i387_fsave( arch_thread_t *regs, struct _vki_fpstate *buf )
+{
+ struct i387_fsave_struct *fs = ®s->m_sse.fsave;
+
+ fs->status = fs->swd;
+ VG_(memcpy)(buf, fs, sizeof(*fs));
+}
+
+static void save_i387_fxsave( arch_thread_t *regs, struct _vki_fpstate *buf )
+{
+ const struct i387_fxsave_struct *fx = ®s->m_sse.fxsave;
+ convert_fxsr_to_user( buf, fx );
+
+ buf->status = fx->swd;
+ buf->magic = X86_FXSR_MAGIC;
+ VG_(memcpy)(buf->_fxsr_env, fx, sizeof(struct i387_fxsave_struct));
+}
+
+static void save_i387( arch_thread_t *regs, struct _vki_fpstate *buf )
+{
+ if ( VG_(have_ssestate) )
+ save_i387_fxsave( regs, buf );
+ else
+ save_i387_fsave( regs, buf );
+}
+
+static inline void restore_i387_fsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
+{
+ VG_(memcpy)( ®s->m_sse.fsave, buf, sizeof(struct i387_fsave_struct) );
+}
+
+static void restore_i387_fxsave( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
+{
+ VG_(memcpy)(®s->m_sse.fxsave, &buf->_fxsr_env[0],
+ sizeof(struct i387_fxsave_struct) );
+ /* mxcsr reserved bits must be masked to zero for security reasons */
+ regs->m_sse.fxsave.mxcsr &= 0xffbf;
+ convert_fxsr_from_user( ®s->m_sse.fxsave, buf );
+}
+
+static void restore_i387( arch_thread_t *regs, const struct _vki_fpstate __user *buf )
+{
+ if ( VG_(have_ssestate) ) {
+ restore_i387_fxsave( regs, buf );
+ } else {
+ restore_i387_fsave( regs, buf );
+ }
+}
+
+
/* Make up a plausible-looking thread state from the thread's current state */
static void synth_ucontext(ThreadId tid, const vki_siginfo_t *si,
- const vki_sigset_t *set, struct vki_ucontext *uc)
+ const vki_sigset_t *set,
+ struct vki_ucontext *uc, struct _vki_fpstate *fpstate)
{
ThreadState *tst = VG_(get_ThreadState)(tid);
@@ -134,4 +308,7 @@ static void synth_ucontext(ThreadId tid,
uc->uc_sigmask = *set;
uc->uc_stack = tst->altstack;
+ sc->fpstate = fpstate;
+
+ save_i387(&tst->arch, fpstate);
#define SC(reg) sc->reg = tst->arch.m_##reg
@@ -173,5 +350,4 @@ void VGA_(push_signal_frame)(ThreadId ti
Addr esp;
ThreadState* tst;
- Int i;
VgSigFrame* frame;
Int sigNo = siginfo->si_signo;
@@ -202,4 +379,6 @@ void VGA_(push_signal_frame)(ThreadId ti
if (flags & VKI_SA_SIGINFO) {
/* if the client asked for a siginfo delivery, then build the stack that way */
+
+ /* pointers to siginfo and ucontext */
VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)",
(Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) );
@@ -208,4 +387,5 @@ void VGA_(push_signal_frame)(ThreadId ti
VG_TRACK( post_mem_write, (Addr)&frame->handlerArgs, sizeof(frame->handlerArgs.sigInfo) );
+ /* siginfo */
VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)",
(Addr)&frame->sigInfo, sizeof(frame->sigInfo) );
@@ -213,14 +393,15 @@ void VGA_(push_signal_frame)(ThreadId ti
VG_TRACK( post_mem_write, (Addr)&frame->sigInfo, sizeof(frame->sigInfo) );
- VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (siginfo)",
+ /* ucontext */
+ VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (ucontext)",
(Addr)&frame->uContext, sizeof(frame->uContext) );
- synth_ucontext(tid, siginfo, mask, &frame->uContext);
+ synth_ucontext(tid, siginfo, mask, &frame->uContext, &frame->fpstate);
VG_TRACK( post_mem_write, (Addr)&frame->uContext, sizeof(frame->uContext) );
} else {
struct vki_ucontext uc;
- /* otherwise just put the sigcontext there */
+ /* non-siginfo: just put the sigcontext there */
- synth_ucontext(tid, siginfo, mask, &uc);
+ synth_ucontext(tid, siginfo, mask, &uc, &frame->fpstate);
VG_TRACK( pre_mem_write, Vg_CoreSignal, tid, "signal handler frame (sigcontext)",
@@ -236,18 +417,4 @@ void VGA_(push_signal_frame)(ThreadId ti
frame->magicPI = 0x31415927;
- for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
- frame->m_sse[i] = tst->arch.m_sse[i];
-
- frame->m_eax = tst->arch.m_eax;
- frame->m_ecx = tst->arch.m_ecx;
- frame->m_edx = tst->arch.m_edx;
- frame->m_ebx = tst->arch.m_ebx;
- frame->m_ebp = tst->arch.m_ebp;
- frame->m_esp = tst->arch.m_esp;
- frame->m_esi = tst->arch.m_esi;
- frame->m_edi = tst->arch.m_edi;
- frame->m_eflags = tst->arch.m_eflags;
- frame->m_eip = tst->arch.m_eip;
-
if (VG_(needs).shadow_regs) {
frame->sh_eax = tst->arch.sh_eax;
@@ -264,10 +431,5 @@ void VGA_(push_signal_frame)(ThreadId ti
frame->mask = tst->sig_mask;
- /* If the thread is currently blocked in a syscall, we want it to
- resume as runnable. */
- if (tst->status == VgTs_WaitSys)
- frame->status = VgTs_Runnable;
- else
- frame->status = tst->status;
+ frame->handlerflags = flags;
frame->magicE = 0x27182818;
@@ -285,5 +447,5 @@ void VGA_(push_signal_frame)(ThreadId ti
if (0)
- VG_(printf)("pushed signal frame; %%ESP now = %p, next %%EBP = %p, status=%d\n",
+ VG_(printf)("pushed signal frame; %%ESP now = %p, next %%EIP = %p, status=%d\n",
esp, tst->arch.m_eip, tst->status);
}
@@ -292,7 +454,7 @@ Int VGA_(pop_signal_frame)(ThreadId tid)
{
Addr esp;
- Int i;
VgSigFrame* frame;
ThreadState* tst;
+ struct vki_sigcontext *sc;
vg_assert(VG_(is_valid_tid)(tid));
@@ -307,7 +469,4 @@ Int VGA_(pop_signal_frame)(ThreadId tid)
vg_assert(frame->magicPI == 0x31415927);
vg_assert(frame->magicE == 0x27182818);
- if (VG_(clo_trace_signals))
- VG_(message)(Vg_DebugMsg,
- "vg_pop_signal_frame (thread %d): valid magic; EIP=%p", tid, frame->m_eip);
/* Mark the frame structure as nonaccessible. */
@@ -315,17 +474,28 @@ Int VGA_(pop_signal_frame)(ThreadId tid)
/* restore machine state */
- for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
- tst->arch.m_sse[i] = frame->m_sse[i];
+ if (frame->handlerflags & VKI_SA_SIGINFO)
+ sc = &frame->uContext.uc_mcontext;
+ else
+ sc = &frame->handlerArgs.sigContext;
- tst->arch.m_eax = frame->m_eax;
- tst->arch.m_ecx = frame->m_ecx;
- tst->arch.m_edx = frame->m_edx;
- tst->arch.m_ebx = frame->m_ebx;
- tst->arch.m_ebp = frame->m_ebp;
- tst->arch.m_esp = frame->m_esp;
- tst->arch.m_esi = frame->m_esi;
- tst->arch.m_edi = frame->m_edi;
- tst->arch.m_eflags = frame->m_eflags;
- tst->arch.m_eip = frame->m_eip;
+ tst->arch.m_eax = sc->eax;
+ tst->arch.m_ecx = sc->ecx;
+ tst->arch.m_edx = sc->edx;
+ tst->arch.m_ebx = sc->ebx;
+ tst->arch.m_ebp = sc->ebp;
+ tst->arch.m_esp = sc->esp;
+ tst->arch.m_esi = sc->esi;
+ tst->arch.m_edi = sc->edi;
+ tst->arch.m_eflags = sc->eflags;
+ tst->arch.m_eip = sc->eip;
+
+ tst->arch.m_cs = sc->cs;
+ tst->arch.m_ss = sc->ss;
+ tst->arch.m_ds = sc->ds;
+ tst->arch.m_es = sc->es;
+ tst->arch.m_fs = sc->fs;
+ tst->arch.m_gs = sc->gs;
+
+ restore_i387(&tst->arch, &frame->fpstate);
if (VG_(needs).shadow_regs) {
@@ -341,7 +511,8 @@ Int VGA_(pop_signal_frame)(ThreadId tid)
}
- /* And restore the thread's status to what it was before the signal
- was delivered. */
- tst->status = frame->status;
+ if (VG_(clo_trace_signals))
+ VG_(message)(Vg_DebugMsg,
+ "vg_pop_signal_frame (thread %d): valid magic; EIP=%p",
+ tid, sc->eip);
tst->sig_mask = frame->mask;
@@ -439,5 +610,5 @@ void VGA_(fill_elffpxregs_from_tst) ( vk
const arch_thread_t* arch )
{
- VG_(memcpy)(xfpu, arch->m_sse, sizeof(*xfpu));
+ VG_(memcpy)(xfpu, arch->m_sse.state, sizeof(*xfpu));
}
--- valgrind/coregrind/x86/state.c #1.13:1.14
@@ -317,5 +317,5 @@ void VGA_(load_state) ( arch_thread_t* a
for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
- VG_(baseBlock)[VGOFF_(m_ssestate) + i] = arch->m_sse[i];
+ VG_(baseBlock)[VGOFF_(m_ssestate) + i] = arch->m_sse.state[i];
if (VG_(needs).shadow_regs) {
@@ -396,5 +396,5 @@ n",
for (i = 0; i < VG_SIZE_OF_SSESTATE_W; i++)
- arch->m_sse[i]
+ arch->m_sse.state[i]
= VG_(baseBlock)[VGOFF_(m_ssestate) + i];
--- valgrind/none/tests/Makefile.am #1.54:1.55
@@ -49,9 +49,10 @@
shortpush.stderr.exp shortpush.vgtest \
shorts.stderr.exp shorts.vgtest \
- tls.stderr.exp tls.stdout.exp \
+ sigcontext.stdout.exp sigcontext.stderr.exp sigcontext.vgtest \
smc1.stderr.exp smc1.stdout.exp smc1.vgtest \
syscall-restart1.vgtest syscall-restart1.stdout.exp syscall-restart1.stderr.exp \
syscall-restart2.vgtest syscall-restart2.stdout.exp syscall-restart2.stderr.exp \
system.stderr.exp system.vgtest \
+ tls.stderr.exp tls.stdout.exp \
yield.stderr.exp yield.stdout.exp yield.vgtest
@@ -62,5 +63,6 @@
munmap_exe map_unaligned map_unmap mq mremap rcrl readline1 \
resolv rlimit_nofile sem semlimit sha1_test \
- shortpush shorts smc1 susphello pending pth_blockedsig pth_stackalign \
+ shortpush shorts sigcontext \
+ smc1 susphello pending pth_blockedsig pth_stackalign \
syscall-restart1 syscall-restart2 system \
coolo_sigaction gxx304 yield
@@ -102,4 +104,5 @@
shortpush_SOURCES = shortpush.c
shorts_SOURCES = shorts.c
+sigcontext_SOURCES = sigcontext.c
susphello_SOURCES = susphello.c
susphello_LDADD = -lpthread
|