Search code examples
c++intel-pin

Intel Pin: How to generate objectdump-ish code?


I am experimenting with intel-pin tool. I have a simple Hello-world.c (It prints nothing but "Hello world") program (say a.out). If I want to generate assembly from the binary, I would do objdump -D a.out.

I want to instrument some instructions in that.

Is it possible to get objdump using pin tool, before (This can be easily done by objdump) and after instrumentation?

I have created a tool which prints all the instructions.

#include <stdio.h>
#include "pin.H"
#include <cstdint>

FILE * trace;

KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", "o", "pinatrace.out","A pin tool");

VOID Count(INS ins, void *v) {


        fprintf(trace,"\n%s",(INS_Disassemble(ins)).c_str());

}

VOID Fini(INT32 code, VOID *v)
{
        printf("count = %ld\n",(long)icount);
        fprintf(trace, "#eof\n");
        fclose(trace);
}

/* ===================================================================== */
/* Print Help Message                                                    */
/* ===================================================================== */

INT32 Usage()
{
    PIN_ERROR( "This Pintool prints a trace of memory addresses\n"
              + KNOB_BASE::StringKnobSummary() + "\n");
    return -1;
}

/* ===================================================================== */
/* Main                                                                  */
/* ===================================================================== */

int main(int argc, char *argv[])
{
    if (PIN_Init(argc, argv)) return Usage();

    trace = fopen("pinatrace.out", "w");


    INS_AddInstrumentFunction(Count, 0);
    PIN_AddFiniFunction(Fini, 0);
    // Never returns
    PIN_StartProgram();

    return 0;
}

It prints the assembly instructions, but I am not sure if it includes the instrumented instructions.

Is this the proper way to do this? Could you please help me?


Solution

  • Is it possible to get objdump using pin tool, before (This can be easily done by objdump) and after instrumentation?

    You'll need a way to tell the PIN engine what you want to do with the results from objdump. You might want to link both of them though a script for example. It totally depends on what you want to do though.

    Is this the proper way to do this?

    Depends on what you want to do exactly, but I guess it's not.

    There's a clear distinction between instrumentation and analysis in PIN. Once you understand it, the rest is (relatively) easy.

    Conceptually, PIN instrumentation consists of two components:

    • A mechanism that decides where and what code is inserted: the instrumentation.
    • The code to execute at insertion points: the analysis.

    That being said, one more important point:

    • The instrumentation is only run once: when the instruction (or BBL, or TRACE) is discovered for the first time.
    • The analysis is run each time the instruction (or BBL, TRACE) is executed.

    So when you have:

    // set up the **instrumentation**
    INS_AddInstrumentFunction(Func_Instrumentation, 0);
    

    You are setting up the instrumentation (which is then only called once). If you need a callback to be called each time an instruction (or BBL, TRACE) is executed you need to set up an analysis routine, for example:

    // this is the **analysis** routine.
    // This function is called before every instruction is executed
    VOID docount() { icount++; }
    
    // The is the **instrumentation routine**, called by INS_AddInstrumentFunction().
    // Pin calls this function each time a **new** instruction is encountered
    // Note that is won't be called for the same instruction after the first time.
    VOID Func_Instrumentation(INS ins, VOID *v)
    {
        // Insert a call to docount before every instruction, no arguments are passed
        INS_InsertCall(
            ins,              // a representation of the instruction
            IPOINT_BEFORE,    // where to insert, relative to the instruction
            (AFUNPTR)docount, // the analysis routine
            IARG_END);        // no args to pass to the analysis routine
    }
    

    Check carefully the instruction count sample available: