// Generate code to check if swizzling is needed, but not do it VOID CheckIns(INS ins, ADDRINT traceAddress) { if (INS_IsMemoryRead(ins) && INS_HasMemoryRead2(ins)) { INS_InsertIfCall(ins, IPOINT_BEFORE, AFUNPTR(SwizzleSpace2), IARG_MEMORYREAD_EA, IARG_MEMORYREAD2_EA, IARG_END); } else if (INS_IsMemoryRead(ins) && INS_IsMemoryWrite(ins)) { INS_InsertIfCall(ins, IPOINT_BEFORE, AFUNPTR(SwizzleSpace2), IARG_MEMORYREAD_EA, IARG_MEMORYWRITE_EA, IARG_END); } else if (INS_IsMemoryRead(ins)) { INS_InsertIfCall(ins, IPOINT_BEFORE, AFUNPTR(SwizzleSpace1), IARG_MEMORYREAD_EA, IARG_END); } else if (INS_IsMemoryWrite(ins)) { INS_InsertIfCall(ins, IPOINT_BEFORE, AFUNPTR(SwizzleSpace1), IARG_MEMORYWRITE_EA, IARG_END); } else { return; } INS_InsertThenCall(ins, IPOINT_BEFORE, AFUNPTR(Restart), IARG_INST_PTR, IARG_CONTEXT, IARG_ADDRINT, traceAddress, IARG_END); }
static void Instruction(INS ins, void *v) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)do_count, IARG_END); // Filters out non memory reference instructions. if (!INS_IsMemoryRead(ins) && !INS_IsMemoryWrite(ins)) return; // Filters out references to stack. if (INS_IsStackRead(ins) || INS_IsStackWrite(ins)) return; // Filters out instructions out of main executable. IMG img = IMG_FindByAddress(INS_Address(ins)); if (!IMG_Valid(img) || !IMG_IsMainExecutable(img)) return; unsigned i; unsigned int mem_op = INS_MemoryOperandCount(ins); for (i = 0; i < mem_op; i++) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)check_addr, IARG_INST_PTR, IARG_MEMORYOP_EA, i, IARG_END); } }
INT32 RecordRegisters(BBL bbl, UINT16 * stats, UINT32 max_stats) { UINT32 count = 0; for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { if (count >= max_stats) { cerr << "Too many stats in this block" << endl; exit(1); } bool rmem = INS_IsMemoryRead(ins) || INS_HasMemoryRead2(ins); bool wmem = INS_IsMemoryWrite(ins); bool rw_mem = rmem & wmem; if (rw_mem) stats[count++] = PATTERN_MEM_RW; else if (rmem) stats[count++] = PATTERN_MEM_R; else if (wmem) stats[count++] = PATTERN_MEM_W; else if (INS_SegmentRegPrefix(ins) != REG_INVALID()) stats[count++] = PATTERN_NO_MEM_LIES; else stats[count++] = PATTERN_NO_MEM; } stats[count++] = 0; return count; }
/****************************************************************** Title:movRMHandler Function:Handler to handle instruction "mov REG [mem addr]" Input: INS ins:Instruction to be handled. int srcA:The 1st src operand. int srcB:The 2nd src operand. int srcC:The 3rd src operand. int dstA:The 1st dst operand. int dstB:The 2nd dst operand. int dstC:The 3rd dst operand. Output: int Return value:-1 means unable to handle the instruction ******************************************************************/ int movRMHandler(INS ins,int srcA,int srcB,int srcC,int dstA,int dstB,int dstC) { REG baseReg = INS_OperandMemoryBaseReg(ins,1); INT64 displacement = INS_OperandMemoryDisplacement(ins,1); REG indexReg = INS_OperandMemoryIndexReg(ins,1); UINT32 scale = INS_OperandMemoryScale(ins,1); if(REG_valid(baseReg)){ INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)getRegisterValue, IARG_REG_VALUE,baseReg, IARG_END); } int valueBaseReg = regValue; if(REG_valid(indexReg)){ INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)getRegisterValue, IARG_REG_VALUE,indexReg, IARG_END); } int valueIndexReg = regValue; unsigned int realAddress = displacement+valueBaseReg+valueIndexReg*scale; if(INS_IsMemoryRead(ins)){ INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(movRMHook), IARG_UINT32, REG(INS_OperandReg(ins, 0)), IARG_MEMORYREAD_EA, IARG_END); }else{ fprintf(log,"Error at reading memory\n"); return -1; } countAllIns++; countHandledIns++; return 0; }
// Is called for every instruction and instruments reads and writes VOID Instruction(INS ins, VOID *v) { BOOL hasReadSegmentedMemAccess = FALSE; BOOL hasWriteSegmentedMemAccess = FALSE; if (INS_SegmentRegPrefix(ins) == TESTED_SEG_REG) //INS_OperandMemorySegmentReg, INS_SegPrefixIsMemoryRead, INS_OperandMemoryDisplacement { if (INS_IsMemoryRead(ins)) { HandleAccess (ins, TRUE /* isRead*/, &hasReadSegmentedMemAccess) ; } if (INS_IsMemoryWrite(ins)) { HandleAccess (ins, FALSE /* isRead*/, &hasWriteSegmentedMemAccess); } if (!hasReadSegmentedMemAccess && !hasWriteSegmentedMemAccess) { fprintf(trace, "**ERROR SegMemAccess-Lies %p %s\n", INS_Address(ins), INS_Disassemble(ins).c_str()); hadError = TRUE; } } /*fprintf(trace, "%p %s\n", INS_Address(ins), INS_Disassemble(ins).c_str()); fflush (trace);*/ }
/* instrumenting (instruction level) */ VOID instrument_stride(INS ins, VOID* v){ UINT32 index; if( INS_IsMemoryRead(ins) ){ // instruction has memory read operand index = stride_index_memRead1(INS_Address(ins)); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)readMem_stride, IARG_UINT32, index, IARG_MEMORYREAD_EA, IARG_MEMORYREAD_SIZE, IARG_END); if( INS_HasMemoryRead2(ins) ){ // second memory read operand index = stride_index_memRead2(INS_Address(ins)); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)readMem_stride, IARG_UINT32, index, IARG_MEMORYREAD2_EA, IARG_MEMORYREAD_SIZE, IARG_END); } } if( INS_IsMemoryWrite(ins) ){ // instruction has memory write operand index = stride_index_memWrite(INS_Address(ins)); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)writeMem_stride, IARG_UINT32, index, IARG_MEMORYWRITE_EA, IARG_MEMORYWRITE_SIZE, IARG_END); } /* inserting calls for counting instructions (full) is done in mica.cpp */ if(interval_size != -1){ INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)stride_instr_intervals, IARG_END); INS_InsertThenCall(ins, IPOINT_BEFORE, (AFUNPTR)stride_instr_interval, IARG_END); } }
// Is called for every instruction and instruments reads and writes VOID Instruction(INS ins, VOID *v) { // Insert a call to docount before every instruction, no arguments are passed INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount,IARG_THREAD_ID, IARG_END); // instruments loads using a predicated call, i.e. // the call happens iff the load will be actually executed // (this does not matter for ia32 but arm and ipf have predicated instructions) if (INS_IsMemoryRead(ins)) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead, IARG_INST_PTR, IARG_MEMORYREAD_EA, IARG_THREAD_ID, IARG_END); } // instruments stores using a predicated call, i.e. // the call happens iff the store will be actually executed if (INS_IsMemoryWrite(ins)) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite, IARG_INST_PTR, IARG_MEMORYWRITE_EA, IARG_THREAD_ID, IARG_END); } }
// Pin calls this function every time a new instruction is encountered VOID Inst(INS ins, VOID *v) { ADDRINT pc = INS_Address (ins); if ( pc == StartAddr ) RecordFlag = true; if ( pc == EndAddr ) RecordFlag = false; if ( RecordFlag && pc < 0x01000000 ) { if ( MinAddr > pc ) MinAddr = pc; if ( MaxAddr < pc ) MaxAddr = pc; INS_InsertCall( ins, IPOINT_BEFORE, (AFUNPTR)profile_code, IARG_INST_PTR, IARG_END ); if (INS_IsMemoryWrite(ins)) INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(profile_mem_write), IARG_INST_PTR, IARG_END); if ( INS_HasMemoryRead2(ins) ) INS_InsertPredicatedCall(ins, IPOINT_BEFORE, AFUNPTR(profile_mem_read), IARG_INST_PTR, IARG_END); if ( INS_IsMemoryRead(ins) ) INS_InsertPredicatedCall(ins, IPOINT_BEFORE, AFUNPTR(profile_mem_read), IARG_INST_PTR, 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)) { for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_IsMemoryRead(ins)) { INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)ReadAlways, IARG_MEMORYREAD_EA, IARG_END); INS_InsertThenCall(ins, IPOINT_BEFORE, (AFUNPTR)ReadRare, IARG_MEMORYREAD_EA, IARG_END); } } // Always()->Rare() are partially inlined BBL_InsertIfCall(bbl, IPOINT_BEFORE, (AFUNPTR)Always, IARG_END); BBL_InsertThenCall(bbl, IPOINT_BEFORE, (AFUNPTR)Rare, IARG_END); // Always()->Rare() are partially inlined BBL_InsertIfCall(bbl, IPOINT_BEFORE, (AFUNPTR)AlwaysNoinline, IARG_END); BBL_InsertThenCall(bbl, IPOINT_BEFORE, (AFUNPTR)RareNoinline, IARG_END); // Noinline() is not inlined BBL_InsertCall(bbl, IPOINT_BEFORE, (AFUNPTR)Noinline, IARG_END); } }
LOCALFUN VOID Instruction(INS ins, void * v) { if (INS_IsMemoryRead(ins)) { const UINT32 size = INS_MemoryReadSize(ins); // we assume accesses <= 4 bytes stay in the same cache line // to speed up cache access lookups const AFUNPTR countFun = (size <= 4 ? (AFUNPTR) MemRefSingle : (AFUNPTR) MemRefMulti); // only predicated-on memory instructions access D-cache INS_InsertPredicatedCall( ins, IPOINT_BEFORE, countFun, IARG_UINT32, CACHE_BASE::ACCESS_TYPE_LOAD, IARG_MEMORYREAD_EA, IARG_MEMORYREAD_SIZE, IARG_END); } if (INS_IsMemoryWrite(ins)) { const UINT32 size = INS_MemoryWriteSize(ins); const AFUNPTR countFun = (size <= 4 ? (AFUNPTR) MemRefSingle : (AFUNPTR) MemRefMulti); // only predicated-on memory instructions access D-cache INS_InsertPredicatedCall( ins, IPOINT_BEFORE, countFun, IARG_UINT32, CACHE_BASE::ACCESS_TYPE_STORE, IARG_MEMORYWRITE_EA, IARG_MEMORYWRITE_SIZE, IARG_END); } }
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); }
bool BBLContainMemOp(BBL bbl) { for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_IsStackRead(ins) || INS_IsStackWrite(ins)) continue; if (INS_IsMemoryRead(ins) || INS_IsMemoryWrite(ins)) return true; } return false; }
void Instruction(INS ins, VOID *) { if (INS_IsMemoryRead(ins)) { // IARG_MEMORYREAD_EA is not valid at IPOINT_AFTER. We're going to check the error message, // to make sure that it points to the next line, which is line 17 (or 47 once the legal header is added) INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)doNothing, IARG_MEMORYREAD_EA, IARG_END); } }
VOID Instruction(INS ins, VOID *v) { // instruments loads using a predicated call, i.e. // the call happens iff the load will be actually executed if (INS_IsMemoryRead(ins)) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)RecordMem, IARG_INST_PTR, IARG_UINT32, 'R', IARG_MEMORYREAD_EA, IARG_MEMORYREAD_SIZE, IARG_UINT32, INS_IsPrefetch(ins), IARG_END); } if (INS_HasMemoryRead2(ins)) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)RecordMem, IARG_INST_PTR, IARG_UINT32, 'R', IARG_MEMORYREAD2_EA, IARG_MEMORYREAD_SIZE, IARG_UINT32, INS_IsPrefetch(ins), IARG_END); } // instruments stores using a predicated call, i.e. // the call happens iff the store will be actually executed if (INS_IsMemoryWrite(ins)) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)RecordWriteAddrSize, IARG_MEMORYWRITE_EA, IARG_MEMORYWRITE_SIZE, IARG_END); if (INS_HasFallThrough(ins)) { INS_InsertCall( ins, IPOINT_AFTER, (AFUNPTR)RecordMemWrite, IARG_INST_PTR, IARG_END); } if (INS_IsBranchOrCall(ins)) { INS_InsertCall( ins, IPOINT_TAKEN_BRANCH, (AFUNPTR)RecordMemWrite, IARG_INST_PTR, IARG_END); } } }
/*! * Instruction instrumentation routine. */ VOID Instruction(INS ins, VOID* v) { if (INS_IsMemoryRead(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(TouchMemory), IARG_MEMORYREAD_EA, IARG_END); } }
/****************************************************************** Title:xorRRHandler Function:Handler to handle instruction "xor Reg Reg" Input: INS ins:Instruction to be handled. int srcA:The 1st src operand. int srcB:The 2nd src operand. int srcC:The 3rd src operand. int dstA:The 1st dst operand. int dstB:The 2nd dst operand. int dstC:The 3rd dst operand. Output: int Return value:-1 means unable to handle the instruction ******************************************************************/ int xorRRHandler(INS ins,int srcA,int srcB,int srcC,int dstA,int dstB,int dstC) { /* This handler has not be completed*/ if(INS_IsMemoryRead(ins)){ }else{ fprintf(log,"Error at reading memory\n"); return -1; } countAllIns++; countHandledIns++; return 0; }
static VOID MemoryTrace(TRACE trace, INS ins) { if (!KnobTraceMemory) return; if (INS_IsMemoryRead(ins) || INS_HasMemoryRead2(ins) || INS_IsMemoryWrite(ins) ) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmitMemory), IARG_THREAD_ID, IARG_INST_PTR, IARG_BOOL, INS_IsMemoryWrite(ins), (INS_IsMemoryWrite(ins) ? IARG_MEMORYWRITE_EA : INS_IsMemoryRead(ins) ? IARG_MEMORYREAD_EA : IARG_MEMORYREAD2_EA), IARG_END ); } }
void convert_load_addr(INS ins, void* v) { if (INS_Opcode(ins) == XED_ICLASS_MOV && INS_IsMemoryRead(ins) && INS_OperandIsReg(ins, 0) && INS_OperandIsMemory(ins, 1)) { // op0 <- *op1 INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(convert), IARG_MEMORYREAD_EA, IARG_END); } }
static VOID InstrumentRoutine(INS ins, VOID *) { if (numThenCalls > 10) { return; } if (INS_IsMemoryRead(ins)) { INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)IfFunc, IARG_END); INS_InsertThenCall(ins, IPOINT_BEFORE, (AFUNPTR)ThenFunc, IARG_MEMORYREAD_EA, // pass a parameter IARG_END); } }
/* ===================================================================== */ VOID Instruction(INS ins, void * v) { if (INS_IsMemoryRead(ins)) { // map sparse INS addresses to dense IDs const UINT32 size = INS_MemoryReadSize(ins); const BOOL single = (size <= 4); if( single ) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) LoadSingle, IARG_MEMORYREAD_EA, IARG_END); } else { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) LoadMulti, IARG_MEMORYREAD_EA, IARG_MEMORYREAD_SIZE, IARG_END); } } if ( INS_IsMemoryWrite(ins) ) { // map sparse INS addresses to dense IDs const UINT32 size = INS_MemoryWriteSize(ins); const BOOL single = (size <= 4); if( single ) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) StoreSingle, IARG_MEMORYWRITE_EA, IARG_END); } else { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) StoreMulti, IARG_MEMORYWRITE_EA, IARG_MEMORYWRITE_SIZE, IARG_END); } } }
void Scheduler::HandlePostInstrumentTrace(TRACE trace) { ExecutionControl::HandlePostInstrumentTrace(trace); 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 (INS_IsMemoryRead(ins) || INS_IsMemoryWrite(ins)) { if (INS_IsStackRead(ins) || INS_IsStackWrite(ins)) continue; // skip stack accesses INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(__Change), IARG_UINT32, 1, IARG_END); } } } }
/****************************************************************** Title:movsdHandler Function:Handler to handle instruction "movsd" Input: INS ins:Instruction to be handled. int srcA:The 1st src operand. int srcB:The 2nd src operand. int srcC:The 3rd src operand. int dstA:The 1st dst operand. int dstB:The 2nd dst operand. int dstC:The 3rd dst operand. Output: int Return value:-1 means unable to handle the instruction ******************************************************************/ int movsdHandler(INS ins,int srcA,int srcB,int srcC,int dstA,int dstB,int dstC) { if(INS_IsMemoryWrite(ins)&&INS_IsMemoryRead(ins)){ INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(movsdHook), IARG_MEMORYREAD_EA, IARG_MEMORYWRITE_EA, IARG_END); }else{ fprintf(log,"Error at writing memory\n"); return -1; } countAllIns++; countHandledIns++; return 0; }
VOID EmulateLoad(INS ins, VOID* v) { if (INS_Opcode(ins) == XEDICLASS_MOV && INS_IsMemoryRead(ins) && INS_OperandIsReg(ins, 0) && INS_OperandIsMemory(ins, 1)) { // op0 <- *op1 INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoLoad), IARG_UINT32, REG(INS_OperandReg(ins, 0)), IARG_MEMORYREAD_EA, IARG_RETURN_REGS, INS_OperandReg(ins, 0), IARG_END); INS_Delete(ins); } }
/****************************************************************** Title:movzxRMHandler Function:Handler to handle instruction "movzx reg,[mem addr]" Input: INS ins:Instruction to be handled. int srcA:The 1st src operand. int srcB:The 2nd src operand. int srcC:The 3rd src operand. int dstA:The 1st dst operand. int dstB:The 2nd dst operand. int dstC:The 3rd dst operand. Output: int Return value:-1 means unable to handle the instruction ******************************************************************/ int movzxRMHandler(INS ins,int srcA,int srcB,int srcC,int dstA,int dstB,int dstC) { if(INS_IsMemoryRead(ins)){ INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(movzxRMHook), IARG_UINT32, REG(INS_OperandReg(ins, 0)), IARG_MEMORYREAD_EA, IARG_END); }else{ fprintf(log,"Error at writing memory\n"); return -1; } countAllIns++; countHandledIns++; return 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); } } } }
static VOID Instruction(INS ins, VOID *v) { IARG_TYPE ea; if (INS_SegmentPrefix(ins)) { if (INS_IsMemoryRead(ins)) ea = IARG_MEMORYREAD_EA; else ea = IARG_MEMORYWRITE_EA; INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(OnSegReference), IARG_UINT32, INS_SegmentRegPrefix(ins), IARG_REG_VALUE, INS_SegmentRegPrefix(ins), IARG_INST_PTR, IARG_THREAD_ID, ea, IARG_END); } REG seg; if (WritesSegment(ins, &seg)) { INS_InsertCall(ins, IPOINT_AFTER, AFUNPTR(OnSegWrite), IARG_UINT32, seg, IARG_REG_VALUE, seg, IARG_INST_PTR, IARG_THREAD_ID, IARG_END); } }
static bool check_for_sse_memop(INS ins, bool& is_read, sse_aligner_t* pthis) { // return true if the instruction is SSEx and reads/writes memory xed_extension_enum_t extension = static_cast<xed_extension_enum_t>(INS_Extension(ins)); if (extension == XED_EXTENSION_SSE || extension == XED_EXTENSION_SSE2 || extension == XED_EXTENSION_SSE3 || extension == XED_EXTENSION_SSSE3 || extension == XED_EXTENSION_SSE4) { if (pthis->realign_loads && INS_IsMemoryRead(ins)) { is_read = true; return true; } if (pthis->realign_stores && INS_IsMemoryWrite(ins)) { is_read = false; return true; } } return false; }
VOID EmulateLoad(INS ins, VOID* v) { // Find the instructions that move a value from memory to a register if (INS_Opcode(ins) == XED_ICLASS_MOV && INS_IsMemoryRead(ins) && INS_OperandIsReg(ins, 0) && INS_OperandIsMemory(ins, 1)) { // op0 <- *op1 INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(DoLoad), IARG_UINT32, REG(INS_OperandReg(ins, 0)), IARG_MEMORYREAD_EA, IARG_RETURN_REGS, INS_OperandReg(ins, 0), IARG_END); // Delete the instruction INS_Delete(ins); } }
LOCALFUN VOID Instruction(INS ins, VOID *v) { // all instruction fetches access I-cache INS_InsertCall( ins, IPOINT_BEFORE, (AFUNPTR)InsRef, IARG_INST_PTR, IARG_END); if (INS_IsMemoryRead(ins)) { const UINT32 size = INS_MemoryReadSize(ins); const AFUNPTR countFun = (size <= 4 ? (AFUNPTR) MemRefSingle : (AFUNPTR) MemRefMulti); // only predicated-on memory instructions access D-cache INS_InsertPredicatedCall( ins, IPOINT_BEFORE, countFun, IARG_MEMORYREAD_EA, IARG_MEMORYREAD_SIZE, IARG_UINT32, CACHE_BASE::ACCESS_TYPE_LOAD, IARG_END); } if (INS_IsMemoryWrite(ins)) { const UINT32 size = INS_MemoryWriteSize(ins); const AFUNPTR countFun = (size <= 4 ? (AFUNPTR) MemRefSingle : (AFUNPTR) MemRefMulti); // only predicated-on memory instructions access D-cache INS_InsertPredicatedCall( ins, IPOINT_BEFORE, countFun, IARG_MEMORYWRITE_EA, IARG_MEMORYWRITE_SIZE, IARG_UINT32, CACHE_BASE::ACCESS_TYPE_STORE, IARG_END); } }
void instruction (INS ins, void *v) { if (INS_IsMemoryRead(ins)) { INS_InsertPredicatedCall(ins, IPOINT_BEFORE, AFUNPTR(on_load), IARG_THREAD_ID, IARG_INST_PTR, IARG_MEMORYREAD_EA, IARG_MEMORYREAD_SIZE, IARG_ADDRINT, INS_Opcode(ins), IARG_END); } if (INS_HasMemoryRead2(ins)) { INS_InsertPredicatedCall(ins, IPOINT_BEFORE, AFUNPTR(on_load), IARG_THREAD_ID, IARG_INST_PTR, IARG_MEMORYREAD2_EA, IARG_MEMORYREAD_SIZE, IARG_ADDRINT, INS_Opcode(ins), IARG_END); } if (INS_IsMemoryWrite(ins)) { //TODO get value. see SimpleExamples/pinatrace.cpp INS_InsertPredicatedCall(ins, IPOINT_BEFORE, AFUNPTR(on_store), IARG_THREAD_ID, IARG_INST_PTR, IARG_MEMORYWRITE_EA, IARG_MEMORYWRITE_SIZE, IARG_ADDRINT, INS_Opcode(ins), IARG_END); } }