link_edge_t * table_get_edge(umbra_info_t *info, int id) { link_edge_t *edge_table; DR_ASSERT_MSG((id >= 0) && (id < info->table.max_num_edges), "Error: edge id out of range!"); edge_table = info->table.edge_table; while(id >= INIT_EDGE_TABLE_SIZE) { id -= INIT_EDGE_TABLE_SIZE; edge_table = (link_edge_t *)edge_table[INIT_EDGE_TABLE_SIZE - 1].dst_tag; } return &edge_table[id]; }
basic_block_t * table_get_bb(umbra_info_t *info, int id) { basic_block_t *bb_table; DR_ASSERT_MSG((id >= 0) && (id < info->table.max_num_bbs), "Error: bb id out of range!"); bb_table = info->table.bb_table; if (id % INIT_BB_TABLE_SIZE == (INIT_BB_TABLE_SIZE - 1)) return &bb_table[0]; while(id >= INIT_BB_TABLE_SIZE) { id -= INIT_BB_TABLE_SIZE; bb_table = (basic_block_t *)bb_table[INIT_BB_TABLE_SIZE - 1].tag; } return &bb_table[id]; }
static void handle_post_write(void *drcontext, instrlist_t *ilist, instr_t *where, reg_id_t reg_addr) { int i; instr_t *prev_instr = instr_get_prev_app(where); bool seen_memref = false; /* XXX: We assume that no write instruction has multiple distinct memory destinations. * This way we are able to persist a single register across an app instruction. Note * there are instructions which currently do break this assumption, but we punt on * this. */ for (i = 0; i < instr_num_dsts(prev_instr); ++i) { if (opnd_is_memory_reference(instr_get_dst(prev_instr, i))) { if (seen_memref) { DR_ASSERT_MSG(false, "Found inst with multiple memory destinations"); break; } seen_memref = true; instrument_post_write(drcontext, ilist, where, instr_get_dst(prev_instr, i), prev_instr, reg_addr); } } }