From 2ac1281f82314d4f49b213583c37213ff710a737 Mon Sep 17 00:00:00 2001 From: Ryan Hileman Date: Fri, 22 Jan 2016 18:28:17 -0800 Subject: [PATCH] rework code/block tracing --- list.c | 2 ++ qemu/target-arm/helper.h | 2 +- qemu/target-arm/translate-a64.c | 20 ++++++------------- qemu/target-arm/translate.c | 29 +++++++++------------------- qemu/target-i386/helper.h | 2 +- qemu/target-i386/translate.c | 25 +++++++----------------- qemu/target-m68k/helper.h | 2 +- qemu/target-m68k/translate.c | 20 ++++++------------- qemu/target-mips/helper.h | 2 +- qemu/target-mips/translate.c | 34 ++++++++++----------------------- qemu/target-sparc/helper.h | 2 +- qemu/target-sparc/translate.c | 26 ++++++++----------------- qemu/tcg/tcg-op.h | 7 +++---- qemu/translate-all.c | 2 +- uc.c | 12 +++++++++--- 15 files changed, 66 insertions(+), 121 deletions(-) diff --git a/list.c b/list.c index 695f5a24..6dbe4782 100644 --- a/list.c +++ b/list.c @@ -18,6 +18,8 @@ void list_clear(struct list *list) free(cur); cur = next; } + list->head = NULL; + list->tail = NULL; } // returns generated linked list node, or NULL on failure diff --git a/qemu/target-arm/helper.h b/qemu/target-arm/helper.h index d2de58d6..6427c18c 100644 --- a/qemu/target-arm/helper.h +++ b/qemu/target-arm/helper.h @@ -1,4 +1,4 @@ -DEF_HELPER_5(uc_tracecode, void, i32, ptr, ptr, i64, ptr) +DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64) DEF_HELPER_FLAGS_1(clz_arm, TCG_CALL_NO_RWG_SE, i32, i32) diff --git a/qemu/target-arm/translate-a64.c b/qemu/target-arm/translate-a64.c index 28d57681..06378453 100644 --- a/qemu/target-arm/translate-a64.c +++ b/qemu/target-arm/translate-a64.c @@ -10970,7 +10970,6 @@ static void disas_data_proc_simd_fp(DisasContext *s, uint32_t insn) static void disas_a64_insn(CPUARMState *env, DisasContext *s) { uint32_t insn; - struct hook *hook; TCGContext *tcg_ctx = env->uc->tcg_ctx; // Unicorn: end address tells us to stop emulation @@ -10985,10 +10984,8 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s) s->pc += 4; // Unicorn: trace this instruction on request - HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) { - if (! HOOK_BOUND_CHECK(hook, s->pc - 4)) - continue; - gen_uc_tracecode(tcg_ctx, 4, hook->callback, env->uc, s->pc - 4, hook->user_data); + if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, s->pc - 4)) { + gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, env->uc, s->pc - 4); // the callback might want to stop emulation immediately check_exit_request(tcg_ctx); } @@ -11044,7 +11041,6 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu, int max_insns; TCGContext *tcg_ctx = env->uc->tcg_ctx; bool block_full = false; - struct hook *hook; pc_start = tb->pc; @@ -11116,14 +11112,10 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu, // Unicorn: trace this block on request // Only hook this block if it is not broken from previous translation due to // full translation cache - if (! env->uc->block_full) { - HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) { - if (! HOOK_BOUND_CHECK(hook, pc_start)) - continue; - // save block address to see if we need to patch block size later - env->uc->block_addr = pc_start; - gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, pc_start, hook->user_data); - } + if (! env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { + // save block address to see if we need to patch block size later + env->uc->block_addr = pc_start; + gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start); } gen_tb_start(tcg_ctx); diff --git a/qemu/target-arm/translate.c b/qemu/target-arm/translate.c index bf190452..d097c236 100644 --- a/qemu/target-arm/translate.c +++ b/qemu/target-arm/translate.c @@ -7680,7 +7680,6 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq TCGv_i32 tmp3; TCGv_i32 addr; TCGv_i64 tmp64; - struct hook *hook; /* M variants do not implement ARM mode. */ if (arm_dc_feature(s, ARM_FEATURE_M)) { @@ -7688,10 +7687,8 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) // qq } // Unicorn: trace this instruction on request - HOOK_FOREACH(s->uc, hook, UC_HOOK_CODE) { - if (! HOOK_BOUND_CHECK(hook, s->pc - 4)) - continue; - gen_uc_tracecode(tcg_ctx, 4, hook->callback, s->uc, s->pc - 4, hook->user_data); + if (HOOK_EXISTS_BOUNDED(s->uc, UC_HOOK_CODE, s->pc - 4)) { + gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, s->uc, s->pc - 4); // the callback might want to stop emulation immediately check_exit_request(tcg_ctx); } @@ -10391,7 +10388,6 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq TCGv_i32 tmp; TCGv_i32 tmp2; TCGv_i32 addr; - struct hook *hook; // Unicorn: end address tells us to stop emulation if (s->pc == s->uc->addr_end) { @@ -10410,11 +10406,9 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s) // qq } // Unicorn: trace this instruction on request - HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) { - if (! HOOK_BOUND_CHECK(hook, s->pc)) - continue; - gen_uc_tracecode(tcg_ctx, 2, hook->callback, env->uc, s->pc, hook->user_data); - // check to see if we need to exit immediately + if (HOOK_EXISTS_BOUNDED(s->uc, UC_HOOK_CODE, s->pc)) { + gen_uc_tracecode(tcg_ctx, 2, UC_HOOK_CODE_IDX, s->uc, s->pc); + // the callback might want to stop emulation immediately check_exit_request(tcg_ctx); } @@ -11147,7 +11141,6 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, int max_insns; TCGContext *tcg_ctx = env->uc->tcg_ctx; bool block_full = false; - struct hook *hook; /* generate intermediate code */ @@ -11237,14 +11230,10 @@ static inline void gen_intermediate_code_internal(ARMCPU *cpu, // Unicorn: trace this block on request // Only hook this block if it is not broken from previous translation due to // full translation cache - if (!env->uc->block_full) { - HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) { - if (! HOOK_BOUND_CHECK(hook, pc_start)) - continue; - // save block address to see if we need to patch block size later - env->uc->block_addr = pc_start; - gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, pc_start, hook->user_data); - } + if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { + // save block address to see if we need to patch block size later + env->uc->block_addr = pc_start; + gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start); } gen_tb_start(tcg_ctx); diff --git a/qemu/target-i386/helper.h b/qemu/target-i386/helper.h index 8ab196ac..d3b52d1f 100644 --- a/qemu/target-i386/helper.h +++ b/qemu/target-i386/helper.h @@ -1,4 +1,4 @@ -DEF_HELPER_5(uc_tracecode, void, i32, ptr, ptr, i64, ptr) +DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64) DEF_HELPER_FLAGS_4(cc_compute_all, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, int) DEF_HELPER_FLAGS_4(cc_compute_c, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, int) diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c index 0d83f4bd..d68cb516 100644 --- a/qemu/target-i386/translate.c +++ b/qemu/target-i386/translate.c @@ -4745,7 +4745,6 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, TCGv cpu_tmp4 = *(TCGv *)tcg_ctx->cpu_tmp4; TCGv **cpu_T = (TCGv **)tcg_ctx->cpu_T; TCGv **cpu_regs = (TCGv **)tcg_ctx->cpu_regs; - struct hook *hook = NULL; TCGArg *save_opparam_ptr = tcg_ctx->gen_opparam_ptr; bool cc_op_dirty = s->cc_op_dirty; bool changed_cc_op = false; @@ -4773,14 +4772,9 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, s->last_cc_op = s->cc_op; changed_cc_op = true; } - HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) { - if (! HOOK_BOUND_CHECK(hook, pc_start)) - continue; - // generate code to call callback - gen_uc_tracecode(tcg_ctx, 0xf1f1f1f1, hook->callback, env->uc, pc_start, hook->user_data); - // the callback might want to stop emulation immediately - check_exit_request(tcg_ctx); - } + gen_uc_tracecode(tcg_ctx, 0xf1f1f1f1, UC_HOOK_CODE_IDX, env->uc, pc_start); + // the callback might want to stop emulation immediately + check_exit_request(tcg_ctx); } prefixes = 0; @@ -8173,7 +8167,7 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_helper_unlock(tcg_ctx, cpu_env); // Unicorn: patch the callback for the instruction size - if (hook) { + if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, pc_start)) { // int i; // for(i = 0; i < 20; i++) // printf("=== [%u] = %x\n", i, *(save_opparam_ptr + i)); @@ -8282,7 +8276,6 @@ static inline void gen_intermediate_code_internal(uint8_t *gen_opc_cc_op, int num_insns = 0; int max_insns; bool block_full = false; - struct hook *hook; /* generate intermediate code */ pc_start = tb->pc; @@ -8388,13 +8381,9 @@ static inline void gen_intermediate_code_internal(uint8_t *gen_opc_cc_op, // Unicorn: trace this block on request // Only hook this block if it is not broken from previous translation due to // full translation cache - if (!env->uc->block_full) { - HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) { - if (! HOOK_BOUND_CHECK(hook, pc_start)) - continue; - env->uc->block_addr = pc_start; - gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, pc_start, hook->user_data); - } + if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { + env->uc->block_addr = pc_start; + gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start); } gen_tb_start(tcg_ctx); diff --git a/qemu/target-m68k/helper.h b/qemu/target-m68k/helper.h index 865cf95d..caaadb3a 100644 --- a/qemu/target-m68k/helper.h +++ b/qemu/target-m68k/helper.h @@ -1,4 +1,4 @@ -DEF_HELPER_5(uc_tracecode, void, i32, ptr, ptr, i64, ptr) +DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64) DEF_HELPER_1(bitrev, i32, i32) DEF_HELPER_1(ff1, i32, i32) diff --git a/qemu/target-m68k/translate.c b/qemu/target-m68k/translate.c index 0f685d8e..bf45a66a 100644 --- a/qemu/target-m68k/translate.c +++ b/qemu/target-m68k/translate.c @@ -3031,7 +3031,6 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s) { TCGContext *tcg_ctx = s->uc->tcg_ctx; uint16_t insn; - struct hook *hook; if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) { tcg_gen_debug_insn_start(tcg_ctx, s->pc); @@ -3044,10 +3043,8 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s) } // Unicorn: trace this instruction on request - HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) { - if (! HOOK_BOUND_CHECK(hook, s->pc)) - continue; - gen_uc_tracecode(tcg_ctx, 2, hook->callback, env->uc, s->pc, hook->user_data); + if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, s->pc)) { + gen_uc_tracecode(tcg_ctx, 2, UC_HOOK_CODE_IDX, env->uc, s->pc); // the callback might want to stop emulation immediately check_exit_request(tcg_ctx); } @@ -3075,7 +3072,6 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb, int max_insns; TCGContext *tcg_ctx = env->uc->tcg_ctx; bool block_full = false; - struct hook *hook; /* generate intermediate code */ pc_start = tb->pc; @@ -3110,14 +3106,10 @@ gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb, // Unicorn: trace this block on request // Only hook this block if it is not broken from previous translation due to // full translation cache - if (!env->uc->block_full) { - HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) { - if (! HOOK_BOUND_CHECK(hook, pc_start)) - continue; - // save block address to see if we need to patch block size later - env->uc->block_addr = pc_start; - gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, pc_start, hook->user_data); - } + if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { + // save block address to see if we need to patch block size later + env->uc->block_addr = pc_start; + gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start); } gen_tb_start(tcg_ctx); diff --git a/qemu/target-mips/helper.h b/qemu/target-mips/helper.h index 81f733c2..1924bf6f 100644 --- a/qemu/target-mips/helper.h +++ b/qemu/target-mips/helper.h @@ -1,4 +1,4 @@ -DEF_HELPER_5(uc_tracecode, void, i32, ptr, ptr, i64, ptr) +DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64) DEF_HELPER_3(raise_exception_err, noreturn, env, i32, int) DEF_HELPER_2(raise_exception, noreturn, env, i32) diff --git a/qemu/target-mips/translate.c b/qemu/target-mips/translate.c index fadbaeb0..8802c221 100644 --- a/qemu/target-mips/translate.c +++ b/qemu/target-mips/translate.c @@ -11331,7 +11331,6 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, bool *insn_n int op, cnvt_op, op1, offset; int funct; int n_bytes; - struct hook *hook; op = (ctx->opcode >> 11) & 0x1f; sa = (ctx->opcode >> 2) & 0x7; @@ -11344,10 +11343,8 @@ static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx, bool *insn_n n_bytes = 2; // Unicorn: trace this instruction on request - HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) { - if (! HOOK_BOUND_CHECK(hook, ctx->pc)) - continue; - gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, ctx->pc, hook->user_data); + if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, ctx->pc)) { + gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_CODE_IDX, env->uc, ctx->pc); *insn_need_patch = true; // the callback might want to stop emulation immediately check_exit_request(tcg_ctx); @@ -13932,7 +13929,6 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, bool *ins TCGContext *tcg_ctx = env->uc->tcg_ctx; TCGv **cpu_gpr = (TCGv **)tcg_ctx->cpu_gpr; uint32_t op; - struct hook *hook; /* make sure instructions are on a halfword boundary */ if (ctx->pc & 0x1) { @@ -13943,10 +13939,8 @@ static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, bool *ins } // Unicorn: trace this instruction on request - HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) { - if (! HOOK_BOUND_CHECK(hook, ctx->pc)) - continue; - gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, ctx->pc, hook->user_data); + if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, ctx->pc)) { + gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_CODE_IDX, env->uc, ctx->pc); *insn_need_patch = true; // the callback might want to stop emulation immediately check_exit_request(tcg_ctx); @@ -18505,11 +18499,8 @@ static void gen_msa(CPUMIPSState *env, DisasContext *ctx) static void hook_insn(CPUMIPSState *env, DisasContext *ctx, bool *insn_need_patch, int *insn_patch_offset, int offset_value) { TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - struct hook *hook; - HOOK_FOREACH(env->uc, hook, UC_HOOK_CODE) { - if (! HOOK_BOUND_CHECK(hook, ctx->pc)) - continue; - gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, ctx->pc, hook->user_data); + if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, ctx->pc)) { + gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_CODE_IDX, env->uc, ctx->pc); *insn_need_patch = true; // the callback might want to stop emulation immediately check_exit_request(tcg_ctx); @@ -19178,7 +19169,6 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, TCGContext *tcg_ctx = env->uc->tcg_ctx; TCGArg *save_opparam_ptr = NULL; bool block_full = false; - struct hook *hook; if (search_pc) qemu_log("search pc %d\n", search_pc); @@ -19224,14 +19214,10 @@ gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb, // Unicorn: trace this block on request // Only hook this block if it is not broken from previous translation due to // full translation cache - if (! env->uc->block_full) { - HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) { - if (! HOOK_BOUND_CHECK(hook, pc_start)) - continue; - // save block address to see if we need to patch block size later - env->uc->block_addr = pc_start; - gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, pc_start, hook->user_data); - } + if (! env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { + // save block address to see if we need to patch block size later + env->uc->block_addr = pc_start; + gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start); } gen_tb_start(tcg_ctx); diff --git a/qemu/target-sparc/helper.h b/qemu/target-sparc/helper.h index 2557dd08..503e1e5c 100644 --- a/qemu/target-sparc/helper.h +++ b/qemu/target-sparc/helper.h @@ -1,4 +1,4 @@ -DEF_HELPER_5(uc_tracecode, void, i32, ptr, ptr, i64, ptr) +DEF_HELPER_4(uc_tracecode, void, i32, i32, ptr, i64) DEF_HELPER_1(power_down, void, env) #ifndef TARGET_SPARC64 diff --git a/qemu/target-sparc/translate.c b/qemu/target-sparc/translate.c index 8caba2b7..a7f067cf 100644 --- a/qemu/target-sparc/translate.c +++ b/qemu/target-sparc/translate.c @@ -2625,7 +2625,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn, bool hook_ins TCGv_i32 cpu_src1_32, cpu_src2_32, cpu_dst_32; TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64; target_long simm; - struct hook *hook; if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) { tcg_gen_debug_insn_start(tcg_ctx, dc->pc); @@ -2638,14 +2637,10 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn, bool hook_ins } // Unicorn: trace this instruction on request - if (hook_insn) { - HOOK_FOREACH(dc->uc, hook, UC_HOOK_CODE) { - if (! HOOK_BOUND_CHECK(hook, dc->pc)) - continue; - gen_uc_tracecode(tcg_ctx, 4, hook->callback, dc->uc, dc->pc, hook->user_data); - // the callback might want to stop emulation immediately - check_exit_request(tcg_ctx); - } + if (hook_insn && HOOK_EXISTS_BOUNDED(dc->uc, UC_HOOK_CODE, dc->pc)) { + gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, dc->uc, dc->pc); + // the callback might want to stop emulation immediately + check_exit_request(tcg_ctx); } opc = GET_FIELD(insn, 0, 1); @@ -5390,7 +5385,6 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu, unsigned int insn; TCGContext *tcg_ctx = env->uc->tcg_ctx; bool block_full = false; - struct hook *hook; memset(dc, 0, sizeof(DisasContext)); dc->uc = env->uc; @@ -5431,14 +5425,10 @@ static inline void gen_intermediate_code_internal(SPARCCPU *cpu, // Unicorn: trace this block on request // Only hook this block if it is not broken from previous translation due to // full translation cache - if (!env->uc->block_full) { - HOOK_FOREACH(env->uc, hook, UC_HOOK_BLOCK) { - if (! HOOK_BOUND_CHECK(hook, pc_start)) - continue; - // save block address to see if we need to patch block size later - env->uc->block_addr = pc_start; - gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, hook->callback, env->uc, pc_start, hook->user_data); - } + if (!env->uc->block_full && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, pc_start)) { + // save block address to see if we need to patch block size later + env->uc->block_addr = pc_start; + gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, env->uc, pc_start); } gen_tb_start(tcg_ctx); diff --git a/qemu/tcg/tcg-op.h b/qemu/tcg/tcg-op.h index 9f096a3d..87358240 100644 --- a/qemu/tcg/tcg-op.h +++ b/qemu/tcg/tcg-op.h @@ -27,14 +27,13 @@ int gen_new_label(TCGContext *); -static inline void gen_uc_tracecode(TCGContext *tcg_ctx, int32_t size, void *callback, void *uc, uint64_t pc, void *data) +static inline void gen_uc_tracecode(TCGContext *tcg_ctx, int32_t size, int32_t type, void *uc, uint64_t pc) { TCGv_i32 tsize = tcg_const_i32(tcg_ctx, size); - TCGv_ptr tcallback = tcg_const_ptr(tcg_ctx, callback); + TCGv_i32 ttype = tcg_const_i32(tcg_ctx, type); TCGv_ptr tuc = tcg_const_ptr(tcg_ctx, uc); TCGv_i64 tpc = tcg_const_i64(tcg_ctx, pc); - TCGv_ptr tdata = tcg_const_ptr(tcg_ctx, data); - gen_helper_uc_tracecode(tcg_ctx, tsize, tcallback, tuc, tpc, tdata); + gen_helper_uc_tracecode(tcg_ctx, tsize, ttype, tuc, tpc); } static inline void tcg_gen_op0(TCGContext *s, TCGOpcode opc) diff --git a/qemu/translate-all.c b/qemu/translate-all.c index 72e1b60f..aec38c7c 100644 --- a/qemu/translate-all.c +++ b/qemu/translate-all.c @@ -179,7 +179,7 @@ static int cpu_gen_code(CPUArchState *env, TranslationBlock *tb, int *gen_code_s gen_intermediate_code(env, tb); // Unicorn: when tracing block, patch 1st operand for block size - if (HOOK_EXISTS(env->uc, UC_HOOK_BLOCK) && env->uc->block_addr == tb->pc) { + if (env->uc->block_addr == tb->pc && HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_BLOCK, tb->pc)) { if (env->uc->block_full) // block size is unknown *(s->gen_opparam_buf + 1) = 0; else diff --git a/uc.c b/uc.c index f7f40853..b0f8a976 100644 --- a/uc.c +++ b/uc.c @@ -1009,17 +1009,23 @@ uc_err uc_hook_del(uc_engine *uc, uc_hook hh) } // TCG helper -void helper_uc_tracecode(int32_t size, void *callback, void *handle, int64_t address, void *user_data); -void helper_uc_tracecode(int32_t size, void *callback, void *handle, int64_t address, void *user_data) +void helper_uc_tracecode(int32_t size, uc_hook_type type, void *handle, int64_t address); +void helper_uc_tracecode(int32_t size, uc_hook_type type, void *handle, int64_t address) { struct uc_struct *uc = handle; + struct list_item *cur = uc->hook[type].head; + struct hook *hook; // sync PC in CPUArchState with address if (uc->set_pc) { uc->set_pc(uc, address); } - ((uc_cb_hookcode_t)callback)(uc, address, size, user_data); + while (cur != NULL && !uc->stop_request) { + hook = (struct hook *)cur->data; + ((uc_cb_hookcode_t)hook->callback)(uc, address, size, hook->user_data); + cur = cur->next; + } } UNICORN_EXPORT