diff --git a/qemu/accel/tcg/translator.c b/qemu/accel/tcg/translator.c index eccf06a7..72f21c41 100644 --- a/qemu/accel/tcg/translator.c +++ b/qemu/accel/tcg/translator.c @@ -74,6 +74,7 @@ void translator_loop(const TranslatorOps *ops, DisasContextBase *db, * full translation cache */ if (HOOK_EXISTS_BOUNDED(uc, UC_HOOK_BLOCK, tb->pc)) { + ops->pc_sync(db, cpu); prev_op = tcg_last_op(tcg_ctx); block_hook = true; gen_uc_tracecode(tcg_ctx, 0xf8f8f8f8, UC_HOOK_BLOCK_IDX, uc, db->pc_first); diff --git a/qemu/include/exec/translator.h b/qemu/include/exec/translator.h index 1b0be080..a86cd759 100644 --- a/qemu/include/exec/translator.h +++ b/qemu/include/exec/translator.h @@ -104,6 +104,8 @@ typedef struct DisasContextBase { * * @tb_stop: * Emit any opcodes required to exit the TB, based on db->is_jmp. + * @pc_sync: + * Sync pc at this point */ typedef struct TranslatorOps { void (*init_disas_context)(DisasContextBase *db, CPUState *cpu); @@ -113,6 +115,7 @@ typedef struct TranslatorOps { const CPUBreakpoint *bp); void (*translate_insn)(DisasContextBase *db, CPUState *cpu); void (*tb_stop)(DisasContextBase *db, CPUState *cpu); + void (*pc_sync)(DisasContextBase *db, CPUState *cpu); } TranslatorOps; /** diff --git a/qemu/target/arm/translate-a64.c b/qemu/target/arm/translate-a64.c index 28abf774..92297653 100644 --- a/qemu/target/arm/translate-a64.c +++ b/qemu/target/arm/translate-a64.c @@ -14834,6 +14834,12 @@ static void aarch64_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) } } +static void aarch64_sync_pc(DisasContextBase *db, CPUState *cpu) +{ + DisasContext *dc = container_of(db, DisasContext, base); + gen_a64_set_pc_im(dc->uc->tcg_ctx, dc->base.pc_next); +} + const TranslatorOps aarch64_translator_ops = { .init_disas_context = aarch64_tr_init_disas_context, .tb_start = aarch64_tr_tb_start, @@ -14841,4 +14847,5 @@ const TranslatorOps aarch64_translator_ops = { .breakpoint_check = aarch64_tr_breakpoint_check, .translate_insn = aarch64_tr_translate_insn, .tb_stop = aarch64_tr_tb_stop, + .pc_sync = aarch64_sync_pc }; diff --git a/qemu/target/arm/translate.c b/qemu/target/arm/translate.c index f8fe7ea7..079b727a 100644 --- a/qemu/target/arm/translate.c +++ b/qemu/target/arm/translate.c @@ -11739,6 +11739,12 @@ static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) } } +static void arm_pc_sync(DisasContextBase *db, CPUState *state) +{ + DisasContext *dc = container_of(db, DisasContext, base); + gen_set_pc_im(dc, dc->base.pc_next); +} + static const TranslatorOps arm_translator_ops = { .init_disas_context = arm_tr_init_disas_context, .tb_start = arm_tr_tb_start, @@ -11746,6 +11752,7 @@ static const TranslatorOps arm_translator_ops = { .breakpoint_check = arm_tr_breakpoint_check, .translate_insn = arm_tr_translate_insn, .tb_stop = arm_tr_tb_stop, + .pc_sync = arm_pc_sync }; static const TranslatorOps thumb_translator_ops = { @@ -11755,6 +11762,7 @@ static const TranslatorOps thumb_translator_ops = { .breakpoint_check = arm_tr_breakpoint_check, .translate_insn = thumb_tr_translate_insn, .tb_stop = arm_tr_tb_stop, + .pc_sync = arm_pc_sync }; /* generate intermediate code for basic block 'tb'. */ diff --git a/qemu/target/i386/translate.c b/qemu/target/i386/translate.c index be632555..741102be 100644 --- a/qemu/target/i386/translate.c +++ b/qemu/target/i386/translate.c @@ -9441,6 +9441,13 @@ static void i386_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) } } +static void i386_sync_pc(DisasContextBase *db, CPUState *cpu) +{ + DisasContext *dc = container_of(db, DisasContext, base); + + gen_jmp_im(dc, dc->base.pc_next - dc->cs_base); +} + static const TranslatorOps i386_tr_ops = { .init_disas_context = i386_tr_init_disas_context, .tb_start = i386_tr_tb_start, @@ -9448,6 +9455,7 @@ static const TranslatorOps i386_tr_ops = { .breakpoint_check = i386_tr_breakpoint_check, .translate_insn = i386_tr_translate_insn, .tb_stop = i386_tr_tb_stop, + .pc_sync = i386_sync_pc, }; /* generate intermediate code for basic block 'tb'. */ diff --git a/qemu/target/m68k/translate.c b/qemu/target/m68k/translate.c index 91dc6aad..5d0fa749 100644 --- a/qemu/target/m68k/translate.c +++ b/qemu/target/m68k/translate.c @@ -6414,6 +6414,13 @@ static void m68k_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) } } +void m68k_sync_pc(DisasContextBase *db, CPUState *cpu) +{ + DisasContext *dc = container_of(db, DisasContext, base); + + tcg_gen_movi_i32(dc->uc->tcg_ctx, QREG_PC, dc->base.pc_next); +} + static const TranslatorOps m68k_tr_ops = { .init_disas_context = m68k_tr_init_disas_context, .tb_start = m68k_tr_tb_start, @@ -6421,6 +6428,7 @@ static const TranslatorOps m68k_tr_ops = { .breakpoint_check = m68k_tr_breakpoint_check, .translate_insn = m68k_tr_translate_insn, .tb_stop = m68k_tr_tb_stop, + .pc_sync = m68k_sync_pc }; void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns) diff --git a/qemu/target/mips/translate.c b/qemu/target/mips/translate.c index f828dbcc..383fcb1b 100644 --- a/qemu/target/mips/translate.c +++ b/qemu/target/mips/translate.c @@ -31063,6 +31063,13 @@ static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) } } +static void mips_sync_pc(DisasContextBase *db, CPUState *cpu) +{ + DisasContext *s = container_of(db, DisasContext, base); + + gen_save_pc(s->uc->tcg_ctx, s->base.pc_next); +} + static const TranslatorOps mips_tr_ops = { .init_disas_context = mips_tr_init_disas_context, .tb_start = mips_tr_tb_start, @@ -31070,6 +31077,7 @@ static const TranslatorOps mips_tr_ops = { .breakpoint_check = mips_tr_breakpoint_check, .translate_insn = mips_tr_translate_insn, .tb_stop = mips_tr_tb_stop, + .pc_sync = mips_sync_pc }; void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) diff --git a/qemu/target/ppc/translate.c b/qemu/target/ppc/translate.c index 1a236913..9822aa32 100644 --- a/qemu/target/ppc/translate.c +++ b/qemu/target/ppc/translate.c @@ -7731,6 +7731,12 @@ static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) } } +static void ppc_sync_pc(DisasContextBase *db, CPUState *cpu) +{ + DisasContext *ctx = container_of(db, DisasContext, base); + gen_update_nip(ctx, ctx->base.pc_next); +} + static const TranslatorOps ppc_tr_ops = { .init_disas_context = ppc_tr_init_disas_context, .tb_start = ppc_tr_tb_start, @@ -7738,6 +7744,7 @@ static const TranslatorOps ppc_tr_ops = { .breakpoint_check = ppc_tr_breakpoint_check, .translate_insn = ppc_tr_translate_insn, .tb_stop = ppc_tr_tb_stop, + .pc_sync = ppc_sync_pc }; void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) diff --git a/qemu/target/riscv/translate.c b/qemu/target/riscv/translate.c index 2ed31178..792bc12f 100644 --- a/qemu/target/riscv/translate.c +++ b/qemu/target/riscv/translate.c @@ -919,6 +919,13 @@ static void riscv_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) } } +static void riscv_sync_pc(DisasContextBase *db, CPUState *cpu) +{ + DisasContext *dc = container_of(db, DisasContext, base); + TCGContext *tcg_ctx = dc->uc->tcg_ctx; + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc, dc->base.pc_next); +} + static const TranslatorOps riscv_tr_ops = { .init_disas_context = riscv_tr_init_disas_context, .tb_start = riscv_tr_tb_start, @@ -926,6 +933,7 @@ static const TranslatorOps riscv_tr_ops = { .breakpoint_check = riscv_tr_breakpoint_check, .translate_insn = riscv_tr_translate_insn, .tb_stop = riscv_tr_tb_stop, + .pc_sync = riscv_sync_pc }; void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) diff --git a/qemu/target/s390x/translate.c b/qemu/target/s390x/translate.c index b9ef06c6..09eea03e 100644 --- a/qemu/target/s390x/translate.c +++ b/qemu/target/s390x/translate.c @@ -6683,6 +6683,8 @@ static DisasJumpType translate_one(CPUS390XState *env, DisasContext *s) // Unicorn: trace this instruction on request if (HOOK_EXISTS_BOUNDED(s->uc, UC_HOOK_CODE, s->base.pc_next)) { + update_psw_addr(s); + update_cc_op(s); gen_uc_tracecode(tcg_ctx, s->ilen, UC_HOOK_CODE_IDX, s->uc, s->base.pc_next); // the callback might want to stop emulation immediately check_exit_request(tcg_ctx); @@ -6928,6 +6930,12 @@ static void s390x_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) } } +static void s390x_sync_pc(DisasContextBase *db, CPUState *cpu) +{ + DisasContext *s = container_of(db, DisasContext, base); + update_psw_addr(s); +} + static const TranslatorOps s390x_tr_ops = { .init_disas_context = s390x_tr_init_disas_context, .tb_start = s390x_tr_tb_start, @@ -6935,6 +6943,7 @@ static const TranslatorOps s390x_tr_ops = { .breakpoint_check = s390x_tr_breakpoint_check, .translate_insn = s390x_tr_translate_insn, .tb_stop = s390x_tr_tb_stop, + .pc_sync = s390x_sync_pc }; void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) diff --git a/qemu/target/sparc/translate.c b/qemu/target/sparc/translate.c index 2891e7fc..95b24ab6 100644 --- a/qemu/target/sparc/translate.c +++ b/qemu/target/sparc/translate.c @@ -6018,6 +6018,15 @@ static void sparc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) } } +static void sparc_sync_pc(DisasContextBase *db, CPUState *cpu) +{ + DisasContext *dc = container_of(db, DisasContext, base); + TCGContext *tcg_ctx = dc->uc->tcg_ctx; + + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc, dc->pc); + tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_npc, dc->npc); +} + static const TranslatorOps sparc_tr_ops = { .init_disas_context = sparc_tr_init_disas_context, .tb_start = sparc_tr_tb_start, @@ -6025,6 +6034,7 @@ static const TranslatorOps sparc_tr_ops = { .breakpoint_check = sparc_tr_breakpoint_check, .translate_insn = sparc_tr_translate_insn, .tb_stop = sparc_tr_tb_stop, + .pc_sync = sparc_sync_pc }; void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns) diff --git a/qemu/target/tricore/translate.c b/qemu/target/tricore/translate.c index 016306fb..75188b8b 100644 --- a/qemu/target/tricore/translate.c +++ b/qemu/target/tricore/translate.c @@ -9297,12 +9297,20 @@ static void tricore_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu) } } +static void tricore_pc_sync(DisasContextBase *db, CPUState *cpu) +{ + DisasContext *ctx = container_of(db, DisasContext, base); + + gen_save_pc(ctx, ctx->base.pc_next); +} + static const TranslatorOps tricore_tr_ops = { .init_disas_context = tricore_tr_init_disas_context, .tb_start = tricore_tr_tb_start, .insn_start = tricore_tr_insn_start, .translate_insn = tricore_tr_translate_insn, .tb_stop = tricore_tr_tb_stop, + .pc_sync = tricore_pc_sync };