Skip to content

Instantly share code, notes, and snippets.

@JamesMenetrey
Created April 17, 2019 16:15
Show Gist options
  • Save JamesMenetrey/622c2abcca1a22413baf731c036368e9 to your computer and use it in GitHub Desktop.
Save JamesMenetrey/622c2abcca1a22413baf731c036368e9 to your computer and use it in GitHub Desktop.
Pin tool (binary instrumentation) - Count the number of executed basic blocks in an application
/*! @file
* The pin tool is based on the sample tool MyPinTool and has been modified
* to only count the executed basic blocks of an application.
*
* Written by Jämes Ménétrey.
*/
#include "pin.H"
#include <iostream>
#include <fstream>
/* ================================================================== */
// Global variables
/* ================================================================== */
UINT64 bblCount = 0; //number of dynamically executed basic blocks
std::ostream * out = &cerr;
/* ===================================================================== */
// Command line switches
/* ===================================================================== */
KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool",
"o", "", "specify file name for MyPinTool output");
KNOB<BOOL> KnobCount(KNOB_MODE_WRITEONCE, "pintool",
"count", "1", "count basic blocks in the application");
/* ===================================================================== */
// Utilities
/* ===================================================================== */
/*!
* Print out help message.
*/
INT32 Usage()
{
cerr << "This tool prints out the number of dynamically executed " << endl <<
"basic blocks in the application." << endl << endl;
cerr << KNOB_BASE::StringKnobSummary() << endl;
return -1;
}
/* ===================================================================== */
// Analysis routines
/* ===================================================================== */
/*!
* Increase counter of the executed basic blocks and instructions.
* This function is called for every basic block when it is about to be executed.
* @param[in] numInstInBbl number of instructions in the basic block
* @note use atomic operations for multi-threaded applications
*/
VOID CountBbl(UINT32 numInstInBbl)
{
bblCount++;
}
/* ===================================================================== */
// Instrumentation callbacks
/* ===================================================================== */
/*!
* 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);
}
}
/*!
* Print out analysis results.
* This function is called when the application exits.
* @param[in] code exit code of the application
* @param[in] v value specified by the tool in the
* PIN_AddFiniFunction function call
*/
VOID Fini(INT32 code, VOID *v)
{
*out << "===============================================" << endl;
*out << "MyPinTool analysis results: " << endl;
*out << "Number of basic blocks: " << bblCount << endl;
*out << "===============================================" << endl;
}
/*!
* The main procedure of the tool.
* This function is called when the application image is loaded but not yet started.
* @param[in] argc total number of elements in the argv array
* @param[in] argv array of command line arguments,
* including pin -t <toolname> -- ...
*/
int main(int argc, char *argv[])
{
// Initialize PIN library. Print help message if -h(elp) is specified
// in the command line or the command line is invalid
if( PIN_Init(argc,argv) )
{
return Usage();
}
string fileName = KnobOutputFile.Value();
if (!fileName.empty()) { out = new std::ofstream(fileName.c_str());}
if (KnobCount)
{
// Register function to be called to instrument traces
TRACE_AddInstrumentFunction(Trace, 0);
// Register function to be called when the application exits
PIN_AddFiniFunction(Fini, 0);
}
cerr << "===============================================" << endl;
cerr << "This application is instrumented by MyPinTool" << endl;
if (!KnobOutputFile.Value().empty())
{
cerr << "See file " << KnobOutputFile.Value() << " for analysis results" << endl;
}
cerr << "===============================================" << endl;
// Start the program, never returns
PIN_StartProgram();
return 0;
}
/* ===================================================================== */
/* eof */
/* ===================================================================== */
#!/usr/bin/env bash
# Change the path of the pin tool framework if needed.
make PIN_ROOT='$HOME/pin' TARGET=ia32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment