61 lines
		
	
	
		
			1.7 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			61 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
 | 
						|
 | 
						|
}
 |