static VOID OnException(THREADID threadIndex, 
                        CONTEXT_CHANGE_REASON reason, 
                        const CONTEXT *ctxtFrom,
                        CONTEXT *ctxtTo,
                        INT32 info, 
                        VOID *v)
{
	if (!toolIsReadyForException && reason == CONTEXT_CHANGE_REASON_EXCEPTION)
	{
		fprintf (out, "See exception %d : info 0x%x from 0x%0x  but this is not the exception we want to replay\n", exceptionCount, info,
                 PIN_GetContextReg(ctxtFrom, REG_INST_PTR));
		return;
	}
    if (!foundReplayException)
    {
        fprintf (out, "Failed to instrument ReplayException!\n");
    }
    if (reason == CONTEXT_CHANGE_REASON_EXCEPTION)
    {
        if (exceptionCount++ == 0)
        {
            PIN_SaveContext (ctxtFrom, &savedFromContext);
            PIN_SaveContext (ctxtTo,   &savedToContext);
            savedReason = info;
        }
        fprintf (out, "See exception %d : info 0x%x from 0x%0x\n", exceptionCount, info,
                 PIN_GetContextReg(ctxtFrom, REG_INST_PTR));
        fflush(out);
        
        if (exceptionCount == 2)
        {
            // Check that the second exception is the same as the first, at least to a first approximation.
            if (info == savedReason && 
                PIN_GetContextReg(ctxtFrom, REG_INST_PTR) == PIN_GetContextReg(&savedFromContext, REG_INST_PTR))
            {
                fprintf (out, "Second exception looks like a replay, good!\n");
                fflush(out);
                exit(0);
            }
            else
            {
                fprintf (out, "Second exception does not look like a replay, BAD!\n");
                fflush(out);
                exit(1);
            }
        }
    }
}
Example #2
0
      /* Enable the snapshot engine. */
      void Snapshot::takeSnapshot(CONTEXT *ctx) {
        /* 1 - Unlock the engine */
        this->locked = false;

        /* 2 - Save current symbolic engine state */
        this->snapshotSymEngine = new triton::engines::symbolic::SymbolicEngine(*triton::api.getSymbolicEngine());

        /* 3 - Save current taint engine state */
        this->snapshotTaintEngine = new triton::engines::taint::TaintEngine(*triton::api.getTaintEngine());

        /* 4 - Save current set of nodes */
        this->nodesList = triton::api.getAllocatedAstNodes();

        /* 5 - Save current map of variables */
        this->variablesMap = triton::api.getAstVariableNodes();

        /* 6 - Save the Triton CPU state */
        #if defined(__x86_64__) || defined(_M_X64)
        this->cpu = new triton::arch::x86::x8664Cpu(*reinterpret_cast<triton::arch::x86::x8664Cpu*>(triton::api.getCpu()));
        #endif
        #if defined(__i386) || defined(_M_IX86)
        this->cpu = new triton::arch::x86::x86Cpu(*reinterpret_cast<triton::arch::x86::x86Cpu*>(triton::api.getCpu()));
        #endif

        /* 7 - Save Pin registers context */
        PIN_SaveContext(ctx, &this->pinCtx);
      }
