コード例 #1
0
ファイル: drx_buf-test.dll.c プロジェクト: stoyannk/dynamorio
static dr_emit_flags_t
event_app_analysis(void *drcontext, void *tag, instrlist_t *bb,
                   bool for_trace, bool translating, OUT void **user_data)
{
    instr_t *inst, *label;
    bool prev_was_mov_const = false;
    ptr_int_t val1, val2;
    *user_data = NULL;
    /* Look for duplicate mov immediates telling us which subtest we're in */
    for (inst = instrlist_first_app(bb); inst != NULL; inst = instr_get_next_app(inst)) {
        if (instr_is_mov_constant(inst, prev_was_mov_const ? &val2 : &val1)) {
            if (prev_was_mov_const && val1 == val2 &&
                val1 != 0 && /* rule out xor w/ self */
                opnd_is_reg(instr_get_dst(inst, 0)) &&
                opnd_get_reg(instr_get_dst(inst, 0)) == TEST_REG) {
                *user_data = (void *) val1;
                label = INSTR_CREATE_label(drcontext);
                instr_set_translation(label, instr_get_app_pc(inst));
                instrlist_meta_postinsert(bb, inst, label);
            } else
                prev_was_mov_const = true;
        } else
            prev_was_mov_const = false;
    }
    return DR_EMIT_DEFAULT;
}
コード例 #2
0
ファイル: instrcalls.c プロジェクト: chubbymaggie/patharmor
static dr_emit_flags_t
event_basic_block(void *drcontext, void *tag, instrlist_t *bb,
                  bool for_trace, bool translating)
{
    instr_t *instr, *next_instr;
#ifdef VERBOSE
    dr_printf("in dr_basic_block(tag="PFX")\n", tag);
# if VERBOSE_VERBOSE
    instrlist_disassemble(drcontext, tag, bb, STDOUT);
# endif
#endif
    for (instr = instrlist_first_app(bb); instr != NULL; instr = next_instr) {
        next_instr = instr_get_next_app(instr);
        if (!instr_opcode_valid(instr))
            continue;
        /* instrument calls and returns -- ignore far calls/rets */
        if (instr_is_call_direct(instr)) {
            dr_insert_call_instrumentation(drcontext, bb, instr, (app_pc)at_call);
        } else if (instr_is_call_indirect(instr)) {
            dr_insert_mbr_instrumentation(drcontext, bb, instr, (app_pc)at_call_ind,
                                          SPILL_SLOT_1);
        } else if (instr_is_return(instr)) {
            dr_insert_mbr_instrumentation(drcontext, bb, instr, (app_pc)at_return,
                                          SPILL_SLOT_1);
        }
    }
    return DR_EMIT_DEFAULT;
}
コード例 #3
0
ファイル: instrlist.c プロジェクト: DynamoRIO/dynamorio
/* returns the first app (non-meta) inst in the list */
instr_t *
instrlist_first_app(instrlist_t *ilist)
{
    instr_t *first = ilist->first;

    if (first == NULL)
        return NULL;
    if (instr_is_app(first))
        return first;

    return instr_get_next_app(first);
}
コード例 #4
0
ファイル: drcovlib.c プロジェクト: stoyannk/dynamorio
/* We collect the basic block information including offset from module base,
 * size, and num of instructions, and add it into a basic block table without
 * instrumentation.
 */
