VOID Instruction(INS ins, void * v) { UINT32 memOperands = INS_MemoryOperandCount(ins); // Instrument each memory operand. If the operand is both read and written // it will be processed twice. // Iterating over memory operands ensures that instructions on IA-32 with // two read operands (such as SCAS and CMPS) are correctly handled. for (UINT32 memOp = 0; memOp < memOperands; memOp++) { const UINT32 size = INS_MemoryOperandSize(ins, memOp); const BOOL single = (size <= 4); if (INS_MemoryOperandIsRead(ins, memOp)) { if( KnobTrackLoads ) { // map sparse INS addresses to dense IDs const ADDRINT iaddr = INS_Address(ins); const UINT32 instId = profile.Map(iaddr); if( single ) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) LoadSingle, IARG_MEMORYOP_EA, memOp, IARG_UINT32, instId, IARG_END); } else { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) LoadMulti, IARG_MEMORYOP_EA, memOp, IARG_UINT32, size, IARG_UINT32, instId, IARG_END); } } else { if( single ) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) LoadSingleFast, IARG_MEMORYOP_EA, memOp, IARG_END); } else { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) LoadMultiFast, IARG_MEMORYOP_EA, memOp, IARG_UINT32, size, IARG_END); } } } if (INS_MemoryOperandIsWritten(ins, memOp)) { if( KnobTrackStores ) { const ADDRINT iaddr = INS_Address(ins); const UINT32 instId = profile.Map(iaddr); if( single ) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) StoreSingle, IARG_MEMORYOP_EA, memOp, IARG_UINT32, instId, IARG_END); } else { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) StoreMulti, IARG_MEMORYOP_EA,memOp, IARG_UINT32, size, IARG_UINT32, instId, IARG_END); } } else { if( single ) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) StoreSingleFast, IARG_MEMORYOP_EA, memOp, IARG_END); } else { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) StoreMultiFast, IARG_MEMORYOP_EA, memOp, IARG_UINT32, size, IARG_END); } } } } }
VOID Instruction(INS ins, void * v) { if (INS_IsMemoryRead(ins) && INS_IsStandardMemop(ins)) { // map sparse INS addresses to dense IDs const ADDRINT iaddr = INS_Address(ins); const UINT32 instId = profile.Map(iaddr); const UINT32 size = INS_MemoryReadSize(ins); const BOOL single = (size <= 4); if( KnobTrackLoads ) { if( single ) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) LoadSingle, IARG_MEMORYREAD_EA, IARG_UINT32, instId, IARG_END); } else { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) LoadMulti, IARG_MEMORYREAD_EA, IARG_MEMORYREAD_SIZE, IARG_UINT32, instId, IARG_END); } } else { if( single ) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) LoadSingleFast, IARG_MEMORYREAD_EA, IARG_END); } else { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) LoadMultiFast, IARG_MEMORYREAD_EA, IARG_MEMORYREAD_SIZE, IARG_END); } } } if ( INS_IsMemoryWrite(ins) && INS_IsStandardMemop(ins)) { // map sparse INS addresses to dense IDs const ADDRINT iaddr = INS_Address(ins); const UINT32 instId = profile.Map(iaddr); const UINT32 size = INS_MemoryWriteSize(ins); const BOOL single = (size <= 4); if( KnobTrackStores ) { if( single ) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) StoreSingle, IARG_MEMORYWRITE_EA, IARG_UINT32, instId, IARG_END); } else { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) StoreMulti, IARG_MEMORYWRITE_EA, IARG_MEMORYWRITE_SIZE, IARG_UINT32, instId, IARG_END); } } else { if( single ) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) StoreSingleFast, IARG_MEMORYWRITE_EA, IARG_END); } else { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR) StoreMultiFast, IARG_MEMORYWRITE_EA, IARG_MEMORYWRITE_SIZE, IARG_END); } } } }