// Pin calls this function every time a new instruction is encountered VOID Instruction(INS ins, VOID *v) { BOOL doInstrument =FALSE; xed_iclass_enum_t iclass = (xed_iclass_enum_t) INS_Opcode(ins); if (INS_Opcode(ins)==XED_ICLASS_FXSAVE || INS_Opcode(ins)==XED_ICLASS_FXSAVE64 || INS_Opcode(ins)==XED_ICLASS_XSAVE || INS_Opcode(ins)==XED_ICLASS_XSAVE64) { doInstrument = TRUE; } else { for (REG reg=REG_XMM_BASE; reg <= REG_YMM_LAST; reg=static_cast<REG>((static_cast<INT32>(reg)+1))) { if (INS_RegRContain(ins, reg)) { doInstrument = TRUE; break; } else if (INS_RegWContain(ins, reg)) { doInstrument = TRUE; break; } } } if (doInstrument) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)SetYmmScratchesFun, IARG_ADDRINT, ymmInitVals, IARG_ADDRINT, xmmSaveVal, IARG_END); } }
VOID Instruction(INS ins, VOID *v) { for (REG reg=REG_XMM_BASE; reg <= REG_XMM_LAST; reg=static_cast<REG>((static_cast<INT32>(reg)+1))) { if (INS_RegRContain(ins, reg)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(TestXmm), IARG_INST_PTR, IARG_REG_REFERENCE, reg, IARG_REG_REFERENCE, REG_XMM1, IARG_ADDRINT, READ, IARG_ADDRINT, (reg-REG_XMM_BASE), IARG_END); fprintf(outfile,"Instrumented read on ins %p %s\n", (void *)(INS_Address(ins)), INS_Disassemble(ins).c_str()); fflush (outfile); } if (INS_RegWContain(ins, reg)) { INS_InsertCall(ins, IPOINT_AFTER, AFUNPTR(TestXmm), IARG_INST_PTR, IARG_REG_REFERENCE, reg, IARG_REG_REFERENCE, REG_XMM1, IARG_ADDRINT, WRITE, IARG_ADDRINT, (reg-REG_XMM_BASE), IARG_END); fprintf(outfile,"Instrumented write on ins %p %s\n", (void *)(INS_Address(ins)), INS_Disassemble(ins).c_str()); fflush (outfile); } } }
// Pin calls this function before a code sequence is executed for the first time VOID TraceCalls(INS ins, VOID *v) { // If we don't have a proper config, we cannot instrument anything if (config == NULL) { return; } ADDRINT addr = INS_Address(ins); IMG img = IMG_FindByAddress(addr); // We are interested only calls from the JITted code. That code is not part of any valid image if (IMG_Valid(img) && img != config->img) { return; } // We don't know the origins of the calls (only the targets) so we need to instrument every call if (INS_IsCall(ins)) { bool ok = false; if (INS_RegRContain(ins, REG_EAX) || INS_RegRContain(ins, REG_EDX)) { ok = true; } else if (INS_IsDirectCall(ins)) { ADDRINT target_addr = INS_DirectBranchOrCallTargetAddress(ins); IMG target_img = IMG_FindByAddress(target_addr); if (!IMG_Valid(img) || img == config->img) { ok = true; } } if (ok) { // Select which call analysis function to use depending on whether we are in fast mode AFUNPTR analysisFunc = (AFUNPTR)MethodCallAnalysis; if (KnobFast.Value()) { analysisFunc = (AFUNPTR)MethodCallAnalysisFast; } ADDRINT ret_addr = INS_NextAddress(ins); INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)ShouldCallBeAnalyzed, IARG_FUNCARG_CALLSITE_REFERENCE, 0, IARG_ADDRINT, ret_addr, IARG_BRANCH_TARGET_ADDR, IARG_END); INS_InsertThenCall(ins, IPOINT_BEFORE, analysisFunc, IARG_FUNCARG_CALLSITE_REFERENCE, 0, IARG_ADDRINT, ret_addr, IARG_BRANCH_TARGET_ADDR, IARG_END); returnAddressToInstument[ret_addr] = true; return; } } if (returnAddressToInstument.find(addr) != returnAddressToInstument.end()) { // Select which call analysis function to use depending on whether we are in fast mode AFUNPTR analysisFuncIf = (AFUNPTR)ShouldReturnAddressBeAnalyzed; AFUNPTR analysisFuncThen = (AFUNPTR)ReturnValueAnalysis; if (KnobFast.Value()) { analysisFuncIf = (AFUNPTR)ShouldReturnAddressBeAnalyzedFast; analysisFuncThen = (AFUNPTR)ReturnValueAnalysisFast; } INS_InsertIfCall(ins, IPOINT_BEFORE, analysisFuncIf, IARG_ADDRINT, addr, IARG_END); INS_InsertThenCall(ins, IPOINT_BEFORE, analysisFuncThen, IARG_ADDRINT, addr, IARG_REG_VALUE, REG_EAX, IARG_FUNCARG_CALLSITE_REFERENCE, 0, IARG_END); return; } }