コード例 #1
0
ファイル: it_arm.c プロジェクト: stoyannk/dynamorio
void
test_dr_insert_it_instrs_cbr(void *dcontext)
{
    instrlist_t *ilist = instrlist_create(dcontext);
    instr_t *where = INSTR_CREATE_label(dcontext);

    instr_t *instr_it1, *instr_it2, *instr_it3;
    byte buffer[4096];

    instrlist_append(ilist, where);
    instrlist_preinsert(ilist, where, XINST_CREATE_move
            (dcontext,
             opnd_create_reg(DR_REG_R1),
             opnd_create_reg(DR_REG_R2)));
    instrlist_preinsert(ilist, where, XINST_CREATE_jump
            (dcontext,
             opnd_create_instr(where)));
    instrlist_preinsert(ilist, where, XINST_CREATE_move
            (dcontext,
             opnd_create_reg(DR_REG_R1),
             opnd_create_reg(DR_REG_R2)));
    instrlist_preinsert(ilist, where, XINST_CREATE_move
            (dcontext,
             opnd_create_reg(DR_REG_R1),
             opnd_create_reg(DR_REG_R2)));
    instrlist_preinsert(ilist, where, XINST_CREATE_jump
            (dcontext,
             opnd_create_instr(where)));
    instrlist_preinsert(ilist, where, XINST_CREATE_move
            (dcontext,
             opnd_create_reg(DR_REG_R1),
             opnd_create_reg(DR_REG_R2)));
    instrlist_preinsert(ilist, where, XINST_CREATE_move
            (dcontext,
             opnd_create_reg(DR_REG_R1),
             opnd_create_reg(DR_REG_R2)));
    instrlist_preinsert(ilist, where, XINST_CREATE_move
            (dcontext,
             opnd_create_reg(DR_REG_R1),
             opnd_create_reg(DR_REG_R2)));
    instrlist_preinsert(ilist, where, XINST_CREATE_jump
            (dcontext,
             opnd_create_instr(where)));
    /* set them all to be predicated and reinstate it instrs */
    for (where = instrlist_first(ilist); where; where = instr_get_next(where)) {
        bool ok = instr_set_isa_mode(where, DR_ISA_ARM_THUMB);
        DR_ASSERT(ok);
        instr_set_predicate(where, DR_PRED_LS);
    }
    dr_insert_it_instrs(dcontext, ilist);

    /* Make sure it was encoded properly, noting that the branches
     * should *not* be in any IT-block.
     *  it
     *  mov.ls r1, r2
     *  b.ls   @0x47366864
     *  itt
     *  mov.ls r1, r2
     *  mov.ls r1, r2
     *  b.ls   @0x47366864
     *  ittt
     *  mov.ls r1, r2
     *  mov.ls r1, r2
     *  mov.ls r1, r2
     *  b.ls   @0x47366864
     */
    instr_it1 = instrlist_first(ilist);
    instr_it2 = instr_get_next(instr_get_next(instr_get_next(instr_it1)));
    instr_it3 = instr_get_next(instr_get_next(instr_get_next(instr_get_next(instr_it2))));
    DR_ASSERT(instr_get_opcode(instr_it1) == OP_it);
    DR_ASSERT(instr_it_block_get_count(instr_it1) == 1);
    DR_ASSERT(instr_get_opcode(instr_it2) == OP_it);
    DR_ASSERT(instr_it_block_get_count(instr_it2) == 2);
    DR_ASSERT(instr_get_opcode(instr_it3) == OP_it);
    DR_ASSERT(instr_it_block_get_count(instr_it3) == 3);
    instrlist_encode(dcontext, ilist, buffer, true);
}
コード例 #2
0
ファイル: memval_simple.c プロジェクト: DynamoRIO/dynamorio
static reg_id_t
instrument_mem(void *drcontext, instrlist_t *ilist, instr_t *where, opnd_t ref)
{
    reg_id_t reg_ptr, reg_tmp, reg_addr;
    ushort type, size;
    bool ok;

    if (drreg_reserve_register(drcontext, ilist, where, NULL, &reg_tmp) !=
        DRREG_SUCCESS) {
        DR_ASSERT(false);
        return DR_REG_NULL;
    }
    if (drreg_reserve_register(drcontext, ilist, where, NULL, &reg_ptr) !=
        DRREG_SUCCESS) {
        DR_ASSERT(false);
        return DR_REG_NULL;
    }

    /* i#2449: In the situation that instrument_post_write, instrument_mem and ref all
     * have the same register reserved, drutil_insert_get_mem_addr will compute the
     * address of an operand using an incorrect register value, as drreg will elide the
     * save/restore.
     */
    if (opnd_uses_reg(ref, reg_tmp) &&
        drreg_get_app_value(drcontext, ilist, where, reg_tmp, reg_tmp) != DRREG_SUCCESS) {
        DR_ASSERT(false);
        return DR_REG_NULL;
    }
    if (opnd_uses_reg(ref, reg_ptr) &&
        drreg_get_app_value(drcontext, ilist, where, reg_ptr, reg_ptr) != DRREG_SUCCESS) {
        DR_ASSERT(false);
        return DR_REG_NULL;
    }

    /* We use reg_ptr as scratch to get addr. Note we do this first as reg_ptr or reg_tmp
     * may be used in ref.
     */
    ok = drutil_insert_get_mem_addr(drcontext, ilist, where, ref, reg_tmp, reg_ptr);
    DR_ASSERT(ok);
    drx_buf_insert_load_buf_ptr(drcontext, trace_buffer, ilist, where, reg_ptr);
    /* inserts memref addr */
    drx_buf_insert_buf_store(drcontext, trace_buffer, ilist, where, reg_ptr, DR_REG_NULL,
                             opnd_create_reg(reg_tmp), OPSZ_PTR,
                             offsetof(mem_ref_t, addr));
    if (IF_AARCHXX_ELSE(true, false)) {
        /* At this point we save the write address for later, because reg_tmp's value
         * will get clobbered on ARM.
         */
        if (drreg_reserve_register(drcontext, ilist, where, NULL, &reg_addr) !=
            DRREG_SUCCESS) {
            DR_ASSERT(false);
            return DR_REG_NULL;
        }
        MINSERT(ilist, where,
                XINST_CREATE_move(drcontext, opnd_create_reg(reg_addr),
                                  opnd_create_reg(reg_tmp)));
    }
    /* inserts type */
    type = (ushort)instr_get_opcode(where);
    drx_buf_insert_buf_store(drcontext, trace_buffer, ilist, where, reg_ptr, reg_tmp,
                             OPND_CREATE_INT16(type), OPSZ_2, offsetof(mem_ref_t, type));
    /* inserts size */
    size = (ushort)drutil_opnd_mem_size_in_bytes(ref, where);
    drx_buf_insert_buf_store(drcontext, trace_buffer, ilist, where, reg_ptr, reg_tmp,
                             OPND_CREATE_INT16(size), OPSZ_2, offsetof(mem_ref_t, size));
    drx_buf_insert_update_buf_ptr(drcontext, trace_buffer, ilist, where, reg_ptr,
                                  DR_REG_NULL, sizeof(mem_ref_t));

    if (instr_is_call(where)) {
        app_pc pc;

        /* Note that on ARM the call instruction writes only to the link register, so
         * we would never even get into instrument_mem() on ARM if this was a call.
         */
        IF_AARCHXX(DR_ASSERT(false));
        /* We simulate the call instruction's written memory by writing the next app_pc
         * to the written buffer, since we can't do this after the call has happened.
         */
        drx_buf_insert_load_buf_ptr(drcontext, write_buffer, ilist, where, reg_ptr);
        pc = decode_next_pc(drcontext, instr_get_app_pc(where));
        /* note that for a circular buffer, we don't need to specify a scratch register */
        drx_buf_insert_buf_store(drcontext, trace_buffer, ilist, where, reg_ptr,
                                 DR_REG_NULL, OPND_CREATE_INTPTR((ptr_int_t)pc), OPSZ_PTR,
                                 0);
        drx_buf_insert_update_buf_ptr(drcontext, write_buffer, ilist, where, reg_ptr,
                                      reg_tmp, sizeof(app_pc));
        /* we don't need to persist reg_tmp to the next instruction */
        if (drreg_unreserve_register(drcontext, ilist, where, reg_tmp) != DRREG_SUCCESS)
            DR_ASSERT(false);
        reg_tmp = DR_REG_NULL;
    } else if (IF_AARCHXX_ELSE(true, false)) {
        /* Now reg_tmp has the address of the write again. */
        MINSERT(ilist, where,
                XINST_CREATE_move(drcontext, opnd_create_reg(reg_tmp),
                                  opnd_create_reg(reg_addr)));
        if (drreg_unreserve_register(drcontext, ilist, where, reg_addr) != DRREG_SUCCESS)
            DR_ASSERT(false);
    }
    if (drreg_unreserve_register(drcontext, ilist, where, reg_ptr) != DRREG_SUCCESS)
        DR_ASSERT(false);
    return reg_tmp;
}