60 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			60 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			C++
		
	
	
| #include <ucontext.h>
 | |
| 
 | |
| 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 unsigned int uap_fpu_status(void* uap) {
 | |
|   ucontext_t* ucontext = (ucontext_t*)uap;
 | |
|   struct _fpstate* fpregs = (struct _fpstate*)ucontext->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;
 | |
|   struct _fpstate* fpregs = (struct _fpstate*)ucontext->uc_mcontext.fpregs;
 | |
|   fpregs->sw = 0;
 | |
|   if (fpregs->magic == X86_FXSR_MAGIC)
 | |
|     fpregs->mxcsr &= 0xffffffc0;
 | |
| }
 | |
| 
 | |
| #define UAP_STACK_POINTER(ucontext) \
 | |
|   (((ucontext_t*)ucontext)->uc_mcontext.gregs[7])
 | |
| #define UAP_PROGRAM_COUNTER(ucontext) \
 | |
|   (((ucontext_t*)ucontext)->uc_mcontext.gregs[14])
 | |
| #define UAP_SET_TOC_POINTER(uap, ptr) (void)0
 | |
| 
 | |
| #define CODE_TO_FUNCTION_POINTER(code) (void)0
 | |
| #define CODE_TO_FUNCTION_POINTER_CALLBACK(vm, code) (void)0
 | |
| #define FUNCTION_CODE_POINTER(ptr) ptr
 | |
| #define FUNCTION_TOC_POINTER(ptr) ptr
 | |
| 
 | |
| }
 |