// We have to instrument traces in order to instrument each BBL, the API doesn't have a BBL_AddInstrumentFunction VOID trace_instrumentation(TRACE trace, VOID *v) { // We don't want to instrument the BBL contained in the Windows API if(is_address_in_blacklisted_modules(TRACE_Address(trace))) return; for(BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { // What's going on under the hood // LOG("[INSTRU] BBL Address: " + hexstr(BBL_Address(bbl)) + ", " + hexstr(BBL_NumIns(bbl)) + "\n"); // Insert a call to handle_basic_block before every basic block, passing the number of instructions BBL_InsertCall( bbl, IPOINT_ANYWHERE, (AFUNPTR)handle_basic_block, IARG_FAST_ANALYSIS_CALL, // Use a faster linkage for calls to analysis functions. Add PIN_FAST_ANALYSIS_CALL to the declaration between the return type and the function name. You must also add IARG_FAST_ANALYSIS_CALL to the InsertCall. For example: IARG_UINT32, BBL_NumIns(bbl), IARG_ADDRINT, BBL_Address(bbl), IARG_END ); } }
/*! * Insert call to the CountBbl() analysis routine before every basic block * of the trace. * This function is called every time a new trace is encountered. * @param[in] trace trace to be instrumented * @param[in] v value specified by the tool in the TRACE_AddInstrumentFunction * function call */ VOID Trace(TRACE trace, VOID *v) { // Visit every basic block in the trace for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { // Insert a call to CountBbl() before every basic bloc, passing the number of instructions BBL_InsertCall(bbl, IPOINT_BEFORE, (AFUNPTR)CountBbl, IARG_UINT32, BBL_NumIns(bbl), IARG_END); } }
VOID Trace(TRACE trace, VOID *v) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) BBL_InsertCall(bbl, IPOINT_ANYWHERE, AFUNPTR(Count), IARG_FAST_ANALYSIS_CALL, IARG_THREAD_ID, IARG_UINT32, BBL_NumIns(bbl), IARG_END); }
// Pin calls this function every time a new basic block is encountered. // It inserts a call to docount. VOID Trace(TRACE trace, VOID *v) { // Visit every basic block in the trace for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { // Insert a call to docount for every bbl, passing the number of instructions. BBL_InsertCall(bbl, IPOINT_ANYWHERE, (AFUNPTR)docount, IARG_FAST_ANALYSIS_CALL, IARG_UINT32, BBL_NumIns(bbl), IARG_THREAD_ID, IARG_END); } }
// Pin calls this function every time a new basic block is encountered // It inserts a call to docount VOID Trace(TRACE trace, VOID *v) { // Visit every basic block in the trace for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { // Insert a call to docount for every bbl, passing the number of instructions. // IPOINT_ANYWHERE allows Pin to schedule the call anywhere in the bbl to obtain best performance. BBL_InsertCall(bbl, IPOINT_ANYWHERE, (AFUNPTR)docount, IARG_FAST_ANALYSIS_CALL, IARG_UINT32, BBL_NumIns(bbl), IARG_THREAD_ID, IARG_INST_PTR, IARG_END); } }
VOID Trace(TRACE trace, VOID *v) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { // The virtual register ScratchReg holds the dynamic instruction // count for each thread. DoCount returns the sum of the basic // block instruction count and G0, we write the result back to G0 BBL_InsertCall(bbl, IPOINT_ANYWHERE, AFUNPTR(DoCount), IARG_FAST_ANALYSIS_CALL, IARG_ADDRINT, BBL_NumIns(bbl), IARG_REG_VALUE, ScratchReg, IARG_RETURN_REGS, ScratchReg, IARG_END); } }
VOID Trace(TRACE trace, VOID *v) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { DBG_PRINT(printf("Inst: Sequence address %p\n",(CHAR*)(INS_Address(BBL_InsHead(bbl))))); for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { DBG_PRINT(printf("Inst: %p\n",(CHAR*)(INS_Address(ins)))); INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(docount_ins), IARG_INST_PTR, IARG_END); } INT32 icount = BBL_NumIns(bbl); DBG_PRINT(printf("Inst: -> control flow change (bbl size %d)\n", icount)); INS_InsertCall(BBL_InsTail(bbl), IPOINT_BEFORE, AFUNPTR(docount_bbl_ins), IARG_INST_PTR, IARG_UINT32, icount, IARG_END); } }
//-------------------------------------------------------------------------------------- VOID Trace(TRACE TraceInfo, VOID *v) { // Visit every basic block in the trace for (BBL Bbl = TRACE_BblHead(TraceInfo); BBL_Valid(Bbl); Bbl = BBL_Next(Bbl)) { // Forward pass over all instructions in bbl for (INS Ins = BBL_InsHead(Bbl); INS_Valid(Ins); Ins = INS_Next(Ins)) { // check for the CALL if (INS_IsCall(Ins)) { INS_InsertCall( Ins, IPOINT_BEFORE, (AFUNPTR)InstCallHandler, IARG_INST_PTR, IARG_BRANCH_TARGET_ADDR, IARG_END ); } // check for the RET if (INS_IsRet(Ins)) { INS_InsertCall( Ins, IPOINT_BEFORE, (AFUNPTR)InstRetHandler, IARG_INST_PTR, IARG_END ); } } // Insert a call to CountBbl() before every basic bloc, passing the number of instructions BBL_InsertCall( Bbl, IPOINT_BEFORE, (AFUNPTR)CountBbl, IARG_INST_PTR, (UINT32)IARG_UINT32, BBL_Size(Bbl), IARG_UINT32, BBL_NumIns(Bbl), IARG_END ); } }
VOID Trace(TRACE trace, VOID *v) { if ( KnobNoSharedLibs.Value() && IMG_Type(SEC_Img(RTN_Sec(TRACE_Rtn(trace)))) == IMG_TYPE_SHAREDLIB) return; const BOOL accurate_handling_of_predicates = KnobProfilePredicated.Value(); for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { // Summarize the stats for the bbl in a 0 terminated list // This is done at instrumentation time UINT16 * stats = new UINT16[BBL_NumIns(bbl) + 1]; INT32 index = 0; for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { // Count the number of times a predicated instruction is actually executed // this is expensive and hence disabled by default if( INS_IsPredicated(ins) && accurate_handling_of_predicates ) { INS_InsertPredicatedCall(ins, IPOINT_BEFORE, AFUNPTR(docount), IARG_PTR, &(GlobalStatsDynamic.predicated_true[INS_Category(ins)]), IARG_END); } stats[index++] = INS_GetStatsIndex(ins); } stats[index] = 0; // Insert instrumentation to count the number of times the bbl is executed BBLSTATS * bblstats = new BBLSTATS(stats); INS_InsertCall(BBL_InsHead(bbl), IPOINT_BEFORE, AFUNPTR(docount), IARG_PTR, &(bblstats->_counter), IARG_END); // Remember the counter and stats so we can compute a summary at the end statsList.push_back(bblstats); } }
static VOID InstrumentTrace(TRACE trace, VOID *v) { // Visit every basic block in the trace for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { // Insert a call to addTotal somewhere in each bbl, passing the number of instructions // in the BBL. BBL_InsertCall(bbl, IPOINT_ANYWHERE, (AFUNPTR)addTotal, IARG_UINT32, BBL_NumIns(bbl), IARG_END); if (KnobCountMemory) { // Compute the number of memory accesses generated by the BBL UINT32 reads = 0; UINT32 writes = 0; for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_IsMemoryRead(ins)) reads++; if (INS_HasMemoryRead2(ins)) reads++; if (INS_IsMemoryWrite(ins)) writes++; } // If we have memory accesses, then add instrumentation to count them. if (reads != 0 || writes != 0) { BBL_InsertCall(bbl, IPOINT_ANYWHERE, (AFUNPTR)addTotalMemops, IARG_UINT32, reads, IARG_UINT32, writes, IARG_END); } } } }
VOID Trace(TRACE trace, VOID *v) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { if (OrigCount.find(INS_Address(ins)) == OrigCount.end()) OrigCount[INS_Address(ins)] = 1; else OrigCount[INS_Address(ins)]++; } if (KnobDynamic) { // Insert instrumentation to count the number of times the bbl is executed BBLSTATS * bblstats = new BBLSTATS(BBL_NumIns(bbl)); BBL_InsertCall(bbl, IPOINT_ANYWHERE, AFUNPTR(docount), IARG_PTR, &(bblstats->_counter), IARG_END); // Remember the counter and stats so we can compute a summary at the end statsList.push_back(bblstats); } } }
VOID instrumentTrace( TRACE trace, VOID *v ) { for ( BBL bbl = TRACE_BblHead( trace ); BBL_Valid( bbl ); bbl = BBL_Next( bbl ) ) { INS ins = BBL_InsHead( bbl ); INS_InsertCall( ins, IPOINT_BEFORE, (AFUNPTR) startBasicBlock, IARG_THREAD_ID, IARG_CONTEXT, IARG_UINT32, BBL_NumIns( bbl ), IARG_END ); UINT32 instPos = 0; for ( ; INS_Valid( ins ); ins = INS_Next( ins ) ) { if ( INS_IsMemoryRead( ins ) ) { INS_InsertCall( ins, IPOINT_BEFORE, (AFUNPTR) memOp, IARG_THREAD_ID, IARG_UINT32, instPos, IARG_MEMORYREAD_EA, IARG_MEMORYREAD_SIZE, IARG_BOOL, true, IARG_BOOL, INS_IsStackRead( ins ), IARG_END ); } if ( INS_IsMemoryWrite( ins ) ) { INS_InsertCall( ins, IPOINT_BEFORE, (AFUNPTR) memOp, IARG_THREAD_ID, IARG_UINT32, instPos, IARG_MEMORYWRITE_EA, IARG_MEMORYWRITE_SIZE, IARG_BOOL, false, IARG_BOOL, INS_IsStackWrite( ins ), IARG_END ); } instPos++; } } }
VOID Trace(TRACE trace, VOID *v) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { INS_InsertCall(BBL_InsHead(bbl), IPOINT_BEFORE, (AFUNPTR)docount, IARG_UINT32, BBL_NumIns(bbl), IARG_END); } }