static PyObject *get_memory_operand_length(instruction_t *self, PyObject *args) { unsigned int i, length; xed_decoded_inst_t *decoded_inst; PyObject *r = NULL; if(PyArg_ParseTuple(args, "I", &i) == 0) goto _err; decoded_inst = self->decoded_inst; if(i >= xed_decoded_inst_number_of_memory_operands(decoded_inst)) { PyErr_SetString(PyExc_IndexError, "Invalid operand index"); goto _err; } length = xed_decoded_inst_get_memory_operand_length(decoded_inst, i); r = PyLong_FromUnsignedLong(length); _err: return r; }
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); } }