// We stored the instr count in *bb_field in bb_analysis(). int offline_instru_t::instrument_instr(void *drcontext, void *tag, void **bb_field, instrlist_t *ilist, instr_t *where, reg_id_t reg_ptr, reg_id_t reg_tmp, int adjust, instr_t *app) { app_pc pc, modbase; uint modidx; offline_entry_t entry; // We write just once per bb. if ((ptr_uint_t)*bb_field > MAX_INSTR_COUNT) return adjust; pc = dr_fragment_app_pc(tag); if (drmodtrack_lookup(drcontext, pc, &modidx, &modbase) != DRCOVLIB_SUCCESS) { // FIXME i#2062: add non-module support. The plan for instrs is to have // one entry w/ the start abs pc, and subsequent entries that pack the instr // length for 10 instrs, 4 bits each, into a pc.modoffs field. We will // also need to store the type (read/write/prefetch*) and size for the // memrefs. modidx = 0; modbase = pc; } entry.pc.type = OFFLINE_TYPE_PC; // We put the ARM vs Thumb mode into the modoffs to ensure proper decoding. entry.pc.modoffs = dr_app_pc_as_jump_target(instr_get_isa_mode(where), pc) - modbase; entry.pc.modidx = modidx; entry.pc.instr_count = (ptr_uint_t)*bb_field; insert_save_pc(drcontext, ilist, where, reg_ptr, reg_tmp, adjust, entry.combined_value); *(ptr_uint_t*)bb_field = MAX_INSTR_COUNT + 1; return (adjust + sizeof(offline_entry_t)); }
static void bb_table_entry_add(void *drcontext, per_thread_t *data, app_pc start, uint size) { bb_entry_t *bb_entry = drtable_alloc(data->bb_table, 1, NULL); uint mod_id; app_pc mod_start; drcovlib_status_t res = drmodtrack_lookup(drcontext, start, &mod_id, &mod_start); /* we do not de-duplicate repeated bbs */ ASSERT(size < USHRT_MAX, "size overflow"); bb_entry->size = (ushort)size; if (res == DRCOVLIB_SUCCESS) { ASSERT(mod_id < USHRT_MAX, "module id overflow"); bb_entry->mod_id = (ushort)mod_id; ASSERT(start > mod_start, "wrong module"); bb_entry->start = (uint)(start - mod_start); } else { /* XXX: we just truncate the address, which may have wrong value * in x64 arch. It should be ok now since it is an unknown module, * which will be ignored in the post-processing. * Should be handled for JIT code in the future. */ bb_entry->mod_id = UNKNOWN_MODULE_ID; bb_entry->start = (uint)(ptr_uint_t)start; } }