static bool OnCommand(THREADID tid, CONTEXT *context, const std::string &cmd, std::string *reply, VOID *) { fprintf (fp, "OnCommand %s\n", cmd.c_str()); fflush (fp); if (cmd == "set_xmm3") { gotOurCommand = true; CHAR fpContextSpaceForFpConextFromPin[FPSTATE_SIZE]; FPSTATE *fpContextFromPin = reinterpret_cast<FPSTATE *>(fpContextSpaceForFpConextFromPin); PIN_GetContextFPState(context, fpContextFromPin); for (int j=0; j<16; j++) { fpContextFromPin->fxsave_legacy._xmms[3]._vec8[j] = 0x5a; } PIN_SetContextFPState(context, fpContextFromPin); CHAR fpContextSpaceForFpConextFromPin1[FPSTATE_SIZE]; fpContextFromPin = reinterpret_cast<FPSTATE *>(fpContextSpaceForFpConextFromPin1); PIN_GetContextFPState(context, fpContextFromPin); for (int j=0; j<16; j++) { if (fpContextFromPin->fxsave_legacy._xmms[3]._vec8[j] != 0x5a) { fprintf (fp, "***Error tool did not properly set xmm3\n"); fflush (fp); PIN_ExitProcess(1); } } fprintf (fp, "tool properly set xmm3\n"); fflush (fp); return true; } return false; }
void CheckAndSetFpContextXmmRegs (const CONTEXT *ctxtFrom, CONTEXT *ctxtTo) { fprintf (stdout, "TOOL CheckAndSetFpContextXmmRegs\n"); fflush (stdout); CHAR fpContextSpaceForFpConextFromPin[FPSTATE_SIZE]; FPSTATE *fpContextFromPin = reinterpret_cast<FPSTATE *>(fpContextSpaceForFpConextFromPin); // the application set the each byte in the xmm regs in the state to be 0xa5 before the exception was caused PIN_GetContextFPState(ctxtFrom, fpContextFromPin); for (int i=0; i<NUM_XMM_REGS; i++) { for (int j=0; j<16; j++) { if (fpContextFromPin->fxsave_legacy._xmms[i]._vec8[j] != 0xa5) { fprintf (stdout, "TOOL unexpected _xmm[%d]._vec8[%d] value %x\n", i, j, (unsigned int)fpContextFromPin->fxsave_legacy._xmms[i]._vec8[j]); fflush (stdout); //exit (-1); } } } fprintf (stdout, "TOOL Checked ctxtFrom OK\n"); fflush (stdout); // the tool now sets the each byte of the xmm regs in the ctxtTo to be 0x5a for (int i=0; i<NUM_XMM_REGS; i++) { for (int j=0; j<16; j++) { fpContextFromPin->fxsave_legacy._xmms[i]._vec8[j] = 0x5a; } } PIN_SetContextFPState(ctxtTo, fpContextFromPin); // verify the setting worked for (int i=0; i<NUM_XMM_REGS; i++) { fpContextFromPin->fxsave_legacy._xmms[i]._vec64[0] = 0x0; fpContextFromPin->fxsave_legacy._xmms[i]._vec64[1] = 0x0; } PIN_GetContextFPState(ctxtTo, fpContextFromPin); for (int i=0; i<NUM_XMM_REGS; i++) { for (int j=0; j<16; j++) { if (fpContextFromPin->fxsave_legacy._xmms[i]._vec8[j] != 0x5a) { printf ("TOOL ERROR\n"); fflush (stdout); exit (-1); } } } printf ("TOOL Checked ctxtTo OK\n"); fflush (stdout); // application will verify that actual xmm registers contain 0x5a in each byte }
/* * Pin calls this function to set the value of an emulated register. */ static VOID SetReg(unsigned toolRegId, THREADID tid, CONTEXT *ctxt, const VOID *data, VOID *) { PrintEmulated(); switch (toolRegId) { case EMULATED_REG_RCX: { const ADDRINT *val = static_cast<const ADDRINT *>(data); PIN_SetContextReg(ctxt, REG_RCX, *val); break; } case EMULATED_REG_RSP: { const ADDRINT *val = static_cast<const ADDRINT *>(data); PIN_SetContextReg(ctxt, REG_RSP, *val); break; } case EMULATED_REG_FPSW: { const UINT32 *val = static_cast<const UINT32 *>(data); PIN_SetContextReg(ctxt, REG_FPSW, static_cast<ADDRINT>(*val)); break; } case EMULATED_REG_ST0: { FPSTATE fpstate; PIN_GetContextFPState(ctxt, &fpstate); std::memcpy(&fpstate.fxsave_legacy._sts[0], data, 10); PIN_SetContextFPState(ctxt, &fpstate); break; } case EMULATED_REG_XMM0: { FPSTATE fpstate; PIN_GetContextFPState(ctxt, &fpstate); std::memcpy(&fpstate.fxsave_legacy._xmms[0], data, 16); PIN_SetContextFPState(ctxt, &fpstate); break; } default: { ASSERTX(0); break; } } }
VOID OnThread(THREADID threadIndex, CONTEXT *ctxt, INT32 flags, VOID *v) { printf ("TOOL OnThread callback\n"); fflush (stdout); /* set the xmm regs in the ctxt which is used to execute the thread */ CHAR fpContextSpaceForFpConextFromPin[FPSTATE_SIZE]; FPSTATE *fpContextFromPin = reinterpret_cast<FPSTATE *>(fpContextSpaceForFpConextFromPin); PIN_GetContextFPState(ctxt, fpContextFromPin); for (int i=0; i<NUM_XMM_REGS; i++) { fpContextFromPin->fxsave_legacy._xmms[i]._vec32[0] = 0xbaadf00d; fpContextFromPin->fxsave_legacy._xmms[i]._vec32[1] = 0xbaadf00d; fpContextFromPin->fxsave_legacy._xmms[i]._vec32[2] = 0xbaadf00d; fpContextFromPin->fxsave_legacy._xmms[i]._vec32[3] = 0xbaadf00d; } PIN_SetContextFPState(ctxt, fpContextFromPin); // verify the xmm regs were set in the ctxt CHAR fpContextSpaceForFpConextFromPin2[FPSTATE_SIZE]; FPSTATE *fpContextFromPin2 = reinterpret_cast<FPSTATE *>(fpContextSpaceForFpConextFromPin2); PIN_GetContextFPState(ctxt, fpContextFromPin2); for (int i=0; i<NUM_XMM_REGS; i++) { if ((fpContextFromPin->fxsave_legacy._xmms[i]._vec64[0] != fpContextFromPin2->fxsave_legacy._xmms[i]._vec64[0]) || (fpContextFromPin->fxsave_legacy._xmms[i]._vec64[1] != fpContextFromPin2->fxsave_legacy._xmms[i]._vec64[1])) { printf("TOOL ERROR2 at xmm[%d] (%lx %lx %lx %lx) (%lx %lx %lx %lx)\n", i, (unsigned long)fpContextFromPin->fxsave_legacy._xmms[i]._vec32[0], (unsigned long)fpContextFromPin->fxsave_legacy._xmms[i]._vec32[1], (unsigned long)fpContextFromPin->fxsave_legacy._xmms[i]._vec32[2], (unsigned long)fpContextFromPin->fxsave_legacy._xmms[i]._vec32[3], (unsigned long)fpContextFromPin2->fxsave_legacy._xmms[i]._vec32[0], (unsigned long)fpContextFromPin2->fxsave_legacy._xmms[i]._vec32[1], (unsigned long)fpContextFromPin2->fxsave_legacy._xmms[i]._vec32[2], (unsigned long)fpContextFromPin2->fxsave_legacy._xmms[i]._vec32[3]); fflush (stdout); exit (-1); } } // now the thread should start running with the values from above in the xmm regs }
VOID REPLACE_ReplacedXmmRegs(CONTEXT *context, THREADID tid, AFUNPTR originalFunction) { printf ("TOOL in REPLACE_ReplacedXmmRegs\n"); fflush (stdout); CONTEXT writableContext, *ctxt; if (KnobUseIargConstContext) { // need to copy the ctxt into a writable context PIN_SaveContext(context, &writableContext); ctxt = &writableContext; } else { ctxt = context; } /* set the xmm regs in the ctxt which is used to execute the originalFunction (via PIN_CallApplicationFunction) */ CHAR fpContextSpaceForFpConextFromPin[FPSTATE_SIZE]; FPSTATE *fpContextFromPin = reinterpret_cast<FPSTATE *>(fpContextSpaceForFpConextFromPin); PIN_GetContextFPState(ctxt, fpContextFromPin); for (int i=0; i<NUM_XMM_REGS; i++) { fpContextFromPin->fxsave_legacy._xmms[i]._vec32[0] = 0xacdcacdc; fpContextFromPin->fxsave_legacy._xmms[i]._vec32[1] = 0xacdcacdc; fpContextFromPin->fxsave_legacy._xmms[i]._vec32[2] = 0xacdcacdc; fpContextFromPin->fxsave_legacy._xmms[i]._vec32[3] = 0xacdcacdc; } PIN_SetContextFPState(ctxt, fpContextFromPin); // verify the xmm regs were set in the ctxt CHAR fpContextSpaceForFpConextFromPin2[FPSTATE_SIZE]; FPSTATE *fpContextFromPin2 = reinterpret_cast<FPSTATE *>(fpContextSpaceForFpConextFromPin2); PIN_GetContextFPState(ctxt, fpContextFromPin2); for (int i=0; i<NUM_XMM_REGS; i++) { if ((fpContextFromPin->fxsave_legacy._xmms[i]._vec64[0] !=fpContextFromPin2->fxsave_legacy._xmms[i]._vec64[0]) || (fpContextFromPin->fxsave_legacy._xmms[i]._vec64[1] !=fpContextFromPin2->fxsave_legacy._xmms[i]._vec64[1])) { printf("TOOL ERROR at xmm[%d] (%lx %lx %lx %lx) (%lx %lx %lx %lx)\n", i, (unsigned long)fpContextFromPin->fxsave_legacy._xmms[i]._vec32[0], (unsigned long)fpContextFromPin->fxsave_legacy._xmms[i]._vec32[1], (unsigned long)fpContextFromPin->fxsave_legacy._xmms[i]._vec32[2], (unsigned long)fpContextFromPin->fxsave_legacy._xmms[i]._vec32[3], (unsigned long)fpContextFromPin2->fxsave_legacy._xmms[i]._vec32[0], (unsigned long)fpContextFromPin2->fxsave_legacy._xmms[i]._vec32[1], (unsigned long)fpContextFromPin2->fxsave_legacy._xmms[i]._vec32[2], (unsigned long)fpContextFromPin2->fxsave_legacy._xmms[i]._vec32[3]); exit (-1); } } // call the originalFunction function with the xmm regs set from above printf("TOOL Calling replaced ReplacedXmmRegs()\n"); fflush (stdout); PIN_CallApplicationFunction(ctxt, tid, CALLINGSTD_DEFAULT, originalFunction, PIN_PARG_END()); printf("TOOL Returned from replaced ReplacedXmmRegs()\n"); fflush (stdout); if (executeAtAddr != 0) { // set xmm regs to other values for (int i=0; i<NUM_XMM_REGS; i++) { fpContextFromPin->fxsave_legacy._xmms[i]._vec32[0] = 0xdeadbeef; fpContextFromPin->fxsave_legacy._xmms[i]._vec32[1] = 0xdeadbeef; fpContextFromPin->fxsave_legacy._xmms[i]._vec32[2] = 0xdeadbeef; fpContextFromPin->fxsave_legacy._xmms[i]._vec32[3] = 0xdeadbeef; } PIN_SetContextFPState(ctxt, fpContextFromPin); // execute the application function ExecuteAtFunc with the xmm regs set PIN_SetContextReg(ctxt, REG_INST_PTR, executeAtAddr); printf("TOOL Calling ExecutedAtFunc\n"); fflush (stdout); PIN_ExecuteAt (ctxt); printf("TOOL returned from ExecutedAtFunc\n"); fflush (stdout); } }
void CheckAndSetFpContextX87RegsAtException (const CONTEXT *ctxtFrom, CONTEXT *ctxtTo) { fprintf (stdout, "TOOL CheckAndSetFpContextX87Regs\n"); fflush (stdout); CHAR fpContextSpaceForFpConextFromPin[FPSTATE_SIZE]; FPSTATE *fpContextFromPin = reinterpret_cast<FPSTATE *>(fpContextSpaceForFpConextFromPin); PIN_GetContextFPState(ctxtFrom, fpContextFromPin); // verfiy that x87 registers are as they were set by the app just before the exception /* app set the x87 fp regs just before the exepction as follows _mxcsr 1f80 _st[0] 0 3fff 80000000 0 _st[1] 0 3fff 80000000 0 _st[2] 0 3fff 80000000 0 _st[3] 0 5a5a 5a5a5a5a 5a5a5a5a _st[4] 0 5a5a 5a5a5a5a 5a5a5a5a _st[5] 0 5a5a 5a5a5a5a 5a5a5a5a _st[6] 0 5a5a 5a5a5a5a 5a5a5a5a _st[7] 0 5a5a 5a5a5a5a 5a5a5a5a */ printf ("_mxcsr %x\n", fpContextFromPin->fxsave_legacy._mxcsr); if (fpContextFromPin->fxsave_legacy._mxcsr & 0x200) { printf ("***Error divide by zero should be masked\n"); exit (-1); } int i; for (i=0; i<3; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); printf ("_st[%d] %x %x %x %x\n", i,ptr->_hi2,ptr->_hi1,ptr->_lo2,ptr->_lo1); if (ptr->_hi2 != 0 && ptr->_hi1 != 0x3fff && ptr->_lo2 != 0x80000000 && ptr->_lo1 != 0) { printf ("***Error in this _st\n"); exit(-1); } } for (; i< 8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); printf ("_st[%d] %x %x %x %x\n", i,ptr->_hi2,ptr->_hi1,ptr->_lo2,ptr->_lo1); if (ptr->_hi2 != 0 && ptr->_hi1 != 0x5a5a && ptr->_lo2 != 0x5a5a5a5a && ptr->_lo1 != 0x5a5a5a5a) { printf ("***Error in this _st\n"); exit(-1); } } fprintf (stdout, "TOOL Checked ctxtFrom OK\n"); fflush (stdout); for (i=0; i< 8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); ptr->_hi2=0xbaadf00d; ptr->_hi1=0xbaadf00d; ptr->_lo2=0xbaadf00d; ptr->_lo1=0xbaadf00d; } fpContextFromPin->fxsave_legacy._mxcsr |= (0x200); // mask divide by zero PIN_SetContextFPState(ctxtTo, fpContextFromPin); // verify the setting worked for (i=0; i<8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); ptr->_hi2=0x0; ptr->_hi1=0x0; ptr->_lo2=0x0; ptr->_lo1=0x0; } PIN_GetContextFPState(ctxtTo, fpContextFromPin); for (i=0; i<8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); if (ptr->_hi2 != 0xbaadf00d || ptr->_hi2 != 0xbaadf00d || ptr->_lo2!= 0xbaadf00d || ptr->_lo1!= 0xbaadf00d ) { printf ("TOOL error in setting fp context in CheckAndSetFpContextX87Regs\n"); exit (-1); } } printf ("TOOL Checked ctxtTo OK\n"); fflush (stdout); }
VOID REPLACE_ReplacedX87Regs(CONTEXT *context, THREADID tid, AFUNPTR originalFunction) { printf ("TOOL in REPLACE_ReplacedX87Regs x87 regs are:\n"); fflush (stdout); CHAR fpContextSpaceForFpConextFromPin[FPSTATE_SIZE]; FPSTATE *fpContextFromPin = reinterpret_cast<FPSTATE *>(fpContextSpaceForFpConextFromPin); PIN_GetContextFPState(context, fpContextFromPin); // verfiy that x87 registers are as they were set by the app just before the call to // ReplacedX87Regs, which is replaced by this function /* app set the x87 fp regs just before the call to ReplacedX87Regs as follows _mxcsr 1f80 _st[0] 0 3fff 80000000 0 _st[1] 0 3fff 80000000 0 _st[2] 0 3fff 80000000 0 _st[3] 0 5a5a 5a5a5a5a 5a5a5a5a _st[4] 0 5a5a 5a5a5a5a 5a5a5a5a _st[5] 0 5a5a 5a5a5a5a 5a5a5a5a _st[6] 0 5a5a 5a5a5a5a 5a5a5a5a _st[7] 0 5a5a 5a5a5a5a 5a5a5a5a */ printf ("_mxcsr %x\n", fpContextFromPin->fxsave_legacy._mxcsr); if (fpContextFromPin->fxsave_legacy._mxcsr & 0x200) { printf ("***Error divide by zero should be masked\n"); exit (-1); } int i; for (i=0; i<3; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); printf ("_st[%d] %x %x %x %x\n", i,ptr->_hi2,ptr->_hi1,ptr->_lo2,ptr->_lo1); if (ptr->_hi2 != 0 && ptr->_hi1 != 0x3fff && ptr->_lo2 != 0x80000000 && ptr->_lo1 != 0) { printf ("***Error in this _st\n"); exit(-1); } } for (; i< 8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); printf ("_st[%d] %x %x %x %x\n", i,ptr->_hi2,ptr->_hi1,ptr->_lo2,ptr->_lo1); if (ptr->_hi2 != 0 && ptr->_hi1 != 0x5a5a && ptr->_lo2 != 0x5a5a5a5a && ptr->_lo1 != 0x5a5a5a5a) { printf ("***Error in this _st\n"); exit(-1); } } CONTEXT writableContext, *ctxt; if (KnobUseIargConstContext) { // need to copy the ctxt into a writable context PIN_SaveContext(context, &writableContext); ctxt = &writableContext; } else { ctxt = context; } /* set the x87 regs in the ctxt which is used to execute the originalFunction (via PIN_CallApplicationFunction) */ PIN_GetContextFPState(ctxt, fpContextFromPin); for (i=0; i< 8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); ptr->_hi2=0xacdcacdc; ptr->_hi1=0xacdcacdc; ptr->_lo2=0xacdcacdc; ptr->_lo1=0xacdcacdc; } fpContextFromPin->fxsave_legacy._mxcsr |= (0x200); // mask divide by zero PIN_SetContextFPState(ctxt, fpContextFromPin); // verify the setting worked for (i=0; i<8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); ptr->_hi2=0x0; ptr->_hi1=0x0; ptr->_lo2=0x0; ptr->_lo1=0x0; } PIN_GetContextFPState(ctxt, fpContextFromPin); for (i=0; i<8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); if (ptr->_hi2 != 0xacdcacdc || ptr->_hi2 != 0xacdcacdc || ptr->_lo2!= 0xacdcacdc || ptr->_lo1!= 0xacdcacdc ) { printf ("TOOL error1 in setting fp context in REPLACE_ReplacedX87Regs\n"); exit (-1); } } // call the originalFunction function with the xmm regs set from above printf("TOOL Calling replaced ReplacedX87Regs()\n"); fflush (stdout); PIN_CallApplicationFunction(ctxt, tid, CALLINGSTD_DEFAULT, originalFunction, PIN_PARG_END()); printf("TOOL Returned from replaced ReplacedX87Regs()\n"); fflush (stdout); if (executeAtAddr != 0) { for (i=0; i< 8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); ptr->_hi2=0xcacdcacd; ptr->_hi1=0xcacdcacd; ptr->_lo2=0xcacdcacd; ptr->_lo1=0xcacdcacd; } PIN_SetContextFPState(ctxt, fpContextFromPin); // verify the setting worked for (i=0; i<8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); ptr->_hi2=0x0; ptr->_hi1=0x0; ptr->_lo2=0x0; ptr->_lo1=0x0; } PIN_GetContextFPState(ctxt, fpContextFromPin); for (i=0; i<8; i++) { RAW32 *ptr = reinterpret_cast<RAW32 *>(&fpContextFromPin->fxsave_legacy._sts[i]._raw); if (ptr->_hi2 != 0xcacdcacd || ptr->_hi2 != 0xcacdcacd || ptr->_lo2!= 0xcacdcacd || ptr->_lo1!= 0xcacdcacd ) { printf ("TOOL error2 in setting fp context in REPLACE_ReplacedX87Regs\n"); exit (-1); } } // execute the application function ExecuteAtFunc with the xmm regs set PIN_SetContextReg(ctxt, REG_INST_PTR, executeAtAddr); printf("TOOL Calling ExecutedAtFunc\n"); fflush (stdout); PIN_ExecuteAt (ctxt); printf("TOOL returned from ExecutedAtFunc\n"); fflush (stdout); } }
VOID VerifyFpContext(ADDRINT pcval, CONTEXT * context) { //printf ("fpContextFromXsave %x FPSTATE_SIZE %d FPSTATE_ALIGNMENT %d\n", fpContextFromXsave, FPSTATE_SIZE, FPSTATE_ALIGNMENT); //fflush (stdout); Do_Xsave (fpContextFromXsave); //printf ("fpContextFromFxsave %x\n", fpContextFromFxsave); //fflush (stdout); Do_Fxsave (fpContextFromFxsave); PIN_SaveContext(context, &contextFromPin); FPSTATE *fpContextFromPin = reinterpret_cast<FPSTATE *> (( reinterpret_cast<ADDRINT>(fpContextSpaceForFpConextFromPin) + (FPSTATE_ALIGNMENT - 1)) & (-1*FPSTATE_ALIGNMENT)); unsigned char * ptr = (reinterpret_cast< unsigned char *>(fpContextFromPin))+ sizeof (FXSAVE); // set values after fxsave part of fp context - to verify that the deprecated call to PIN_GetContextFPState does NOT change these memset (ptr, 0xa5, sizeof(FPSTATE) - sizeof (FXSAVE)); PIN_GetContextFPState(&contextFromPin, reinterpret_cast<void *>(fpContextFromPin)); for (int i=0; i<sizeof(FPSTATE) - sizeof (FXSAVE); i++,ptr++) { if (*ptr != 0xa5) { printf ("**** ERROR: value set after FXSAVE part in deprecated PIN_GetContextFPState *ptr = %x (i %d)\n", *ptr, i); exit (-1); } } PIN_GetContextFPState(&contextFromPin, fpContextFromPin); ptr = (reinterpret_cast< unsigned char *>(fpContextFromPin))+ sizeof (FXSAVE); FPSTATE *fpContextFromPin1 = reinterpret_cast<FPSTATE *> (( reinterpret_cast<ADDRINT>(fpContextSpaceForFpConextFromPin1) + (FPSTATE_ALIGNMENT - 1)) & (-1*FPSTATE_ALIGNMENT)); PIN_GetContextFPState(&contextFromPin, fpContextFromPin1); // set values after fxsave part of fp context - to verify that the deprecated call to PIN_SetContextFPState does NOT change these unsigned char * ptr1 = (reinterpret_cast< unsigned char *>(fpContextFromPin1)) + sizeof (FXSAVE); memset (ptr1, 0xa5, sizeof(FPSTATE) - sizeof (FXSAVE)); PIN_SetContextFPState(&contextFromPin, reinterpret_cast<const void *>(fpContextFromPin1)); PIN_GetContextFPState(&contextFromPin, fpContextFromPin1); if (memcmp (ptr1, ptr, sizeof(FPSTATE) - sizeof (FXSAVE)) != 0) { printf ("**** ERROR: value set after FXSAVE part in deprecated PIN_SetContextFPState\n"); exit (-1); } if (!CompareFpContext (fpContextFromPin, fpContextFromFxsave, FALSE)) { fprintf (log_inl, "***ERROR in fxsave fp context\n"); printf ("***ERROR in fxsave fp context see file %s\n", KnobOutputFile.Value().c_str()); fflush (stdout); string s = disassemble ((pcval),(pcval)+15); fprintf (log_inl," %s\n", s.c_str()); exit (-1); } }