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; }
VOID ThreadStart( THREADID tid, CONTEXT *ctxt, INT32 flags, VOID *v) { ADDRINT rsp = PIN_GetContextReg(ctxt, REG_STACK_PTR); ADDRINT eip = PIN_GetContextReg(ctxt, REG_INST_PTR); OutFile << dec << tid << hex<< " NTH " << eip << " " << rsp << endl; }
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); } } } }
static void CheckPcBefore (ADDRINT pcExpectedInstPtr, CONTEXT *ctxt, CONTEXT *constCtxt, ADDRINT pcInstPtr, const char *dis) { ADDRINT pcCtxt = PIN_GetContextReg(ctxt, REG_INST_PTR); ADDRINT pcConstCtxt = PIN_GetContextReg(constCtxt, REG_INST_PTR); if (pcConstCtxt != pcCtxt) { haveError = TRUE; Out << "***Error3 CONTEXT pc is 0x" << std::hex << pcCtxt << " at IPOINT_BEFORE " << " is not equal to CONST_CONTEXT pc 0x" << std::hex << pcConstCtxt << std::endl; } if (pcCtxt != pcExpectedInstPtr) { haveError = TRUE; Out << "***Error3 CONTEXT pc is 0x" << std::hex << pcCtxt << " at IPOINT_BEFORE " << ", but expected 0x" << std::hex << pcExpectedInstPtr << ". PC of INS is 0x" << std::hex << pcExpectedInstPtr << ": " << dis << std::endl; } if (pcInstPtr != pcExpectedInstPtr) { haveError = TRUE; Out << "***Error3 INST_PTR pc is 0x" << std::hex << pcInstPtr << " at IPOINT_BEFORE " << ", but expected 0x" << std::hex << pcExpectedInstPtr << ": " << dis << std::endl; } }
static BOOL Intercept(THREADID tid, DEBUGGING_EVENT eventType, CONTEXT *ctxt, VOID *) { if (eventType == DEBUGGING_EVENT_BREAKPOINT) { // When the child thread reaches the breakpoint in Breakpoint(), wait for the main // thread to reach the One() function. If the main thread is not there yet, squash the // breakpoint and move the PC back to the start of the Breakpoint() function. This will // delay a while and then re-trigger the breakpoint. // ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); if (pc == BreakpointLocation && !AllowBreakpoint) { PIN_SetContextReg(ctxt, REG_INST_PTR, BreakpointFunction); GetLock(&Lock, 1); std::cout << "Squashing breakpoint at 0x" << std::hex << pc << " on thread " << std::dec << tid << std::endl; ReleaseLock(&Lock); return FALSE; } GetLock(&Lock, 1); std::cout << "Stopping at breakpoint at 0x" << std::hex << pc << " on thread " << std::dec << tid << std::endl; ReleaseLock(&Lock); return TRUE; } if (eventType == DEBUGGING_EVENT_ASYNC_BREAK) { // When the child thread triggers the breakpoint, we should be at the One() function. // Change the PC to the Two() function, which is the point of this test. We want to // make sure Pin properly handles the change of PC in this case. // ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); if (pc == OneFunction) { PIN_SetContextReg(ctxt, REG_INST_PTR, TwoFunction); GetLock(&Lock, 1); std::cout << "Changing ASYNC BREAK PC to Two() on thread " << std::dec << tid << std::endl; ReleaseLock(&Lock); return TRUE; } // If the PC is not at the One() function, the child thread has probably hit some breakpoint // other than the one at Breakpoint(). (E.g. an internal breakpoint set by GDB.) Don't // change the PC in such a case. // GetLock(&Lock, 1); std::cout << "ASYNC_BREAK at 0x" << std::hex << pc << " on thread " << std::dec << tid << std::endl; ReleaseLock(&Lock); return TRUE; } GetLock(&Lock, 1); std::cout << "FAILURE: Unexpected debugging event type" << std::endl; ReleaseLock(&Lock); std::exit(1); }
/* * SyscallEntry * Calls Sysbefore - syscall processor */ VOID SyscallEntry(THREADID threadIndex, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID *v) { SysBefore(PIN_GetContextReg(ctxt, REG_INST_PTR), PIN_GetSyscallNumber(ctxt, std), PIN_GetSyscallArgument(ctxt, std, 0), PIN_GetSyscallArgument(ctxt, std, 1), PIN_GetSyscallArgument(ctxt, std, 2), PIN_GetSyscallArgument(ctxt, std, 3), PIN_GetSyscallArgument(ctxt, std, 4), PIN_GetSyscallArgument(ctxt, std, 5), PIN_GetContextReg(ctxt,REG_STACK_PTR)); }
static VOID After1WithContext (ADDRINT ip, ADDRINT repInsAddr, CONTEXT * ctxt, CONTEXT *constCtxt, ADDRINT *constRefToIp ) { ADDRINT expectedIpAfter; numCallsToAfter1WithContext++; printf ("***After1WithContext# %d repInsAddr %p ip %p\n",//*constRefToIp %p\n", numCallsToAfter1WithContext, (char *)repInsAddr, (char *)ip //,(char *)constRefToIp, //(char *)(*constRefToIp) ); if (numCallsToAfter1WithContext == 2) { // see "Test different string comparison" in rep_ip_at_ipoint_after_app.c expectedIpAfter = repInsAddr+GetInstructionLength(repInsAddr); } else { expectedIpAfter = repInsAddr; } if (ip != *constRefToIp) { printf ("Unexpcted diff between ip and *constRefToIp\n"); exit (1); } if (PIN_GetContextReg( ctxt, REG_INST_PTR )!=expectedIpAfter) { printf (" After1WithContext Unexpected IP in ctxt %p\n", (char *)PIN_GetContextReg( ctxt, REG_INST_PTR )); exit (1); } if (PIN_GetContextReg( constCtxt, REG_INST_PTR )!=expectedIpAfter) { printf (" After1WithContext Unexpected IP in constCtxt %p\n", (char *)PIN_GetContextReg( constCtxt, REG_INST_PTR )); exit (1); } if (expectedIpAfter!=ip) { printf (" After1WithContext Unexpected IP from REG_VALUE REG_INST_PTR %p\n", (char *)ip); exit (1); } }
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); } } } }
VOID doPause(VOID * arg) { for (int i = 0; i < TIMES; i++) { while (stopFlag == false) { PIN_Sleep(10); } stopFlag = false; printf("Threads to be stopped by internal thread %u\n", intTid); fflush(stdout); if (PIN_StopApplicationThreads(intTid)) { UINT32 nThreads = PIN_GetStoppedThreadCount(); printf("Threads stopped by internal thread %u : %u\n", intTid, nThreads); fflush(stdout); for (UINT32 index = 0; index < nThreads; index++) { THREADID tid = PIN_GetStoppedThreadId(index); const CONTEXT * ctxt = PIN_GetStoppedThreadContext(tid); printf(" Thread %u, IP = %llx, icount = %llu\n", tid, (long long unsigned int)PIN_GetContextReg(ctxt, REG_INST_PTR), icounter[tid]); } PIN_ResumeApplicationThreads(intTid); printf("Threads resumed by internal thread %u\n", intTid); fflush(stdout); } } return; }
// - retrive the stack base address static VOID OnThreadStart(THREADID, CONTEXT *ctxt, INT32, VOID *){ ADDRINT stackBase = PIN_GetContextReg(ctxt, REG_STACK_PTR); FilterHandler *filterH = FilterHandler::getInstance(); filterH->setStackBase(stackBase); }
// - retrive the stack base address static VOID OnThreadStart(THREADID, CONTEXT *ctxt, INT32, VOID *){ ADDRINT stackBase = PIN_GetContextReg(ctxt, REG_STACK_PTR); ProcInfo *pInfo = ProcInfo::getInstance(); pInfo->addThreadStackAddress(stackBase); pInfo->addThreadTebAddress(); //MYINFO("-----------------a NEW Thread started!--------------------\n"); }
PostPatchFn PatchTimeoutSyscall(PrePatchArgs args) { if (SkipTimeoutVirt(args)) return NullPostPatch; int syscall = PIN_GetSyscallNumber(args.ctxt, args.std); assert_msg(syscall == SYS_futex || syscall == SYS_epoll_wait || syscall == SYS_epoll_pwait || syscall == SYS_poll, "Invalid timeout syscall %d", syscall); FutexInfo fi = {0, 0}; if (syscall == SYS_futex) fi = PrePatchFutex(args.tid, args.ctxt, args.std); if (PrePatchTimeoutSyscall(args.tid, args.ctxt, args.std, syscall)) { ADDRINT prevIp = PIN_GetContextReg(args.ctxt, REG_INST_PTR); ADDRINT timeoutArgVal = PIN_GetSyscallArgument(args.ctxt, args.std, getTimeoutArg(syscall)); return [syscall, prevIp, timeoutArgVal, fi](PostPatchArgs args) { if (PostPatchTimeoutSyscall(args.tid, args.ctxt, args.std, syscall, prevIp, timeoutArgVal)) { return PPA_USE_NOP_PTRS; // retry } else { if (syscall == SYS_futex) PostPatchFutex(args.tid, fi, args.ctxt, args.std); return PPA_USE_JOIN_PTRS; // finish } }; } else { if (syscall == SYS_futex) { return [fi](PostPatchArgs args) { PostPatchFutex(args.tid, fi, args.ctxt, args.std); return PPA_NOTHING; }; } else { return NullPostPatch; } } }
// this function verifies that the xmm regs in the ctxtFrom are as they were set in the app just before the // exception occurs. Then it sets the xmm regs in the ctxtTo to a different value, finally it causes the // execution to continue in the application function DumpXmmRegsAtException static void OnException(THREADID threadIndex, CONTEXT_CHANGE_REASON reason, const CONTEXT *ctxtFrom, CONTEXT *ctxtTo, INT32 info, VOID *v) { if (CONTEXT_CHANGE_REASON_SIGRETURN == reason || CONTEXT_CHANGE_REASON_APC == reason || CONTEXT_CHANGE_REASON_CALLBACK == reason || CONTEXT_CHANGE_REASON_FATALSIGNAL == reason || ctxtTo == NULL) { // don't want to handle these return; } fprintf (stdout, "TOOL OnException callback\n"); fflush (stdout); //PIN_SaveContext(ctxtFrom, ctxtTo); CheckAndSetFpContextXmmRegs(ctxtFrom, ctxtTo); // call the application function with the ctxtTo context #ifdef TARGET_IA32E PIN_SetContextReg(ctxtTo, REG_RIP, dumpXmmRegsAtExceptionAddr); // take care of stack alignment since tool is redirecting execution flow to function ADDRINT curSp = PIN_GetContextReg(ctxtTo, REG_RSP); INT32 currentAlignment = curSp % 16; PIN_SetContextReg(ctxtTo, REG_RSP, curSp - GetStackAdjustmentForRedirectionToFunction(currentAlignment)); #else PIN_SetContextReg(ctxtTo, REG_EIP, dumpXmmRegsAtExceptionAddr); #endif }
// There is no verification on the validity of the ID. uint64 PINContextHandler::getFlagValue(uint64 TritFlagID) const { uint64 rflags; REG reg = safecast(PINConverter::convertTritonReg2DBIReg(ID_RFLAGS)); if (!REG_valid(reg)) throw std::runtime_error("Error: getFlagValue() - Invalid PIN register id."); rflags = PIN_GetContextReg(this->_ctx, reg); switch (TritFlagID){ case ID_AF: return (rflags >> 4) & 1; case ID_CF: return (rflags & 1); case ID_DF: return (rflags >> 10) & 1; case ID_IF: return (rflags >> 9) & 1; case ID_OF: return (rflags >> 11) & 1; case ID_PF: return (rflags >> 2) & 1; case ID_SF: return (rflags >> 7) & 1; case ID_TF: return (rflags >> 8) & 1; case ID_ZF: return (rflags >> 6) & 1; default: throw std::runtime_error("Error: getFlagValue() - Invalid Flag id."); } return 0; }
VOID OnIns(THREADID tid, #if defined(TARGET_IA32) || defined(TARGET_IA32E) CONTEXT *ctxt, #endif ADDRINT g0, ADDRINT g1, ADDRINT g2, ADDRINT g3, ADDRINT g4, ADDRINT g5, ADDRINT g6, ADDRINT g7, ADDRINT g8, ADDRINT g9) { ADDRINT gx[10]; gx[0] = g0; gx[1] = g1; gx[2] = g2; gx[3] = g3; gx[4] = g4; gx[5] = g5; gx[6] = g6; gx[7] = g7; gx[8] = g8; gx[9] = g9; for (UINT32 r = 0; r <= 9; r++) { ADDRINT expect = BaseValue + tid + r; if (expect != gx[r]) Error("on IARG_REG_VALUE", tid, r, expect, gx[r]); #if defined(TARGET_IA32) || defined(TARGET_IA32E) ADDRINT val = PIN_GetContextReg(ctxt, REG(REG_INST_G0 + r)); if (expect != val) Error("on IARG_CONTEXT", tid, r, expect, val); #endif } }
static VOID SyscallEntry(THREADID threadIndex, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID *v) { if (PIN_GetSyscallNumber(ctxt, std) != SYS_sysarch) return; ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); ADDRINT op = PIN_GetSyscallArgument(ctxt, std, 0); ADDRINT addr = PIN_GetSyscallArgument(ctxt, std, 1); ADDRINT value = 0; if (op == AMD64_SET_FSBASE || op == AMD64_SET_GSBASE) { if (PIN_SafeCopy(&value, Addrint2VoidStar(addr), sizeof(ADDRINT)) != sizeof(ADDRINT)) { Out << Header(threadIndex, pc) << "Failed to read actual TLS pointer" << endl; } } else { // Remember the location where to write the segment register in REG_INST_G0 PIN_SetContextReg(ctxt, REG_INST_G0, addr); value = addr; } Out << Header(threadIndex, pc) << "sysarch(" << SysArchFunc(op) << ", 0x" << std::hex << value << ")" << std::endl; }
static VOID ThreadExitCallback(THREADID tid, const CONTEXT *ctxt, INT32 code, VOID * v) { cerr << "Thread " << tid << " terminated (" << code <<")\n"; if (ctxt) { cerr << "Thread " << tid << " IP: " << hex << PIN_GetContextReg(ctxt, REG_INST_PTR) << dec << "\n"; } }
std::string dumpContext(CONTEXT* ctxt) { std::stringstream ss; ss << "eax = " << setw(8) << hex << PIN_GetContextReg(ctxt, REG_EAX) << " " << "ebx = " << setw(8) << hex << PIN_GetContextReg(ctxt, REG_EBX) << " " << "ecx = " << setw(8) << hex << PIN_GetContextReg(ctxt, REG_ECX) << " " << "edx = " << setw(8) << hex << PIN_GetContextReg(ctxt, REG_EDX) << " " << "esi = " << setw(8) << hex << PIN_GetContextReg(ctxt, REG_ESI) << " " << "edi = " << setw(8) << hex << PIN_GetContextReg(ctxt, REG_EDI) << std::endl << "eip = " << setw(8) << hex << PIN_GetContextReg(ctxt, REG_EIP) << " " << "esp = " << setw(8) << hex << PIN_GetContextReg(ctxt, REG_ESP) << " " << "ebp = " << setw(8) << hex << PIN_GetContextReg(ctxt, REG_EBP) << " " << "eflags = " << setw(8) << hex << PIN_GetContextReg(ctxt, REG_EFLAGS); return ss.str(); }
/* * Pin calls this function to get the value of an emulated register. */ static VOID GetReg(unsigned toolRegId, THREADID tid, CONTEXT *ctxt, VOID *data, VOID *) { PrintEmulated(); switch (toolRegId) { case EMULATED_REG_RCX: { ADDRINT *val = static_cast<ADDRINT *>(data); *val = PIN_GetContextReg(ctxt, REG_RCX); break; } case EMULATED_REG_RSP: { ADDRINT *val = static_cast<ADDRINT *>(data); *val = PIN_GetContextReg(ctxt, REG_RSP); break; } case EMULATED_REG_FPSW: { UINT32 *val = static_cast<UINT32 *>(data); *val = static_cast<UINT32>(PIN_GetContextReg(ctxt, REG_FPSW)); break; } case EMULATED_REG_ST0: { FPSTATE fpstate; PIN_GetContextFPState(ctxt, &fpstate); std::memcpy(data, &fpstate.fxsave_legacy._sts[0], 10); break; } case EMULATED_REG_XMM0: { FPSTATE fpstate; PIN_GetContextFPState(ctxt, &fpstate); std::memcpy(data, &fpstate.fxsave_legacy._xmms[0], 16); break; } default: { ASSERTX(0); break; } } }
static VOID ContextChangeCallback(THREADID tid, CONTEXT_CHANGE_REASON reason, const CONTEXT *from, CONTEXT *to, INT32 info, VOID *v) { cerr << "Thread " << tid << " context change " << reason << " info " << info << "\n"; if (from) { cerr << "Thread " << tid << " IP: " << hex << PIN_GetContextReg(from, REG_INST_PTR) << dec << "\n"; } }
VOID ThreadFini(THREADID tid, const CONTEXT *ctxt, INT32 code, VOID *v) { // When the thread exits, accumulate the thread's dynamic instruction // count into the total. // GetLock(&Lock, tid+1); TotalCount += PIN_GetContextReg(ctxt, ScratchReg); ReleaseLock(&Lock); }
static VOID SyscallExit(THREADID threadIndex, CONTEXT *ctxt, SYSCALL_STANDARD std, VOID *v) { ADDRINT addr = PIN_GetContextReg(ctxt, REG_INST_G0); if (!addr) return; // Reset REG_INST_G0 PIN_SetContextReg(ctxt, REG_INST_G0, 0); ADDRINT pc = PIN_GetContextReg(ctxt, REG_INST_PTR); ADDRINT ret = PIN_GetSyscallReturn(ctxt, std); ADDRINT value = 0; if (ret == (ADDRINT)-1 || PIN_SafeCopy(&value, Addrint2VoidStar(addr), sizeof(ADDRINT)) != sizeof(ADDRINT)) { Out << Header(threadIndex, pc) << "Failed to read actual TLS pointer" << endl; } Out << Header(threadIndex, pc) << "sysarch returned: " << ", 0x" << std::hex << value << "" << std::endl; }
static VOID OnThreadFini(THREADID tid, const CONTEXT *ctxt, INT32, VOID *) { if (tid == 0) return; ADDRINT addrInfo = PIN_GetContextReg(ctxt, RegThreadInfo); THREAD_INFO *info = reinterpret_cast<THREAD_INFO *>(addrInfo); delete info; }
// There is no verification on the validity of the ID. uint64 PINContextHandler::getRegisterValue(uint64 TritRegID) const { REG reg = safecast(PINConverter::convertTritonReg2DBIReg(TritRegID)); if (!REG_valid(reg) || (TritRegID >= ID_XMM0 && TritRegID <= ID_XMM15)) throw std::runtime_error("Error: getRegisterValue() - Invalid PIN register id."); return PIN_GetContextReg(this->_ctx, reg); }
/* Save the current registers inside the struct You can fine the macro fo the registers at: https://software.intel.com/sites/landingpage/pintool/docs/49306/Pin/html/group__REG__CPU__IA32.html */ void ProcInfo::setCurrRegContext(CONTEXT * ctx){ this->reg_curr_context.eax = PIN_GetContextReg(ctx,REG_EAX); this->reg_curr_context.ebx = PIN_GetContextReg(ctx,REG_EBX); this->reg_curr_context.ecx = PIN_GetContextReg(ctx,REG_ECX); this->reg_curr_context.edx = PIN_GetContextReg(ctx,REG_EDX); this->reg_curr_context.esp = PIN_GetContextReg(ctx,REG_ESP); this->reg_curr_context.ebp = PIN_GetContextReg(ctx,REG_EBP); this->reg_curr_context.edi = PIN_GetContextReg(ctx,REG_EDI); this->reg_curr_context.esi = PIN_GetContextReg(ctx,REG_ESI); }
/* * thread finish callback (analysis function) * * free the space for the syscall context and VCPUs * * @tid: thread id * @ctx: CPU context * @code: OS specific termination code for the thread * @v: callback value */ static void thread_free(THREADID tid, const CONTEXT *ctx, INT32 code, VOID *v) { /* get the thread context */ thread_ctx_t *tctx = (thread_ctx_t *) PIN_GetContextReg(ctx, thread_ctx_ptr); /* free the allocated space */ free(tctx); }
VOID ThreadFini(THREADID tid, const CONTEXT *ctxt, INT32 code, VOID *v) { for (UINT32 r = 0; r <= 9; r++) { ADDRINT val = PIN_GetContextReg(ctxt, REG(REG_INST_G0 + r)); ADDRINT expect = BaseValue + tid + r; if (expect != val) Error("at thread exit", tid, r, expect, val); } }
BOOL SigFunc(THREADID tid, INT32 sig, CONTEXT *ctxt, BOOL hasHandler, const EXCEPTION_INFO *pExceptInfo, void *dummy) { ADDRINT address = PIN_GetContextReg(ctxt, REG_INST_PTR); cout << "Thread " << tid << ": Tool got signal " << sig << " at PC " << hex << address << dec << "\n"; numSignalsReceived++; if (numSignalsReceived == (NUM_SEGVS/2)) { // Invalidate this instruction in code cache so it will be reinstrumented cout << "invalidating after " << numSignalsReceived << endl; CODECACHE_InvalidateRange(address, address + 20); } return (TRUE); // skip to next instruction }
unsigned int PinExecutionContext::getRegisterValue(enum eRegister reg, unsigned long *value) const { REG pin_register; ADDRINT content; unsigned int result; result = mapRegisterToPin(reg, &pin_register); if (result == 0) { content = PIN_GetContextReg(pin_context, pin_register); *value = (unsigned long) content; return 0; } else { return result; } }
static void CheckPcAtBranchTarget(ADDRINT branchTargetAddr, ADDRINT pcExpectedInstPtr, CONTEXT *ctxt, CONTEXT *constCtxt, ADDRINT pcInstPtr, const char *dis) { ADDRINT pcCtxt = PIN_GetContextReg(ctxt, REG_INST_PTR); ADDRINT pcConstCtxt = PIN_GetContextReg(constCtxt, REG_INST_PTR); if (pcConstCtxt != pcCtxt) { haveError = TRUE; Out << "***Error2 CONTEXT pc is 0x" << std::hex << pcCtxt << " at IPOINT_TAKEN_BRANCH " << " is not equal to CONST_CONTEXT pc 0x" << std::hex << pcConstCtxt << std::endl; } if (pcCtxt != branchTargetAddr) { haveError = TRUE; Out << "***Error2 CONTEXT pc is 0x" << std::hex << pcCtxt << " at IPOINT_TAKEN_BRANCH " << ", but expected 0x" << std::hex << branchTargetAddr << ". PC of INS is 0x" << std::hex << pcExpectedInstPtr << ": " << dis << std::endl; } if (pcInstPtr != pcExpectedInstPtr) { haveError = TRUE; Out << "***Error2 INST_PTR pc is 0x" << std::hex << pcInstPtr << " at IPOINT_TAKEN_BRANCH " << ", but expected 0x" << std::hex << pcExpectedInstPtr << ": " << dis << std::endl; } if (branchTargetAddrBefore != branchTargetAddr) { haveError = TRUE; Out << "***Error2 branchTargetAddr received from IPOINT_BEFORE instrumentation at pc 0x" << std::hex << pcInstPtr << " is " << std::hex << branchTargetAddrBefore << ", is different form branchTargetAddr at IOPINT_TAKEN_BRANCH 0x" << std::hex << branchTargetAddr << ": " << dis << std::endl; } }