Пример #1
0
static dr_emit_flags_t
event_bb_insert(void *drcontext, void *tag, instrlist_t *bb, instr_t *inst,
                bool for_trace, bool translating, void *user_data)
{
    static int freq;
    reg_id_t reg1 = IF_X86_ELSE(DR_REG_XAX, DR_REG_R0);
    reg_id_t reg2 = IF_X86_ELSE(DR_REG_XCX, DR_REG_R1);

    CHECK(drmgr_is_first_instr(drcontext, instrlist_first_app(bb)), "first incorrect");
    CHECK(!drmgr_is_first_instr(drcontext, instrlist_last(bb)) ||
          instrlist_first_app(bb) == instrlist_last(bb), "first incorrect");
    CHECK(drmgr_is_last_instr(drcontext, instrlist_last(bb)), "last incorrect");
    CHECK(!drmgr_is_last_instr(drcontext, instrlist_first_app(bb)) ||
          instrlist_first_app(bb) == instrlist_last(bb), "last incorrect");

    /* hack to instrument every nth bb.  assumes DR serializes bb events. */
    freq++;
    if (freq % 100 == 0 && inst == (instr_t*)user_data/*first instr*/) {
        /* test read from cache */
        dr_save_reg(drcontext, bb, inst, reg1, SPILL_SLOT_1);
        drmgr_insert_read_tls_field(drcontext, tls_idx, bb, inst, reg1);
        dr_insert_clean_call(drcontext, bb, inst, (void *)check_tls_from_cache,
                             false, 1, opnd_create_reg(reg1));
        drmgr_insert_read_cls_field(drcontext, cls_idx, bb, inst, reg1);
        dr_insert_clean_call(drcontext, bb, inst, (void *)check_cls_from_cache,
                             false, 1, opnd_create_reg(reg1));
        dr_restore_reg(drcontext, bb, inst, reg1, SPILL_SLOT_1);
    }
    if (freq % 300 == 0 && inst == (instr_t*)user_data/*first instr*/) {
        instr_t *first, *second;
        /* test write from cache */
        dr_save_reg(drcontext, bb, inst, reg1, SPILL_SLOT_1);
        dr_save_reg(drcontext, bb, inst, reg2, SPILL_SLOT_2);
        instrlist_insert_mov_immed_ptrsz(drcontext,
                                         (ptr_int_t)MAGIC_NUMBER_FROM_CACHE,
                                         opnd_create_reg(reg1),
                                         bb, inst, &first, &second);
        instr_set_meta(first);
        if (second != NULL)
            instr_set_meta(second);
        drmgr_insert_write_tls_field(drcontext, tls_idx, bb, inst, reg1, reg2);
        dr_insert_clean_call(drcontext, bb, inst, (void *)check_tls_write_from_cache,
                             false, 0);
        drmgr_insert_write_cls_field(drcontext, cls_idx, bb, inst, reg1, reg2);
        dr_insert_clean_call(drcontext, bb, inst, (void *)check_cls_write_from_cache,
                             false, 0);
        dr_restore_reg(drcontext, bb, inst, reg2, SPILL_SLOT_2);
        dr_restore_reg(drcontext, bb, inst, reg1, SPILL_SLOT_1);
    }
    return DR_EMIT_DEFAULT;
}
Пример #2
0
static dr_emit_flags_t
event_app_instruction(void *drcontext, void *tag, instrlist_t *bb, instr_t *instr,
                      bool for_trace, bool translating, void *user_data)
{
    /* We test reserving across app instrs by reserving on each store and
     * unreserving on the subsequent instr.
     */
    drvector_t allowed;
    if (reg != DR_REG_NULL) {
        if (drreg_unreserve_register(drcontext, bb, instr, reg) != DRREG_SUCCESS)
            CHECK(false, "failed to unreserve");
        reg = DR_REG_NULL;
    }

    if (!instr_is_app(instr))
        return DR_EMIT_DEFAULT;
    if (!instr_writes_memory(instr))
        return DR_EMIT_DEFAULT;

    if (!drmgr_is_last_instr(drcontext, instr)) {
        drreg_init_and_fill_vector(&allowed, true);
        /* Limit the registers for more of a stress test: */
        drreg_set_vector_entry(&allowed, IF_X86_ELSE(DR_REG_XCX, DR_REG_R0), false);
        drreg_set_vector_entry(&allowed, IF_X86_ELSE(DR_REG_XDX, DR_REG_R1), false);
        if (drreg_reserve_register(drcontext, bb, instr, &allowed, &reg) != DRREG_SUCCESS)
            DR_ASSERT(false);
        drvector_delete(&allowed);
    }
    return DR_EMIT_DEFAULT;
}
Пример #3
0
/* This event is called separately for each individual instruction in the bb. */
static dr_emit_flags_t
event_insert_instrumentation(void *drcontext, void *tag, instrlist_t *bb,
                             instr_t *instr, bool for_trace, bool translating,
                             void *user_data)
{
    per_bb_data_t *per_bb = (per_bb_data_t *)user_data;
    /* We increment the per-bb counters just once, at the top of the bb. */
    if (drmgr_is_first_instr(drcontext, instr)) {
        /* drx will analyze whether to save the flags for us. */
        uint flags = DRX_COUNTER_LOCK;
        if (per_bb->num_instrs > 0) {
            drx_insert_counter_update(drcontext, bb, instr, SPILL_SLOT_MAX+1,
                                      &stats->num_instrs, per_bb->num_instrs, flags);
        }
        if (per_bb->num_flops > 0) {
            drx_insert_counter_update(drcontext, bb, instr, SPILL_SLOT_MAX+1,
                                      &stats->num_flops, per_bb->num_flops, flags);
        }
        if (per_bb->num_syscalls > 0) {
            drx_insert_counter_update(drcontext, bb, instr, SPILL_SLOT_MAX+1,
                                      &stats->num_syscalls, per_bb->num_syscalls, flags);
        }
    }
    if (drmgr_is_last_instr(drcontext, instr))
        dr_thread_free(drcontext, per_bb, sizeof(*per_bb));
    return DR_EMIT_DEFAULT;
}