Esempio n. 1
0
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);
        }
    }