Example #3
0
int REPLACE_Replaced(CONTEXT *context, THREADID tid, AFUNPTR func)
{
    int ret;

    printf("Calling replaced Replaced()\n");

    CONTEXT writableContext, *ctxt;
    if (KnobUseIargConstContext)
    { // need to copy the ctxt into a writable context
        PIN_SaveContext(context, &writableContext);
        ctxt = &writableContext;
    }
    else
    {
        ctxt = context;
    }

    PIN_SetContextReg(ctxt, scratchReg, 1);
    printf("REPLACE_Replaced: REG_INST_G0=0x%x\n",  PIN_GetContextReg(ctxt, scratchReg));

    PIN_CallApplicationFunction(ctxt, tid, CALLINGSTD_DEFAULT, func,
        PIN_PARG(int), &ret,
        PIN_PARG_END());
    
    printf("REPLACE_Replaced: REG_INST_G0=0x%x\n",  PIN_GetContextReg(ctxt, scratchReg));
    printf("Returning from replaced Replaced()\n");
    return ret;
}
static VOID printRegisterDiffs(THREADID tid, CONTEXT *ctx, UINT32 where)
{    
    threadState * s = &threadStates[tid];
    UINT32 seqNo    = s->iCount;
    CONTEXT * savedCtx = &s->context;

    // Save the context if this was the first instruction
    if (seqNo == 0)
        PIN_SaveContext(ctx, savedCtx);
    else
    {
        for (UINT32 i=0; i<sizeof(checkedRegisters)/sizeof(checkedRegisters[0]); i++)
        {
            REG r = checkedRegisters[i].regnum;
            ADDRINT newValue = PIN_GetContextReg(ctx, r);

            if (PIN_GetContextReg(savedCtx, r) != newValue)
            {
                if (where != 0)
                {
                    out << "*** Instrumentation (" << dec << where << ") caused a change ";
                }
                out << dec << seqNo << ": " << checkedRegisters[i].name << " = " << hex << UINT32(newValue) << endl;
                PIN_SetContextReg(savedCtx, r, newValue);
            }
        }
    }
}
Example #5
0
static BOOL DebugInterpreter(THREADID, CONTEXT *ctxt, const string &cmd, string *, VOID *)
{
    if (cmd == "checkpoint")
    {
        PIN_SaveContext(ctxt, &Registers);
        isCheckpointing = TRUE;
        return TRUE;
    }
    if (cmd == "restore")
    {
        PIN_SaveContext(&Registers, ctxt);
        MemLog.Restore();
        return TRUE;
    }
    return FALSE;
}
VOID VerifyContext(               
                ADDRINT pcval,
                CONTEXT * context)
{
    
    PIN_SaveContext(context, &contextAtVerify); 
    
    BOOL hadError = FALSE;
    if (!CompareContext (&contextAtVerify,&contextAtRecordFastCall))
    {
        fprintf (log_inl,"contextAtRecordFastCall ERROR\n");
        hadError = TRUE;
    }
    
    if (!CompareContext (&contextAtVerify,&contextAtRecordNonFastCall))
    {
        fprintf (log_inl,"contextAtRecordNonFastCall ERROR\n"); 
        hadError = TRUE;
    }
    if (hadError)
    {
        string s = disassemble ((pcval),(pcval)+15);
        fprintf (log_inl,"    %s\n", s.c_str());
        exit (-1);
    }
    
}
VOID RecordContext(
                UINT32 dummy1, UINT32 dummy2, UINT32 dummy3, UINT32 dummy4, 
                CONTEXT * context)
{
    PIN_SaveContext (context, &contextAtRecordNonFastCall);
    
}
Example #8
0
      /* Restore the snapshot. */
      void Snapshot::restoreSnapshot(CONTEXT *ctx) {

        if (this->mustBeRestore == false)
          return;

        /* 1 - Restore all memory modification. */
        for(auto i = this->memory.begin(); i != this->memory.end(); ++i){
          *(reinterpret_cast<char*>(i->first)) = i->second;
        }
        this->memory.clear();

        /* 2 - Delete unused expressions */
        auto currentExpressions     = triton::api.getSymbolicExpressions();
        auto snapshotExpressions    = this->snapshotSymEngine->getSymbolicExpressions();
        triton::__uint currentSize  = currentExpressions.size();
        triton::__uint snapshotSize = snapshotExpressions.size();
        for (auto i = currentExpressions.begin(); i != currentExpressions.end(); ++i) {
          if (snapshotExpressions.find(i->first) == snapshotExpressions.end())
            delete currentExpressions[i->first];
        }

        /* 3 - Delete unused variables */
        auto currentSymbolicVars   = triton::api.getSymbolicVariables();
        auto snapshotSymbolicVars  = this->snapshotSymEngine->getSymbolicVariables();
        currentSize                = currentSymbolicVars.size();
        snapshotSize               = snapshotSymbolicVars.size();
        for (auto i = currentSymbolicVars.begin(); i != currentSymbolicVars.end(); ++i) {
          if (snapshotSymbolicVars.find(i->first) == snapshotSymbolicVars.end())
            delete currentSymbolicVars[i->first];
        }

        /* 4 - Restore current symbolic engine state */
        *triton::api.getSymbolicEngine() = *this->snapshotSymEngine;

        /* 5 - Restore current taint engine state */
        *triton::api.getTaintEngine() = *this->snapshotTaintEngine;

        /* 6 - Restore current AST node state */
        triton::api.setAllocatedAstNodes(this->nodesList);

        /* 7 - Restore current variables map state */
        triton::api.setAstVariableNodes(this->variablesMap);

        /* 8 - Restore the Triton CPU state */
        #if defined(__x86_64__) || defined(_M_X64)
        *reinterpret_cast<triton::arch::x86::x8664Cpu*>(triton::api.getCpu()) = *this->cpu;
        #endif
        #if defined(__i386) || defined(_M_IX86)
        *reinterpret_cast<triton::arch::x86::x86Cpu*>(triton::api.getCpu()) = *this->cpu;
        #endif

        /* 9 - Restore Pin registers context */
        PIN_SaveContext(&this->pinCtx, ctx);

        this->mustBeRestore = false;
        PIN_UnlockClient();
        PIN_ExecuteAt(ctx);
      }
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));
    //printf ("fpContextFromPin %x\n", fpContextFromPin);
    //fflush (stdout);
    PIN_GetContextFPState(&contextFromPin, fpContextFromPin);

    
    BOOL hadError = FALSE;
    
    if (!CompareFpContext (fpContextFromPin, fpContextFromXsave, TRUE))
    {
        fprintf (log_inl, "***ERROR in xsave fp context\n");
        printf ("***ERROR in xsave 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);
    }

    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);
    }
    //printf ("verify success\n");
    //fflush (stdout);
    
}
Example #10
0
/* Enable the snapshot engine. */
void SnapshotEngine::takeSnapshot(const SymbolicEngine &currentSymEngine, const TaintEngine &currentTaintEngine, CONTEXT *ctx)
{
  /* 1 - Unlock the engine */
  this->locked = UNLOCKED;

  /* 2 - Save current symbolic engine state */
  this->snapshotSymEngine = new SymbolicEngine(currentSymEngine);

  /* 3 - Save current taint engine state */
  this->snapshotTaintEngine = new TaintEngine(currentTaintEngine);

  /* 4 - Save Pin registers context */
  PIN_SaveContext(ctx, &this->pinCtx);
}
VOID ReceiveContext (CONTEXT *ctxt)
{
    if (KnobGetIntContext || KnobGetPartOfIntContext)
    {
        GetIntRegsFromContext(ctxt);
    }
    if (KnobGetFpContext)
    {
        GetFpContextFromContext(ctxt);
    }
    if (!(KnobOnStackContextOnly || KnobGetSpillAreaContextOnly || !KnobCompareContexts))
    {
        PIN_SaveContext(ctxt, &contextAtReceive);
    }
}
Example #12
0
/* Restore the snapshot. */
void SnapshotEngine::restoreSnapshot(SymbolicEngine *currentSymEngine, TaintEngine *currentTaintEngine, CONTEXT *ctx) {

  if (this->mustBeRestore == false)
    return;

  /* 1 - Restore all memory modification. */
  list< std::pair<uint64, char> >::iterator i;
  for(i = this->memory.begin(); i != this->memory.end(); ++i){
    *(reinterpret_cast<char*>(i->first)) = i->second;
  }
  this->memory.clear();

  /* 2.1 - Delete unused expressions */
  std::vector<SymbolicExpression *> currentExpressions = currentSymEngine->getExpressions();

  uint64 currentSize  = currentExpressions.size();
  uint64 snapshotSize = this->snapshotSymEngine->getExpressions().size();
  for (uint64 index = snapshotSize; index < currentSize; index++) {
    delete currentExpressions[index];
  }

  /* 2.2 - Delete unused variables */
  std::vector<SymbolicVariable *> currentSymbolicVars = currentSymEngine->getSymVars();

  currentSize  = currentSymbolicVars.size();
  snapshotSize = this->snapshotSymEngine->getSymVars().size();
  for (uint64 index = snapshotSize; index < currentSize; index++) {
    delete currentSymbolicVars[index];
  }

  /* 2.3 - Restore current symbolic engine state */
  *currentSymEngine = *this->snapshotSymEngine;

  /* 3 - Restore current taint engine state */
  *currentTaintEngine = *this->snapshotTaintEngine;

  /* 4 - Delete unused AST nodes */
  smt2lib::freeUnusedNodes(this->nodesList);

  /* 5 - Restore Pin registers context */
  PIN_SaveContext(&this->pinCtx, ctx);

  this->mustBeRestore = false;
  PIN_UnlockClient();
  PIN_ExecuteAt(ctx);
}
Example #13
0
/* Restore the snapshot. */
void SnapshotEngine::restoreSnapshot(SymbolicEngine *currentSymEngine, TaintEngine *currentTaintEngine, CONTEXT *ctx)
{
  /* 1 - Restore all memory modification. */
  list< std::pair<uint64_t, char> >::iterator i;
  for(i = this->memory.begin(); i != this->memory.end(); ++i){
    *(reinterpret_cast<char*>(i->first)) = i->second;
  }
  this->memory.clear();

  /* 2 - Restore current symbolic engine state */
  *currentSymEngine = *this->snapshotSymEngine;

  /* 3 - Restore current taint engine state */
  *currentTaintEngine = *this->snapshotTaintEngine;

  /* 4 - Restore Pin registers context */
  PIN_SaveContext(&this->pinCtx, ctx);

  PIN_ExecuteAt(ctx);
}
Example #14
0
// This function is called whenever Pin wants to report a breakpoint event to the
// debugger.
//
static BOOL InterceptBreakpoint(THREADID tid, DEBUGGING_EVENT eventType, CONTEXT *ctxt, VOID *)
{
    if (eventType != DEBUGGING_EVENT_BREAKPOINT)
    {
        std::cout << "FAILURE: Wrong event type in InterceptBreakpoint()" << std::endl;
        std::exit(1);
    }

    ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR);
    RTN rtn = RTN_FindByAddress(pc);

    // When the application triggers the breakpoint in Breakpoint1(), squash the breakpoint
    // and roll the application back to the Checkpoint() call.  The application will NOT stop
    // at the breakpoint, and it will immediately resume from Checkpoint().
    //
    if (rtn != RTN_Invalid() && RTN_Name(rtn) == "Breakpoint1")
    {
        std::cout << "Intercepting breakpoint #1 at 0x" << std::hex << pc << std::endl;
        PIN_SaveContext(&SavedContext, ctxt);
        PIN_SetContextReg(ctxt, REG_GAX, 1);
        MemLog.Restore();
        IsCheckpointing = FALSE;
        return FALSE;
    }

    // When the application triggers the breakpoint in Breakpoint2(), do not squash the
    // breakpoint, but change the return value from Breakpoint2().  The application will stop
    // in the debugger, and the debugger should see the modified return value.
    //
    if (rtn != RTN_Invalid() && (RTN_Name(rtn) == "Breakpoint2" || RTN_Name(rtn) == "Breakpoint2Label"))
    {
        std::cout << "Intercepting breakpoint #2 at 0x" << std::hex << pc << std::endl;
        std::cout << "RTN=" << RTN_Name(rtn) << std::endl;
        PIN_SetContextReg(ctxt, REG_GAX, 1);
        return TRUE;
    }

    std::cout << "Skipping breakpoint at 0x" << std::hex << pc << ", RTN=" << RTN_Name(rtn) << std::endl;
    return TRUE;
}
static VOID OnSignal(THREADID, CONTEXT_CHANGE_REASON reason, const CONTEXT *, CONTEXT *to, INT32 sig, VOID *)
{
    if (reason == CONTEXT_CHANGE_REASON_SIGRETURN)
        return;

    SignalCount++;
    switch (SignalCount)
    {
    case 1:
        std::cout << "Notified of real signal, recording" << std::endl;
        PIN_SaveContext(to, &RecordedContext);
        RecordedSignal = sig;
        break;

    case 2:
        std::cout << "Notified of first replayed signal" << std::endl;
        if (reason != CONTEXT_CHANGE_REASON_SIGNAL)
        {
            std::cout << "Wrong 'reason' in signal notification, expected " << static_cast<int>(CONTEXT_CHANGE_REASON_SIGNAL)
                << " (CONTEXT_CHANGE_REASON_SIGNAL), but got " << reason << std::endl;
            std::exit(1);
        }
        break;

    case 3:
        std::cout << "Notified of second replayed signal" << std::endl;
        if (reason != CONTEXT_CHANGE_REASON_FATALSIGNAL)
        {
            std::cout << "Wrong 'reason' in signal notification" << std::endl;
            std::exit(1);
        }
        break;

    default:
        std::cout << "Notified of too many signals" << std::endl;
        std::exit(1);
    }
}
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);
    }
}
Example #17
0
static void OnCheckpoint(CONTEXT *ctxt)
{
    PIN_SaveContext(ctxt, &SavedContext);
    IsCheckpointing = TRUE;
}
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);
    }
}
VOID PIN_FAST_ANALYSIS_CALL RecordContextFastCall(
                CONTEXT * context)
{
    PIN_SaveContext (context, &contextAtRecordFastCall);  
}