// 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
        );
    }
}
Beispiel #2
0
/*!
 * 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);
    }
}
Beispiel #3
0
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);
    }
}
Beispiel #7
0
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
        );
    }
}
Beispiel #9
0
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);
    }
}
Beispiel #10
0
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);
            }
        }
    }
}
Beispiel #11
0
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);
        }
    }
}
Beispiel #12
0
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++;
    }
  }
}
Beispiel #13
0
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);
    }
}