/* * A routine to query the immediate operand per instruction. May be called at * instrumentation or analysis time. */ VOID GetOperLenAndSigned(INS ins, INT32 i, INT32& length_bits, bool& is_signed) { xed_decoded_inst_t* xedd = INS_XedDec(ins); // To print out the gory details uncomment this: // char buf[2048]; // xed_decoded_inst_dump(xedd, buf, 2048); // *outFile << buf << endl; length_bits = 8*xed_decoded_inst_operand_length(xedd, i); is_signed = xed_decoded_inst_get_immediate_is_signed(xedd); }
// Is called for every instruction and instruments reads and writes VOID Instruction(INS ins, VOID *v) { // Instruments memory accesses using a predicated call, i.e. // the instrumentation is called iff the instruction will actually be executed. // // On the IA-32 and Intel(R) 64 architectures conditional moves and REP // prefixed instructions appear as predicated instructions in Pin. UINT32 memOperands = INS_MemoryOperandCount(ins); // Iterate over each memory operand of the instruction. for (UINT32 memOp = 0; memOp < memOperands; memOp++) { /*if (INS_MemoryOperandIsRead(ins, memOp)) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead, IARG_INST_PTR, IARG_MEMORYOP_EA, memOp, IARG_END); }*/ // Note that in some architectures a single memory operand can be // both read and written (for instance incl (%eax) on IA-32) // In that case we instrument it once for read and once for write. if (INS_MemoryOperandIsWritten(ins, memOp)) { xed_decoded_inst_t* xedd = INS_XedDec(ins); xed_syntax_enum_t syntax = XED_SYNTAX_INTEL; // XED_SYNTAX_ATT, XED_SYNTAX_XED const UINT32 BUFLEN = 100; //char buffer[BUFLEN]; ADDRINT addr = INS_Address(ins); BOOL ok = xed_format(syntax, xedd, writeInstruction, BUFLEN, static_cast<UINT64>(addr)); if (ok){ } INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite, IARG_INST_PTR, IARG_MEMORYOP_EA, memOp, IARG_END); } } }
VOID Instruction(INS ins, VOID *v) { xed_decoded_inst_t* xedd = INS_XedDec(ins); // To print out the gory details uncomment this: // char buf[2048]; // xed_decoded_inst_dump(xedd, buf, 2048); // *out << buf << endl; xed_syntax_enum_t syntax = XED_SYNTAX_INTEL; // XED_SYNTAX_ATT, XED_SYNTAX_XED const UINT32 BUFLEN = 100; char buffer[BUFLEN]; ADDRINT addr = INS_Address(ins); BOOL ok = xed_format(syntax, xedd, buffer, BUFLEN, static_cast<UINT64>(addr)); if (ok) { *out << setw(sizeof(ADDRINT)*2) << hex << addr << dec << " " << buffer << endl; } else { *out << "disas-error @" << hex << addr << dec << endl; } }
static void rewrite_instruction(INS ins, bool is_read, sse_aligner_t* pthis) { // Avoid aligning trivially aligned stuff const xed_decoded_inst_t* xedd = INS_XedDec(ins); if (xed_decoded_inst_get_memory_operand_length(xedd,0) > sizeof (sse_aligned_buffer_t)) { return; } //fprintf(stderr,"Rewriting %p\n",(void*)INS_Address(ins)); if (pthis->verbose) *(pthis->out) << "REWRITE " << string(is_read ? "LOAD :" : "STORE:") << std::setw(16) << std::hex << INS_Address(ins) << std::dec << " " << INS_Disassemble(ins) << std::endl; if (is_read) { // Loads -- we change the load to use G0 as the base register and // then add a "before" function that sets G0 and copies the data to // an aligned bufffer. INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(copy_to_aligned_load_buffer_and_return_pointer), IARG_MEMORYREAD_EA, IARG_MEMORYREAD_SIZE, IARG_INST_PTR, IARG_THREAD_ID, IARG_PTR, pthis, IARG_RETURN_REGS, REG_INST_G0, IARG_END); } else { // Stores -- we change the store to use G0 as a base register and // then add a "before" function to set G0 and an "after" function // that copies the data from the aligned buffer to where it was // supposed to go. // Since we can't ask for the MEMORYWRITE_EA at IPOINT_AFTER, we save // that in REG_INST_G1 at IPOINT_BEFORE and then use it at IPOINT_AFTER. INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(return_pointer_to_aligned_store_buffer), IARG_MEMORYWRITE_EA, IARG_INST_PTR, IARG_THREAD_ID, IARG_PTR, pthis, IARG_REG_REFERENCE, REG_INST_G1, IARG_RETURN_REGS, REG_INST_G0, IARG_END); INS_InsertCall(ins, IPOINT_AFTER, AFUNPTR(copy_from_aligned_store_buffer), IARG_REG_VALUE, REG_INST_G1, IARG_MEMORYWRITE_SIZE, IARG_INST_PTR, IARG_THREAD_ID, IARG_PTR, pthis, IARG_END); } // Rewrite the memory operand (we assume there's only one) to use the address in REG_INST_G0 INS_RewriteMemoryOperand (ins, 0, REG_INST_G0); }
static void rewrite_instruction(INS ins, bool is_read, sse_aligner_t* pthis) { // Avoid aligning trivially aligned stuff const xed_decoded_inst_t* xedd = INS_XedDec(ins); if (xed_decoded_inst_get_memory_operand_length(xedd,0) > sizeof (sse_aligned_buffer_t)) { return; } //fprintf(stderr,"Rewriting %p\n",(void*)INS_Address(ins)); if (pthis->verbose) *(pthis->out) << "REWRITE: " << std::setw(16) << std::hex << INS_Address(ins) << std::dec << " " << INS_Disassemble(ins) << std::endl; // Loads -- we change the load to use G0 as the base register and // then add a "before" function that sets G0 and copies the data to // an aligned bufffer. if (is_read && INS_RewriteMemoryAddressingToBaseRegisterOnly(ins, MEMORY_TYPE_READ, REG_INST_G0)) { if (pthis->verbose) *(pthis->out) << "REWRITING LOAD" << std::endl; INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(copy_to_aligned_load_buffer_and_return_pointer), IARG_MEMORYREAD_EA, IARG_MEMORYREAD_SIZE, IARG_INST_PTR, IARG_THREAD_ID, IARG_PTR, pthis, IARG_RETURN_REGS, REG_INST_G0, IARG_END); } // Stores -- we change the store to use G1 as a base register and // then add a "before" function to set G1 and an "after" function // that copies the data from the aligned buffer to where it was // supposed to go. if (!is_read && INS_RewriteMemoryAddressingToBaseRegisterOnly(ins, MEMORY_TYPE_WRITE, REG_INST_G1)) { if (pthis->verbose) *(pthis->out) << "REWRITING STORE" << std::endl; INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(return_pointer_to_aligned_store_buffer), IARG_MEMORYWRITE_EA, IARG_INST_PTR, IARG_THREAD_ID, IARG_PTR, pthis, IARG_RETURN_REGS, REG_INST_G1, IARG_END); INS_InsertCall(ins, IPOINT_AFTER, AFUNPTR(copy_from_aligned_store_buffer), IARG_MEMORYWRITE_EA, IARG_MEMORYWRITE_SIZE, IARG_INST_PTR, IARG_THREAD_ID, IARG_PTR, pthis, IARG_END); } }