static dr_emit_flags_t
event_basic_block_analysis(void *drcontext, void *tag, instrlist_t *bb,
                           bool for_trace, bool translating, OUT void **user_data)
{
    per_thread_t *data;
    instr_t *instr;
    app_pc tag_pc, start_pc, end_pc;

    /* do nothing for translation */
    if (translating)
        return DR_EMIT_DEFAULT;

    data = (per_thread_t *)drmgr_get_tls_field(drcontext, tls_idx);
    /* Collect the number of instructions and the basic block size,
     * assuming the basic block does not have any elision on control
     * transfer instructions, which is true for default options passed
     * to DR but not for -opt_speed.
     */
    /* We separate the tag from the instr pc ranges to handle displaced code
     * such as for the vsyscall hook.
     */
    tag_pc = dr_fragment_app_pc(tag);
    start_pc = instr_get_app_pc(instrlist_first_app(bb));
    end_pc   = start_pc; /* for finding the size */
    for (instr  = instrlist_first_app(bb);
         instr != NULL;
         instr  = instr_get_next_app(instr)) {
        app_pc pc = instr_get_app_pc(instr);
        int len = instr_length(drcontext, instr);
        /* -opt_speed (elision) is not supported */
        /* For rep str expansion pc may be one back from start pc but equal to the tag. */
        ASSERT(pc != NULL && (pc >= start_pc || pc == tag_pc),
               "-opt_speed is not supported");
        if (pc + len > end_pc)
            end_pc = pc + len;
    }
    /* We allow duplicated basic blocks for the following reasons:
     * 1. Avoids handling issues like code cache consistency, e.g.,
     *    module load/unload, self-modifying code, etc.
     * 2. Avoids the overhead on duplication check.
     * 3. Stores more information on code cache events, e.g., trace building,
     *    repeated bb building, etc.
     * 4. The duplication can be easily handled in a post-processing step,
     *    which is required anyway.
     */
    bb_table_entry_add(drcontext, data, tag_pc, (uint)(end_pc - start_pc));

    if (go_native)
        return DR_EMIT_GO_NATIVE;
    else
        return DR_EMIT_DEFAULT;
}
コード例 #5
0
ファイル: modxfer_app2lib.c プロジェクト: DynamoRIO/dynamorio
/* This event is passed the instruction list for the whole bb. */
static dr_emit_flags_t
event_analyze_bb(void *drcontext, void *tag, instrlist_t *bb, bool for_trace,
                 bool translating, void **user_data)
{
    /* Count the instructions and pass the result to event_insert_instrumentation. */
    instr_t *instr;
    uint num_instrs;
    for (instr = instrlist_first_app(bb), num_instrs = 0; instr != NULL;
         instr = instr_get_next_app(instr)) {
        num_instrs++;
    }
    *(uint *)user_data = num_instrs;
    return DR_EMIT_DEFAULT;
}
コード例 #6
0
ファイル: inline.c プロジェクト: stoyannk/dynamorio
static dr_emit_flags_t
event_analyze_bb(void *drcontext, void *tag, instrlist_t *bb,
                 bool for_trace, bool translating, void **user_data)
{
    instr_t *instr;
    trace_head_entry_t *e = NULL;
    if (translating)
        return DR_EMIT_DEFAULT;
    for (instr  = instrlist_first_app(bb);
         instr != NULL;
         instr  = instr_get_next_app(instr)) {
        /* Blocks containing calls are trace heads. */
        if (instr_is_call(instr)) {
            dr_mark_trace_head(drcontext, tag);
            hashtable_lock(&head_table);
            e = hashtable_lookup(&head_table, tag);
            if (e == NULL) {
                e = create_trace_head_entry(tag);
                if (!hashtable_add(&head_table, tag, (void *)e))
                    DR_ASSERT(false);
            } else
                e->refcount++;
            e->is_trace_head = true;
            hashtable_unlock(&head_table);
#ifdef VERBOSE
            dr_log(drcontext, DR_LOG_ALL, 3,
                   "inline: marking bb "PFX" as call trace head\n", tag);
#endif
            /* Doesn't matter what's in rest of the bb. */
            return DR_EMIT_DEFAULT;
        } else if (instr_is_return(instr)) {
            hashtable_lock(&head_table);
            e = hashtable_lookup(&head_table, tag);
            if (e == NULL) {
                e = create_trace_head_entry(tag);
                if (!hashtable_add(&head_table, tag, (void *)e))
                    DR_ASSERT(false);
            } else
                e->refcount++;
            e->has_ret = true;
            hashtable_unlock(&head_table);
#ifdef VERBOSE
            dr_log(drcontext, DR_LOG_ALL, 3,
                   "inline: marking bb "PFX" as return trace head\n", tag);
#endif
        }
    }
    return DR_EMIT_DEFAULT;
}
コード例 #7
0
ファイル: cbrtrace.c プロジェクト: AVGirl/dynamorio
static dr_emit_flags_t
event_basic_block(void *drcontext, void *tag, instrlist_t *bb,
                  bool for_trace, bool translating)
{
    instr_t *instr;
    for (instr  = instrlist_first_app(bb);
         instr != NULL;
         instr  = instr_get_next_app(instr)) {
        if (instr_is_cbr(instr)) {
            dr_insert_cbr_instrumentation_ex
                (drcontext, bb, instr, (void *)at_cbr,
                 OPND_CREATE_INTPTR(dr_fragment_app_pc(tag)));
        }
    }
    return DR_EMIT_DEFAULT;
}
コード例 #8
0
ファイル: modxfer_app2lib.c プロジェクト: AVGirl/dynamorio
static dr_emit_flags_t
event_basic_block(void *drcontext, void *tag, instrlist_t *bb,
                  bool for_trace, bool translating)
{
    instr_t *instr, *mbr = NULL;
    uint num_instrs;
    bool bb_in_app;

#ifdef VERBOSE
    dr_printf("in dynamorio_basic_block(tag="PFX")\n", tag);
# ifdef VERBOSE_VERBOSE
    instrlist_disassemble(drcontext, tag, bb, STDOUT);
# endif
#endif

    for (instr  = instrlist_first_app(bb), num_instrs = 0;
         instr != NULL;
         instr  = instr_get_next_app(instr)) {
        num_instrs++;
        /* Assuming most of the transfers between app and lib are paired, we
         * instrument indirect branches but not returns for better performance.
         */
        if (instr_is_mbr(instr) && !instr_is_return(instr))
            mbr = instr;
    }

    if (dr_fragment_app_pc(tag) >= app_base &&
        dr_fragment_app_pc(tag) <  app_end)
        bb_in_app = true;
    else
        bb_in_app = false;
    dr_insert_clean_call(drcontext, bb, instrlist_first(bb),
                         (void *)(bb_in_app ? app_update : lib_update),
                         false /* save fpstate */, 1,
                         OPND_CREATE_INT32(num_instrs));
    if (mbr != NULL) {
        dr_insert_mbr_instrumentation(drcontext, bb, mbr,
                                      (void *)(bb_in_app ? app_mbr : lib_mbr),
                                      SPILL_SLOT_1);
    }

#if defined(VERBOSE) && defined(VERBOSE_VERBOSE)
    dr_printf("Finished instrumenting dynamorio_basic_block(tag="PFX")\n", tag);
    instrlist_disassemble(drcontext, tag, bb, STDOUT);
#endif
    return DR_EMIT_DEFAULT;
}
コード例 #9
0
ファイル: instru_offline.cpp プロジェクト: mdlui/dynamorio
void
offline_instru_t::bb_analysis(void *drcontext, void *tag, void **bb_field,
                             instrlist_t *ilist, bool repstr_expanded)
{
    instr_t *instr;
    ptr_uint_t count = 0;
    app_pc last_xl8 = NULL;
    if (repstr_expanded) {
        // The same-translation check below is not sufficient as drutil uses
        // two different translations to deal with complexities.
        // Thus we hardcode this.
        count = 1;
    } else {
        for (instr = instrlist_first_app(ilist); instr != NULL;
             instr = instr_get_next_app(instr)) {
            // To deal with app2app changes, we do not double-count consecutive instrs
            // with the same translation.
            if (instr_get_app_pc(instr) != last_xl8)
                ++count;
            last_xl8 = instr_get_app_pc(instr);
        }
    }
    *bb_field = (void *)count;
}
コード例 #10
0
ファイル: stats.c プロジェクト: FirstBlue/dynamorio
/* This event is passed the instruction list for the whole bb. */
static dr_emit_flags_t
event_analyze_bb(void *drcontext, void *tag, instrlist_t *bb,
                 bool for_trace, bool translating, void **user_data)
{
    /* Count the instructions and pass the result to event_insert_instrumentation. */
    per_bb_data_t *per_bb = dr_thread_alloc(drcontext, sizeof(*per_bb));
    instr_t *instr;
    uint num_instrs = 0;
    uint num_flops = 0;
    uint num_syscalls = 0;
    dr_fp_type_t fp_type;

    for (instr  = instrlist_first_app(bb);
         instr != NULL;
         instr  = instr_get_next_app(instr)) {
        num_instrs++;
        if (instr_is_floating_ex(instr, &fp_type) &&
            /* We exclude loads and stores (and reg-reg moves) and state preservation */
            (fp_type == DR_FP_CONVERT || fp_type == DR_FP_MATH)) {
#ifdef VERBOSE
            dr_print_instr(drcontext, STDOUT, instr, "Found flop: ");
#endif
            num_flops++;
        }
        if (instr_is_syscall(instr)) {
            num_syscalls++;
        }
    }

    per_bb->num_instrs = num_instrs;
    per_bb->num_flops = num_flops;
    per_bb->num_syscalls = num_syscalls;
    *(per_bb_data_t**)user_data = per_bb;

    return DR_EMIT_DEFAULT;
}
コード例 #11
0
ファイル: countcalls.c プロジェクト: Safe3/dynamorio
static dr_emit_flags_t
event_basic_block(void *drcontext, void *tag, instrlist_t *bb,
                  bool for_trace, bool translating)
{
    instr_t *instr, *next_instr;

#ifdef VERBOSE
    dr_printf("in dynamorio_basic_block(tag="PFX")\n", tag);
# ifdef VERBOSE_VERBOSE
    instrlist_disassemble(drcontext, tag, bb, STDOUT);
# endif
#endif

    for (instr = instrlist_first_app(bb); instr != NULL; instr = next_instr) {
        /* grab next now so we don't go over instructions we insert */
        next_instr = instr_get_next_app(instr);

        /* instrument calls and returns -- ignore far calls/rets */
        if (instr_is_call_direct(instr)) {
            insert_counter_update(drcontext, bb, instr,
                                  offsetof(per_thread_t, num_direct_calls));
        } else if (instr_is_call_indirect(instr)) {
            insert_counter_update(drcontext, bb, instr,
                                  offsetof(per_thread_t, num_indirect_calls));
        } else if (instr_is_return(instr)) {
            insert_counter_update(drcontext, bb, instr,
                                  offsetof(per_thread_t, num_returns));
        }
    }

#if defined(VERBOSE) && defined(VERBOSE_VERBOSE)
    dr_printf("Finished instrumenting dynamorio_basic_block(tag="PFX")\n", tag);
    instrlist_disassemble(drcontext, tag, bb, STDOUT);
#endif
    return DR_EMIT_DEFAULT;
}