From c3e95ec34ee0be3ac74e57bd9987e1fce176952c Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Tue, 25 Aug 2015 14:50:55 +0800 Subject: [PATCH] x86: do not generate basic-block callback when translation is broken in the middle due to full cache --- include/uc_priv.h | 2 ++ qemu/target-i386/translate.c | 8 +++++++- uc.c | 1 + 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/uc_priv.h b/include/uc_priv.h index 1494cc65..2703627c 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -163,6 +163,8 @@ struct uc_struct { uint64_t addr_end; // address where emulation stops (@end param of uc_emu_start()) int thumb; // thumb mode for ARM + // full TCG cache leads to middle-block break in the last translation? + bool block_full; }; #include "qemu_macro.h" diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c index 15b941c4..7ce37ef8 100644 --- a/qemu/target-i386/translate.c +++ b/qemu/target-i386/translate.c @@ -8256,6 +8256,7 @@ static inline void gen_intermediate_code_internal(uint8_t *gen_opc_cc_op, target_ulong cs_base; int num_insns; int max_insns; + bool block_full = false; /* generate intermediate code */ pc_start = tb->pc; @@ -8349,7 +8350,9 @@ static inline void gen_intermediate_code_internal(uint8_t *gen_opc_cc_op, max_insns = CF_COUNT_MASK; // Unicorn: trace this block on request - if (env->uc->hook_block) { + // Only hook this block if it is not broken from previous translation due to + // full translation cache + if (env->uc->hook_block && !env->uc->block_full) { struct hook_struct *trace = hook_find((uch)env->uc, UC_HOOK_BLOCK, pc_start); if (trace) { env->uc->block_addr = pc_start; @@ -8407,6 +8410,7 @@ static inline void gen_intermediate_code_internal(uint8_t *gen_opc_cc_op, num_insns >= max_insns) { gen_jmp_im(dc, pc_ptr - dc->cs_base); gen_eob(dc); + block_full = true; break; } } @@ -8427,6 +8431,8 @@ done_generating: tb->size = pc_ptr - pc_start; // tb->icount = num_insns; } + + env->uc->block_full = block_full; } void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb) diff --git a/uc.c b/uc.c index 2011c693..65179095 100644 --- a/uc.c +++ b/uc.c @@ -414,6 +414,7 @@ uc_err uc_emu_start(uch handle, uint64_t begin, uint64_t until, uint64_t timeout uc->emu_counter = 0; uc->stop_request = false; uc->invalid_error = UC_ERR_OK; + uc->block_full = false; switch(uc->arch) { default: