From b335cf016c7ed3f2857f537f2fe49aed6eabb7ab Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Thu, 27 Aug 2015 21:09:00 +0800 Subject: [PATCH] do not generate basic-block callback when translation is broken in the middle due to full cache (all the remaining archs) --- qemu/target-arm/translate-a64.c | 12 +++++++++++- qemu/target-arm/translate.c | 12 +++++++++++- qemu/target-m68k/translate.c | 11 ++++++++++- qemu/target-mips/translate.c | 14 ++++++++++++-- qemu/target-sparc/translate.c | 11 ++++++++++- 5 files changed, 54 insertions(+), 6 deletions(-) diff --git a/qemu/target-arm/translate-a64.c b/qemu/target-arm/translate-a64.c index 2e159f21..73e0c0ae 100644 --- a/qemu/target-arm/translate-a64.c +++ b/qemu/target-arm/translate-a64.c @@ -11044,6 +11044,7 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu, int num_insns; int max_insns; TCGContext *tcg_ctx = env->uc->tcg_ctx; + bool block_full = false; pc_start = tb->pc; @@ -11105,7 +11106,9 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu, tcg_clear_temp_count(); // 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) { // save block address to see if we need to patch block size later @@ -11186,6 +11189,11 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu, dc->pc < next_page_start && num_insns < max_insns); + /* if too long translation, save this info */ + if (tcg_ctx->gen_opc_ptr >= gen_opc_end || num_insns >= max_insns) { + block_full = true; + } + //if (tb->cflags & CF_LAST_IO) { // gen_io_end(); //} @@ -11251,4 +11259,6 @@ done_generating: tb->size = dc->pc - pc_start; tb->icount = num_insns; } + + env->uc->block_full = block_full; } diff --git a/qemu/target-arm/translate.c b/qemu/target-arm/translate.c index 9a1b7914..68b3b5ea 100644 --- a/qemu/target-arm/translate.c +++ b/qemu/target-arm/translate.c @@ -11149,6 +11149,7 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, int num_insns; int max_insns; TCGContext *tcg_ctx = env->uc->tcg_ctx; + bool block_full = false; /* generate intermediate code */ @@ -11228,7 +11229,9 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, tcg_clear_temp_count(); // 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) { // save block address to see if we need to patch block size later @@ -11398,6 +11401,11 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, //gen_io_end(); } + /* if too long translation, save this info */ + if (tcg_ctx->gen_opc_ptr >= gen_opc_end || num_insns >= max_insns) { + block_full = true; + } + /* At this stage dc->condjmp will only be set when the skipped instruction was a conditional branch or trap, and the PC has already been written. */ @@ -11502,6 +11510,8 @@ done_generating: tb->size = dc->pc - pc_start; //tb->icount = num_insns; } + + env->uc->block_full = block_full; } void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) diff --git a/qemu/target-m68k/translate.c b/qemu/target-m68k/translate.c index ce630d7d..6565056c 100644 --- a/qemu/target-m68k/translate.c +++ b/qemu/target-m68k/translate.c @@ -3076,6 +3076,7 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb, int num_insns; int max_insns; TCGContext *tcg_ctx = env->uc->tcg_ctx; + bool block_full = false; /* generate intermediate code */ pc_start = tb->pc; @@ -3101,7 +3102,9 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb, 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) { // save block address to see if we need to patch block size later @@ -3145,6 +3148,10 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb, (pc_offset) < (TARGET_PAGE_SIZE - 32) && num_insns < max_insns); + /* if too long translation, save this info */ + if (tcg_ctx->gen_opc_ptr >= gen_opc_end || num_insns >= max_insns) + block_full = true; + //if (tb->cflags & CF_LAST_IO) // gen_io_end(); if (unlikely(cs->singlestep_enabled)) { @@ -3187,6 +3194,8 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb, //optimize_flags(); //expand_target_qops(); + + env->uc->block_full = block_full; } void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb) diff --git a/qemu/target-mips/translate.c b/qemu/target-mips/translate.c index 4dbad582..97e28225 100644 --- a/qemu/target-mips/translate.c +++ b/qemu/target-mips/translate.c @@ -19172,6 +19172,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, int is_slot = 0; TCGContext *tcg_ctx = env->uc->tcg_ctx; TCGArg *save_opparam_ptr = NULL; + bool block_full = false; if (search_pc) qemu_log("search pc %d\n", search_pc); @@ -19207,7 +19208,9 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags); // 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) { // save block address to see if we need to patch block size later @@ -19251,7 +19254,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, // Unicorn: end address tells us to stop emulation if (ctx.pc == ctx.uc->addr_end) { generate_exception(&ctx, EXCP_SYSCALL); - insn_bytes = 0; + break; } else { // Unicorn: save param buffer if (env->uc->hook_insn) @@ -19315,6 +19318,11 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, //if (singlestep) // break; } + + if (tcg_ctx->gen_opc_ptr >= gen_opc_end || num_insns >= max_insns) { + block_full = true; + } + //if (tb->cflags & CF_LAST_IO) { // gen_io_end(); //} @@ -19350,6 +19358,8 @@ done_generating: tb->size = ctx.pc - pc_start; tb->icount = num_insns; } + + env->uc->block_full = block_full; } void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb) diff --git a/qemu/target-sparc/translate.c b/qemu/target-sparc/translate.c index 60c7ba20..d36d1a7f 100644 --- a/qemu/target-sparc/translate.c +++ b/qemu/target-sparc/translate.c @@ -5383,6 +5383,7 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu, int max_insns; unsigned int insn; TCGContext *tcg_ctx = env->uc->tcg_ctx; + bool block_full = false; memset(dc, 0, sizeof(DisasContext)); dc->uc = env->uc; @@ -5405,7 +5406,9 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu, 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) { // save block address to see if we need to patch block size later @@ -5473,6 +5476,10 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu, (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32) && num_insns < max_insns); + /* if too long translation, save this info */ + if (tcg_ctx->gen_opc_ptr >= gen_opc_end || num_insns >= max_insns) + block_full = true; + exit_gen_loop: //if (tb->cflags & CF_LAST_IO) { // gen_io_end(); @@ -5506,6 +5513,8 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu, tb->size = last_pc + 4 - pc_start; tb->icount = num_insns; } + + env->uc->block_full = block_full; } void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)