static VOID InstrumentInstruction(INS ins, VOID *) { if (INS_IsPredicated(ins)) { INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)returnArg, IARG_EXECUTING, IARG_END); INS_InsertThenCall(ins, IPOINT_BEFORE, (AFUNPTR)increment, IARG_ADDRINT, ADDRINT(&predicatedTrueCount), IARG_END); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)add, IARG_ADDRINT, ADDRINT(&predicatedTrueCountArg), IARG_EXECUTING, IARG_END); // CountOp = TRUE; } if (INS_HasRealRep(ins)) { INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)returnArg, IARG_FIRST_REP_ITERATION, IARG_END); INS_InsertThenCall(ins, IPOINT_BEFORE, (AFUNPTR)increment, IARG_ADDRINT, ADDRINT(&firstRepCount), IARG_END); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)add, IARG_ADDRINT, ADDRINT(&firstRepCountArg), IARG_FIRST_REP_ITERATION, IARG_END); } if (INS_IsBranch(ins)) { UINT32 op = INS_Opcode(ins); INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)returnArg, IARG_BRANCH_TAKEN, IARG_END); INS_InsertThenCall(ins, IPOINT_BEFORE, (AFUNPTR)increment, IARG_ADDRINT, ADDRINT(&(branchCounts[op].taken)), IARG_END); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)add, IARG_ADDRINT, ADDRINT(&(branchCounts[op].takenArg)), IARG_BRANCH_TAKEN, IARG_END); } }
VOID Trace(TRACE trace, VOID *v) { static BOOL programStart = TRUE; if (programStart) { programStart = FALSE; next_pc = (void*)INS_Address(BBL_InsHead(TRACE_BblHead(trace))); } for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { // check BBL entry PC INS_InsertCall( BBL_InsHead(bbl), IPOINT_BEFORE, (AFUNPTR)CheckPc, IARG_INST_PTR, IARG_END); INS tail = BBL_InsTail(bbl); if (INS_IsBranchOrCall(tail)) { // record taken branch targets INS_InsertCall( tail, IPOINT_BEFORE, AFUNPTR(RecordPc), IARG_INST_PTR, IARG_BRANCH_TARGET_ADDR, IARG_BRANCH_TAKEN, IARG_END); } if (INS_HasFallThrough(tail)) { // record fall-through INS_InsertCall( tail, IPOINT_AFTER, (AFUNPTR)RecordPc, IARG_INST_PTR, IARG_FALLTHROUGH_ADDR, IARG_BOOL, TRUE, IARG_END); } #if defined(TARGET_IA32) || defined(TARGET_IA32E) if (INS_IsSysenter(tail) || INS_HasRealRep(tail)) { // sysenter on x86 has some funny control flow that we can't correctly verify for now // Genuinely REP prefixed instructions are also odd, they appear to stutter. INS_InsertCall(tail, IPOINT_BEFORE, (AFUNPTR)Skip, IARG_END); } #endif } }
// Instrument individual instructions. // Specific instrumentation for REP prefixed instructions. static VOID InstrumentInstruction(INS ins, VOID *) { if (INS_IsBranchOrCall(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ClearPrevRep, IARG_END); } // We're only interested in REP prefixed instructions. if (!INS_HasRealRep(ins)) return; UINT32 opIdx = opcodeIndex(INS_Opcode(ins)); insertRepExecutionCountInstrumentation(ins, opIdx); // If requested also add the instrumentation to count memory references. if (KnobCountMemory) insertRepMemoryCountInstrumentation (ins, opIdx); if (KnobAddresses) insertRepMemoryTraceInstrumentation (ins, opIdx); }
static VOID InstrumentInstruction(INS ins, VOID *v) { if (!repAppStarted) return; if (INS_HasRealRep(ins)) { if (INS_Address(ins)!=repAddress) { numInstrumentedRepInss++; repAddress = INS_Address(ins); } printf ("Instrument rep# %d at %p: %s\n", numInstrumentedRepInss, (char *)INS_Address(ins), INS_Disassemble(ins).c_str()); switch (numInstrumentedRepInss) { case 1: DoInstrumentation1(ins); break; case 2: DoInstrumentation2(ins); break; case 3: DoInstrumentation3(ins); break; case 4: DoInstrumentation4(ins); break; case 5: DoInstrumentation5(ins); break; case 6: DoInstrumentation6(ins); break; case 7: DoInstrumentation7(ins); break; default: break; } } }
VOID Instruction(INS ins, VOID *v) { UINT32 where = 0; if (INS_Opcode(ins) == XED_ICLASS_FNOP) { instrumenting = !instrumenting; } if (!instrumenting) return; #if (0) INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)printRegisterDiffs, IARG_THREAD_ID, IARG_CONTEXT, IARG_UINT32, where++, IARG_END); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)printInstruction, IARG_THREAD_ID, IARG_ADDRINT, VoidStar2Addrint(formatInstruction(ins)), IARG_END); #endif INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)printRegisterDiffs, IARG_THREAD_ID, IARG_CONTEXT, IARG_UINT32, where++, IARG_END); // Find string ops only. if (INS_IsStringop(ins)) { for (UINT32 bit =0; bit < 5; bit++) { INS_InsertIfCall (ins, IPOINT_AFTER, (AFUNPTR)predicate, IARG_UINT32, bit, IARG_INST_PTR, IARG_END); INS_InsertThenCall (ins, IPOINT_AFTER, (AFUNPTR)addCount,IARG_UINT32, bit, IARG_END); } INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)printRegisterDiffs, IARG_THREAD_ID, IARG_CONTEXT, IARG_UINT32, where++, IARG_END); INS_InsertCall (ins, IPOINT_BEFORE, (AFUNPTR)countInst, IARG_UINT32, 0, IARG_END); INS_InsertCall (ins, IPOINT_AFTER, (AFUNPTR)countInst, IARG_UINT32, 1, IARG_END); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)printRegisterDiffs, IARG_THREAD_ID, IARG_CONTEXT, IARG_UINT32, where++, IARG_END); INS_InsertCall( ins, IPOINT_BEFORE, (AFUNPTR) printSz, IARG_MEMORYREAD_SIZE, IARG_INST_PTR, IARG_EXECUTING, IARG_REG_VALUE, REG_ECX, IARG_END); INS_InsertCall( ins, IPOINT_AFTER, (AFUNPTR) printCntVal, IARG_REG_VALUE,REG_ECX, IARG_END); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)printRegisterDiffs, IARG_THREAD_ID, IARG_CONTEXT, IARG_UINT32, where++, IARG_END); INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) printSzPredicated, IARG_MEMORYREAD_SIZE, IARG_INST_PTR, IARG_EXECUTING, IARG_REG_VALUE, REG_ECX, IARG_END); INS_InsertPredicatedCall( ins, IPOINT_AFTER, (AFUNPTR) printCntValPredicated, IARG_REG_VALUE,REG_ECX, IARG_END); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)printRegisterDiffs, IARG_THREAD_ID, IARG_CONTEXT, IARG_UINT32, where++, IARG_END); if (INS_HasRealRep(ins)) { INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)firstTime, IARG_END); INS_InsertThenCall(ins, IPOINT_BEFORE, (AFUNPTR)checkFirstRep, IARG_FIRST_REP_ITERATION, IARG_END); INS_InsertCall (ins, IPOINT_BEFORE, (AFUNPTR)countReps, IARG_FIRST_REP_ITERATION, IARG_EXECUTING, IARG_END); } } }