From b77d9d29608c43d2cb5304343a224cbd0861778c Mon Sep 17 00:00:00 2001 From: Joe Groff Date: Mon, 14 Sep 2009 12:30:10 -0500 Subject: [PATCH 1/2] more secret sauce to tease mxcsr out of linux-x86.32 ucontext --- vm/os-linux-x86.32.hpp | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/vm/os-linux-x86.32.hpp b/vm/os-linux-x86.32.hpp index 1db87f995d..8fa7eff842 100644 --- a/vm/os-linux-x86.32.hpp +++ b/vm/os-linux-x86.32.hpp @@ -3,6 +3,32 @@ namespace factor { +// glibc lies about the contents of the fpstate the kernel provides, hiding the FXSR +// environment +struct _fpstate { + /* Regular FPU environment */ + unsigned long cw; + unsigned long sw; + unsigned long tag; + unsigned long ipoff; + unsigned long cssel; + unsigned long dataoff; + unsigned long datasel; + struct _fpreg _st[8]; + unsigned short status; + unsigned short magic; /* 0xffff = regular FPU data only */ + + /* FXSR FPU environment */ + unsigned long _fxsr_env[6]; /* FXSR FPU env is ignored */ + unsigned long mxcsr; + unsigned long reserved; + struct _fpxreg _fxsr_st[8]; /* FXSR FPU reg data is ignored */ + struct _xmmreg _xmm[8]; + unsigned long padding[56]; +}; + +#define X86_FXSR_MAGIC 0x0000 + inline static void *ucontext_stack_pointer(void *uap) { ucontext_t *ucontext = (ucontext_t *)uap; @@ -11,15 +37,21 @@ inline static void *ucontext_stack_pointer(void *uap) inline static unsigned int uap_fpu_status(void *uap) { - // XXX mxcsr not available in i386 ucontext ucontext_t *ucontext = (ucontext_t *)uap; - return ucontext->uc_mcontext.fpregs->sw; + struct _fpstate *fpregs = (struct _fpstate *)uap->uc_mcontext.fpregs; + if (fpregs->magic == X86_FXSR_MAGIC) + return fpregs->sw | fpregs->mxcsr; + else + return fpregs->sw; } inline static void uap_clear_fpu_status(void *uap) { ucontext_t *ucontext = (ucontext_t *)uap; - ucontext->uc_mcontext.fpregs->sw = 0; + struct _fpstate *fpregs = (struct _fpstate *)uap->uc_mcontext.fpregs; + fpregs->sw = 0; + if (fpregs->magic == X86_FXSR_MAGIC) + fpregs->mxcsr &= 0xffffffc0; } #define UAP_PROGRAM_COUNTER(ucontext) \ From 89ce13d4d46f61b445cd0e9b0aebaebed54d66f0 Mon Sep 17 00:00:00 2001 From: Joe Groff Date: Mon, 14 Sep 2009 13:21:46 -0500 Subject: [PATCH 2/2] linux 32 typo --- vm/os-linux-x86.32.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vm/os-linux-x86.32.hpp b/vm/os-linux-x86.32.hpp index 8fa7eff842..bd2315ccef 100644 --- a/vm/os-linux-x86.32.hpp +++ b/vm/os-linux-x86.32.hpp @@ -38,7 +38,7 @@ inline static void *ucontext_stack_pointer(void *uap) inline static unsigned int uap_fpu_status(void *uap) { ucontext_t *ucontext = (ucontext_t *)uap; - struct _fpstate *fpregs = (struct _fpstate *)uap->uc_mcontext.fpregs; + struct _fpstate *fpregs = (struct _fpstate *)ucontext->uc_mcontext.fpregs; if (fpregs->magic == X86_FXSR_MAGIC) return fpregs->sw | fpregs->mxcsr; else @@ -48,7 +48,7 @@ inline static unsigned int uap_fpu_status(void *uap) inline static void uap_clear_fpu_status(void *uap) { ucontext_t *ucontext = (ucontext_t *)uap; - struct _fpstate *fpregs = (struct _fpstate *)uap->uc_mcontext.fpregs; + struct _fpstate *fpregs = (struct _fpstate *)ucontext->uc_mcontext.fpregs; fpregs->sw = 0; if (fpregs->magic == X86_FXSR_MAGIC) fpregs->mxcsr &= 0xffffffc0;