// argc, argv are the entire command line, including pin -t <toolname> -- ... int main(int argc, char * argv[]) { toolLowAddr = ADDRINT(&reportError); toolHighAddr= ADDRINT(&main); fprintf (stderr, "toolLowAddr is 0x%08x\n", toolLowAddr); fprintf (stderr, "toolHighAddr is 0x%08x\n", toolHighAddr); PIN_InitSymbols(); // Initialize pin PIN_Init(argc, argv); IMG_AddInstrumentFunction (imageLoad, 0); PIN_AddFetchFunction (fetchIns, 0); // Register Fini to be called when the application exits PIN_AddFiniFunction(fini, 0); // Start the program, never returns PIN_StartProgram(); return 0; }
static VOID ThreadCreateCallback(THREADID tid, CONTEXT * ctxt, INT32 flags, VOID * v) { if (KnobVerbose) cerr << "Thread create callback for " << tid << "\n"; // First thread is static, we don't want to mangle it, but we do create a new thread // from the callback. if (KnobFromCallback) { ADDRINT * stack = new ADDRINT [1024]; CONTEXT context; ctxt = &context; if (!threadFunction) { cerr << "Cannot find 'doNothing()' in application\n"; PIN_ExitProcess(-1); } // Fill in sensible values for critical registers. PIN_SetContextReg(ctxt, REG_STACK_PTR,ADDRINT (&stack[1023])); PIN_SetContextReg(ctxt, REG_INST_PTR, threadFunction); PIN_SetContextReg(ctxt, REG_GFLAGS, 0); cloneThread(ctxt); } if (tid >= (MAXTHREADS-1)) { cerr << "Created all threads OK\n"; PIN_ExitProcess(0); } // First thread is created statically, we don't want to mess with it. if (tid == 0 || KnobFromCallback) return; if (!threadFunction) { cerr << "Cannot find 'doNothing()' in application\n"; PIN_ExitProcess(-1); } ADDRINT * stack = new ADDRINT [1024]; // Fill in sensible values for critical registers. PIN_SetContextReg(ctxt, REG_STACK_PTR,ADDRINT (&stack[1023])); PIN_SetContextReg(ctxt, REG_INST_PTR, ADDRINT (&threadFunction)); PIN_SetContextReg(ctxt, REG_GFLAGS, 0); }
static VOID Instrument(INS ins) { UINT32 op = INS_Opcode(ins); switch (op) { case XED_ICLASS_BT: case XED_ICLASS_BTC: case XED_ICLASS_BTR: case XED_ICLASS_BTS: // Filter out the BTs we want to look at, we don't expect any in system libraries, // but we have seen a bt reg,reg on FC12 if (INS_IsMemoryRead(ins) && !INS_OperandIsImmediate(ins,1)) break; // Fall through and ignore non mem,reg operations. default: return; } INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(ProcessAddress), IARG_ADDRINT, ADDRINT (formatInstruction(ins)), IARG_MEMORYREAD_SIZE, IARG_MEMORYOP_EA, 0, IARG_REG_VALUE, INS_OperandReg(ins, 1), IARG_END); }
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 Insert(INT32 frameSize) { INS_InsertCall(_ins, IPOINT_BEFORE, _afunptr, IARG_FAST_ANALYSIS_CALL, IARG_REG_VALUE, scratch_reg0, IARG_ADDRINT, ADDRINT(_offset - frameSize), _itype, IARG_END); }