diff --git a/include/uc_priv.h b/include/uc_priv.h index c9a11172..4bd806cc 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -142,6 +142,13 @@ struct hook { void *user_data; }; +// Add an inline hook to helper_table +typedef void (*uc_add_inline_hook_t)(struct uc_struct *uc, struct hook *hk, + void **args, int args_len); + +// Delete a hook from helper_table +typedef void (*uc_del_inline_hook_t)(struct uc_struct *uc, struct hook *hk); + // hook list offsets // // The lowest 6 bits are used for hook type index while the others @@ -254,6 +261,8 @@ struct uc_struct { uc_tcg_flush_tlb tcg_flush_tlb; uc_invalidate_tb_t uc_invalidate_tb; uc_gen_tb_t uc_gen_tb; + uc_add_inline_hook_t add_inline_hook; + uc_del_inline_hook_t del_inline_hook; /* only 1 cpu in unicorn, do not need current_cpu to handle current running cpu. */ @@ -296,6 +305,7 @@ struct uc_struct { // linked lists containing hooks per type struct list hook[UC_HOOK_MAX]; struct list hooks_to_del; + int hooks_count[UC_HOOK_MAX]; // hook to count number of instructions for uc_emu_start() uc_hook count_hook; diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 1ef7fd53..12f6833c 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -4,6 +4,8 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _aarch64 #endif +#define uc_add_inline_hook uc_add_inline_hook_aarch64 +#define uc_del_inline_hook uc_del_inline_hook_aarch64 #define tb_invalidate_phys_range tb_invalidate_phys_range_aarch64 #define use_idiv_instructions use_idiv_instructions_aarch64 #define arm_arch arm_arch_aarch64 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index 25c3c8a2..068b2d02 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -4,6 +4,8 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _aarch64eb #endif +#define uc_add_inline_hook uc_add_inline_hook_aarch64eb +#define uc_del_inline_hook uc_del_inline_hook_aarch64eb #define tb_invalidate_phys_range tb_invalidate_phys_range_aarch64eb #define use_idiv_instructions use_idiv_instructions_aarch64eb #define arm_arch arm_arch_aarch64eb diff --git a/qemu/accel/tcg/translate-all.c b/qemu/accel/tcg/translate-all.c index 3e5f693d..ac14d902 100644 --- a/qemu/accel/tcg/translate-all.c +++ b/qemu/accel/tcg/translate-all.c @@ -1078,6 +1078,10 @@ void tcg_exec_init(struct uc_struct *uc, unsigned long tb_size) /* Invalidate / Cache TBs */ uc->uc_invalidate_tb = uc_invalidate_tb; uc->uc_gen_tb = uc_gen_tb; + + /* Inline hooks optimization */ + uc->add_inline_hook = uc_add_inline_hook; + uc->del_inline_hook = uc_del_inline_hook; } /* call with @p->lock held */ diff --git a/qemu/arm.h b/qemu/arm.h index 545a9ca6..871a604f 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -4,6 +4,8 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _arm #endif +#define uc_add_inline_hook uc_add_inline_hook_arm +#define uc_del_inline_hook uc_del_inline_hook_arm #define tb_invalidate_phys_range tb_invalidate_phys_range_arm #define use_idiv_instructions use_idiv_instructions_arm #define arm_arch arm_arch_arm diff --git a/qemu/armeb.h b/qemu/armeb.h index 988dab96..f4c26746 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -4,6 +4,8 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _armeb #endif +#define uc_add_inline_hook uc_add_inline_hook_armeb +#define uc_del_inline_hook uc_del_inline_hook_armeb #define tb_invalidate_phys_range tb_invalidate_phys_range_armeb #define use_idiv_instructions use_idiv_instructions_armeb #define arm_arch arm_arch_armeb diff --git a/qemu/include/tcg/tcg-op.h b/qemu/include/tcg/tcg-op.h index 0333daf1..13ec344a 100644 --- a/qemu/include/tcg/tcg-op.h +++ b/qemu/include/tcg/tcg-op.h @@ -32,13 +32,41 @@ 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_i32 ttype = tcg_const_i32(tcg_ctx, type); + TCGv_i32 ttype; TCGv_ptr tuc = tcg_const_ptr(tcg_ctx, uc); TCGv_i64 tpc = tcg_const_i64(tcg_ctx, pc); - gen_helper_uc_tracecode(tcg_ctx, tsize, ttype, tuc, tpc); + TCGv_ptr tdata; + uc_engine* puc = uc; + struct list_item *cur; + struct hook* hk; + TCGTemp* args[] = { + tcgv_ptr_temp(tcg_ctx, tuc), + tcgv_i64_temp(tcg_ctx, tpc), + tcgv_i32_temp(tcg_ctx, tsize), + 0 + }; + + if (puc->hooks_count[type] == 1) { + cur = puc->hook[type].head; + + while (cur) { + hk = cur->data; + if (!hk->to_delete) { + tdata = tcg_const_ptr(tcg_ctx, hk->user_data); + args[3] = tcgv_ptr_temp(tcg_ctx, tdata); + puc->add_inline_hook(uc, hk, (void**)args, 4); + tcg_temp_free_ptr(tcg_ctx, tdata); + } + cur = cur->next; + } + + } else { + ttype = tcg_const_i32(tcg_ctx, type); + gen_helper_uc_tracecode(tcg_ctx, tsize, ttype, tuc, tpc); + tcg_temp_free_i32(tcg_ctx, ttype); + } tcg_temp_free_i64(tcg_ctx, tpc); tcg_temp_free_ptr(tcg_ctx, tuc); - tcg_temp_free_i32(tcg_ctx, ttype); tcg_temp_free_i32(tcg_ctx, tsize); } diff --git a/qemu/include/tcg/tcg.h b/qemu/include/tcg/tcg.h index a1566e4f..c1c6d7b6 100644 --- a/qemu/include/tcg/tcg.h +++ b/qemu/include/tcg/tcg.h @@ -1561,4 +1561,7 @@ struct jit_code_entry { uint64_t symfile_size; }; +void uc_del_inline_hook(uc_engine *uc, struct hook *hk); +void uc_add_inline_hook(uc_engine *uc, struct hook *hk, void** args, int args_len); + #endif /* TCG_H */ diff --git a/qemu/m68k.h b/qemu/m68k.h index 81472490..1d0352c1 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -4,6 +4,8 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _m68k #endif +#define uc_add_inline_hook uc_add_inline_hook_m68k +#define uc_del_inline_hook uc_del_inline_hook_m68k #define tb_invalidate_phys_range tb_invalidate_phys_range_m68k #define use_idiv_instructions use_idiv_instructions_m68k #define arm_arch arm_arch_m68k diff --git a/qemu/mips.h b/qemu/mips.h index cd1cccb4..f1666d06 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -4,6 +4,8 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _mips #endif +#define uc_add_inline_hook uc_add_inline_hook_mips +#define uc_del_inline_hook uc_del_inline_hook_mips #define tb_invalidate_phys_range tb_invalidate_phys_range_mips #define use_idiv_instructions use_idiv_instructions_mips #define arm_arch arm_arch_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index e56c5f1f..bdcb4dae 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -4,6 +4,8 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _mips64 #endif +#define uc_add_inline_hook uc_add_inline_hook_mips64 +#define uc_del_inline_hook uc_del_inline_hook_mips64 #define tb_invalidate_phys_range tb_invalidate_phys_range_mips64 #define use_idiv_instructions use_idiv_instructions_mips64 #define arm_arch arm_arch_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 8e3bdbfe..ea1c1874 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -4,6 +4,8 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _mips64el #endif +#define uc_add_inline_hook uc_add_inline_hook_mips64el +#define uc_del_inline_hook uc_del_inline_hook_mips64el #define tb_invalidate_phys_range tb_invalidate_phys_range_mips64el #define use_idiv_instructions use_idiv_instructions_mips64el #define arm_arch arm_arch_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 1c1660f3..67b11060 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -4,6 +4,8 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _mipsel #endif +#define uc_add_inline_hook uc_add_inline_hook_mipsel +#define uc_del_inline_hook uc_del_inline_hook_mipsel #define tb_invalidate_phys_range tb_invalidate_phys_range_mipsel #define use_idiv_instructions use_idiv_instructions_mipsel #define arm_arch arm_arch_mipsel diff --git a/qemu/ppc.h b/qemu/ppc.h index 87a216a3..7022629e 100644 --- a/qemu/ppc.h +++ b/qemu/ppc.h @@ -4,6 +4,8 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _ppc #endif +#define uc_add_inline_hook uc_add_inline_hook_ppc +#define uc_del_inline_hook uc_del_inline_hook_ppc #define tb_invalidate_phys_range tb_invalidate_phys_range_ppc #define use_idiv_instructions use_idiv_instructions_ppc #define arm_arch arm_arch_ppc diff --git a/qemu/ppc64.h b/qemu/ppc64.h index d4f27146..992caf87 100644 --- a/qemu/ppc64.h +++ b/qemu/ppc64.h @@ -4,6 +4,8 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _ppc64 #endif +#define uc_add_inline_hook uc_add_inline_hook_ppc64 +#define uc_del_inline_hook uc_del_inline_hook_ppc64 #define tb_invalidate_phys_range tb_invalidate_phys_range_ppc64 #define use_idiv_instructions use_idiv_instructions_ppc64 #define arm_arch arm_arch_ppc64 diff --git a/qemu/riscv32.h b/qemu/riscv32.h index 57795e38..432b9bb3 100644 --- a/qemu/riscv32.h +++ b/qemu/riscv32.h @@ -4,6 +4,8 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _riscv32 #endif +#define uc_add_inline_hook uc_add_inline_hook_riscv32 +#define uc_del_inline_hook uc_del_inline_hook_riscv32 #define tb_invalidate_phys_range tb_invalidate_phys_range_riscv32 #define use_idiv_instructions use_idiv_instructions_riscv32 #define arm_arch arm_arch_riscv32 diff --git a/qemu/riscv64.h b/qemu/riscv64.h index 4b19f2c9..f0aa87d1 100644 --- a/qemu/riscv64.h +++ b/qemu/riscv64.h @@ -4,6 +4,8 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _riscv64 #endif +#define uc_add_inline_hook uc_add_inline_hook_riscv64 +#define uc_del_inline_hook uc_del_inline_hook_riscv64 #define tb_invalidate_phys_range tb_invalidate_phys_range_riscv64 #define use_idiv_instructions use_idiv_instructions_riscv64 #define arm_arch arm_arch_riscv64 diff --git a/qemu/sparc.h b/qemu/sparc.h index ecb8c6c2..5b57febc 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -4,6 +4,8 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _sparc #endif +#define uc_add_inline_hook uc_add_inline_hook_sparc +#define uc_del_inline_hook uc_del_inline_hook_sparc #define tb_invalidate_phys_range tb_invalidate_phys_range_sparc #define use_idiv_instructions use_idiv_instructions_sparc #define arm_arch arm_arch_sparc diff --git a/qemu/sparc64.h b/qemu/sparc64.h index 22d1ea35..5a792deb 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -4,6 +4,8 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _sparc64 #endif +#define uc_add_inline_hook uc_add_inline_hook_sparc64 +#define uc_del_inline_hook uc_del_inline_hook_sparc64 #define tb_invalidate_phys_range tb_invalidate_phys_range_sparc64 #define use_idiv_instructions use_idiv_instructions_sparc64 #define arm_arch arm_arch_sparc64 diff --git a/qemu/target/arm/translate-a64.c b/qemu/target/arm/translate-a64.c index 914b382b..78b42c9f 100644 --- a/qemu/target/arm/translate-a64.c +++ b/qemu/target/arm/translate-a64.c @@ -14420,7 +14420,10 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s) // Unicorn: trace this instruction on request if (HOOK_EXISTS_BOUNDED(env->uc, UC_HOOK_CODE, s->pc_curr)) { + + // Sync PC in advance TCGContext *tcg_ctx = env->uc->tcg_ctx; + gen_a64_set_pc_im(tcg_ctx, s->pc_curr); gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, env->uc, s->pc_curr); // the callback might want to stop emulation immediately diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index efdfc4b4..9de036cd 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -10910,6 +10910,10 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn) // Unicorn: trace this instruction on request if (HOOK_EXISTS_BOUNDED(s->uc, UC_HOOK_CODE, s->pc_curr)) { + + // Sync PC in advance + gen_set_pc_im(s, s->pc_curr); + gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, s->uc, s->pc_curr); // the callback might want to stop emulation immediately check_exit_request(tcg_ctx); @@ -11538,6 +11542,10 @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) // Unicorn: trace this instruction on request insn_size = is_16bit ? 2 : 4; if (HOOK_EXISTS_BOUNDED(uc, UC_HOOK_CODE, dc->base.pc_next - insn_size)) { + + // Sync PC in advance + gen_set_pc_im(dc, dc->base.pc_next - insn_size); + if (uc->no_exit_request) { gen_uc_tracecode(tcg_ctx, insn_size, UC_HOOK_CODE_IDX | UC_HOOK_FLAG_NO_STOP, uc, dc->base.pc_next - insn_size); } else { diff --git a/qemu/target/i386/translate.c b/qemu/target/i386/translate.c index 97c33ecd..eef26242 100644 --- a/qemu/target/i386/translate.c +++ b/qemu/target/i386/translate.c @@ -4811,6 +4811,9 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) s->last_cc_op = s->cc_op; } + // Sync PC in advance + gen_jmp_im(s, pc_start); + // save the last operand prev_op = tcg_last_op(tcg_ctx); insn_hook = true; diff --git a/qemu/target/m68k/translate.c b/qemu/target/m68k/translate.c index c447a905..91dc6aad 100644 --- a/qemu/target/m68k/translate.c +++ b/qemu/target/m68k/translate.c @@ -6333,6 +6333,10 @@ static void m68k_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) // Unicorn: trace this instruction on request if (HOOK_EXISTS_BOUNDED(uc, UC_HOOK_CODE, dc->pc)) { + + // Sync PC in advance + tcg_gen_movi_i32(tcg_ctx, QREG_PC, dc->pc); + gen_uc_tracecode(tcg_ctx, 2, UC_HOOK_CODE_IDX, uc, dc->pc); // the callback might want to stop emulation immediately check_exit_request(tcg_ctx); diff --git a/qemu/target/mips/translate.c b/qemu/target/mips/translate.c index e9fceaf9..11617489 100644 --- a/qemu/target/mips/translate.c +++ b/qemu/target/mips/translate.c @@ -30941,6 +30941,10 @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) // Unicorn: trace this instruction on request if (HOOK_EXISTS_BOUNDED(uc, UC_HOOK_CODE, ctx->base.pc_next)) { + + // Sync PC in advance + gen_save_pc(tcg_ctx, ctx->base.pc_next); + // save the last operand prev_op = tcg_last_op(tcg_ctx); hook_insn = true; diff --git a/qemu/target/ppc/translate.c b/qemu/target/ppc/translate.c index fec05d19..1a236913 100644 --- a/qemu/target/ppc/translate.c +++ b/qemu/target/ppc/translate.c @@ -7633,6 +7633,10 @@ static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) // Unicorn: trace this instruction on request if (HOOK_EXISTS_BOUNDED(uc, UC_HOOK_CODE, ctx->base.pc_next)) { + + // Sypc PC in advance + gen_update_nip(ctx, ctx->base.pc_next); + gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, uc, ctx->base.pc_next); // the callback might want to stop emulation immediately check_exit_request(tcg_ctx); diff --git a/qemu/target/riscv/translate.c b/qemu/target/riscv/translate.c index e256958f..3b6b3544 100644 --- a/qemu/target/riscv/translate.c +++ b/qemu/target/riscv/translate.c @@ -856,6 +856,10 @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu) } else { // Unicorn: trace this instruction on request if (HOOK_EXISTS_BOUNDED(uc, UC_HOOK_CODE, ctx->base.pc_next)) { + + // Sync PC in advance + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc, ctx->base.pc_next); + // save the last operand prev_op = tcg_last_op(tcg_ctx); insn_hook = true; diff --git a/qemu/target/sparc/translate.c b/qemu/target/sparc/translate.c index 8c2a8b40..63182abb 100644 --- a/qemu/target/sparc/translate.c +++ b/qemu/target/sparc/translate.c @@ -5961,6 +5961,10 @@ static void sparc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) // Unicorn: trace this instruction on request if (HOOK_EXISTS_BOUNDED(uc, UC_HOOK_CODE, dc->pc)) { + + // Sync PC in advance + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc, dc->pc); + gen_uc_tracecode(tcg_ctx, 4, UC_HOOK_CODE_IDX, uc, dc->pc); // the callback might want to stop emulation immediately check_exit_request(tcg_ctx); diff --git a/qemu/tcg/tcg.c b/qemu/tcg/tcg.c index 5fd5ff0f..7da79cd8 100644 --- a/qemu/tcg/tcg.c +++ b/qemu/tcg/tcg.c @@ -662,6 +662,54 @@ static void process_op_defs(TCGContext *s); static TCGTemp *tcg_global_reg_new_internal(TCGContext *s, TCGType type, TCGReg reg, const char *name); +void uc_add_inline_hook(uc_engine *uc, struct hook *hk, void** args, int args_len) +{ + TCGHelperInfo* info = g_malloc(sizeof(TCGHelperInfo)); + char *name = g_malloc(64); + unsigned sizemask = 0xFFFFFFFF; + TCGContext *tcg_ctx = uc->tcg_ctx; + GHashTable *helper_table = uc->tcg_ctx->helper_table; + + info->func = hk->callback; + info->name = name; + info->flags = 0; // From helper-head.h + + // Only UC_HOOK_BLOCK and UC_HOOK_CODE is generated into tcg code and can be inlined. + switch (hk->type) { + case UC_HOOK_BLOCK: + case UC_HOOK_CODE: + // (*uc_cb_hookcode_t)(uc_engine *uc, uint64_t address, uint32_t size, void *user_data); + sizemask = dh_sizemask(void, 0) | dh_sizemask(i64, 1) | dh_sizemask(i32, 2) | dh_sizemask(void, 3); + snprintf(name, 63, "hookcode_%d_%" PRIx64 , hk->type, (uint64_t)hk->callback); + break; + + default: + break; + } + + name[63] = 0; + info->name = name; + info->sizemask = sizemask; + + g_hash_table_insert(helper_table, (gpointer)info->func, (gpointer)info); + + tcg_gen_callN(tcg_ctx, info->func, NULL, args_len, (TCGTemp**)args); +} + +void uc_del_inline_hook(uc_engine *uc, struct hook *hk) +{ + GHashTable *helper_table = uc->tcg_ctx->helper_table; + TCGHelperInfo* info = g_hash_table_lookup(helper_table, hk->callback); + + if (info) { + g_hash_table_remove(helper_table, info); + + g_free((gpointer)info->name); + g_free(info); + } +} + + void tcg_context_init(TCGContext *s) { int op, total_args, n, i; diff --git a/qemu/x86_64.h b/qemu/x86_64.h index d0d3fba0..ef4f4ad4 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -4,6 +4,8 @@ #ifndef UNICORN_ARCH_POSTFIX #define UNICORN_ARCH_POSTFIX _x86_64 #endif +#define uc_add_inline_hook uc_add_inline_hook_x86_64 +#define uc_del_inline_hook uc_del_inline_hook_x86_64 #define tb_invalidate_phys_range tb_invalidate_phys_range_x86_64 #define use_idiv_instructions use_idiv_instructions_x86_64 #define arm_arch arm_arch_x86_64 diff --git a/symbols.sh b/symbols.sh index a30c0f90..eaec4b9a 100755 --- a/symbols.sh +++ b/symbols.sh @@ -4,6 +4,8 @@ CMD_PATH=$(realpath $0) SOURCE_DIR=$(dirname ${CMD_PATH}) COMMON_SYMBOLS=" +uc_add_inline_hook \ +uc_del_inline_hook \ tb_invalidate_phys_range \ use_idiv_instructions \ arm_arch \ diff --git a/uc.c b/uc.c index 06f9823b..591ed69c 100644 --- a/uc.c +++ b/uc.c @@ -664,6 +664,7 @@ static void clear_deleted_hooks(uc_engine *uc) for (i = 0; i < UC_HOOK_MAX; i++) { if (list_remove(&uc->hook[i], (void *)hook)) { if (--hook->refs == 0) { + uc->del_inline_hook(uc, hook); free(hook); } @@ -1421,6 +1422,7 @@ uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback, } } + uc->hooks_count[UC_HOOK_INSN_IDX]++; hook->refs++; return UC_ERR_OK; } @@ -1452,6 +1454,7 @@ uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback, } } + uc->hooks_count[UC_HOOK_TCG_OPCODE_IDX]++; hook->refs++; return UC_ERR_OK; } @@ -1475,6 +1478,7 @@ uc_err uc_hook_add(uc_engine *uc, uc_hook *hh, int type, void *callback, return UC_ERR_NOMEM; } } + uc->hooks_count[i]++; hook->refs++; } } @@ -1506,6 +1510,7 @@ uc_err uc_hook_del(uc_engine *uc, uc_hook hh) for (i = 0; i < UC_HOOK_MAX; i++) { if (list_exists(&uc->hook[i], (void *)hook)) { hook->to_delete = true; + uc->hooks_count[i]--; list_append(&uc->hooks_to_del, hook); } } @@ -1562,10 +1567,11 @@ void helper_uc_tracecode(int32_t size, uc_hook_idx index, void *handle, index = index & UC_HOOK_IDX_MASK; + // This has been done in tcg code. // sync PC in CPUArchState with address - if (uc->set_pc) { - uc->set_pc(uc, address); - } + // if (uc->set_pc) { + // uc->set_pc(uc, address); + // } // the last callback may already asked to stop emulation if (uc->stop_request && !(hook_flags & UC_HOOK_FLAG_NO_STOP)) {