From c01a6dab0a17d1d558199ccdab2807b1bf441657 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Sat, 17 Feb 2018 14:09:42 -0500 Subject: [PATCH] target-*: Advance pc after recognizing a breakpoint Some targets already had this within their logic, but make sure it's present for all targets. Backports commit 522a0d4e3c0d397ffb45ec400d8cbd426dad9d17 from qemu --- qemu/target-arm/translate-a64.c | 7 +++++-- qemu/target-arm/translate.c | 7 +++++-- qemu/target-i386/translate.c | 5 +++++ qemu/target-m68k/translate.c | 5 +++++ qemu/target-mips/translate.c | 6 ++++-- qemu/target-sparc/translate.c | 2 +- 6 files changed, 25 insertions(+), 7 deletions(-) diff --git a/qemu/target-arm/translate-a64.c b/qemu/target-arm/translate-a64.c index 18ccb366..48e82da0 100644 --- a/qemu/target-arm/translate-a64.c +++ b/qemu/target-arm/translate-a64.c @@ -11323,8 +11323,11 @@ void gen_intermediate_code_a64(ARMCPU *cpu, TranslationBlock *tb) QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { if (bp->pc == dc->pc) { gen_exception_internal_insn(dc, 0, EXCP_DEBUG); - /* Advance PC so that clearing the breakpoint will - invalidate this TB. */ + /* The address covered by the breakpoint must be + included in [tb->pc, tb->pc + tb->size) in order + to for it to be properly cleared -- thus we + increment the PC here so that the logic setting + tb->size below does the right thing. */ dc->pc += 2; goto done_generating; } diff --git a/qemu/target-arm/translate.c b/qemu/target-arm/translate.c index 9195dfb5..f8b00f3e 100644 --- a/qemu/target-arm/translate.c +++ b/qemu/target-arm/translate.c @@ -11572,8 +11572,11 @@ void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb) dc->is_jmp = DISAS_UPDATE; } else { gen_exception_internal_insn(dc, 0, EXCP_DEBUG); - /* Advance PC so that clearing the breakpoint will - invalidate this TB. */ + /* The address covered by the breakpoint must be + included in [tb->pc, tb->pc + tb->size) in order + to for it to be properly cleared -- thus we + increment the PC here so that the logic setting + tb->size below does the right thing. */ /* TODO: Advance PC by correct instruction length to * avoid disassembler error messages */ dc->pc += 2; diff --git a/qemu/target-i386/translate.c b/qemu/target-i386/translate.c index 9028138e..7d7c266c 100644 --- a/qemu/target-i386/translate.c +++ b/qemu/target-i386/translate.c @@ -8708,6 +8708,11 @@ void gen_intermediate_code(CPUX86State *env, TranslationBlock *tb) tb->flags & HF_RF_MASK ? BP_GDB : BP_ANY))) { gen_debug(dc, pc_ptr - dc->cs_base); + /* The address covered by the breakpoint must be included in + [tb->pc, tb->pc + tb->size) in order to for it to be + properly cleared -- thus we increment the PC here so that + the logic setting tb->size below does the right thing. */ + pc_ptr += 1; goto done_generating; } // Unicorn: commented out diff --git a/qemu/target-m68k/translate.c b/qemu/target-m68k/translate.c index 4a2110e9..cabbce57 100644 --- a/qemu/target-m68k/translate.c +++ b/qemu/target-m68k/translate.c @@ -3117,6 +3117,11 @@ void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb) if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) { gen_exception(dc, dc->pc, EXCP_DEBUG); dc->is_jmp = DISAS_JUMP; + /* The address covered by the breakpoint must be included in + [tb->pc, tb->pc + tb->size) in order to for it to be + properly cleared -- thus we increment the PC here so that + the logic setting tb->size below does the right thing. */ + dc->pc += 2; break; } diff --git a/qemu/target-mips/translate.c b/qemu/target-mips/translate.c index 12b74400..2d9fee3f 100644 --- a/qemu/target-mips/translate.c +++ b/qemu/target-mips/translate.c @@ -19779,8 +19779,10 @@ void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb) save_cpu_state(&ctx, 1); ctx.bstate = BS_BRANCH; gen_helper_raise_exception_debug(tcg_ctx, tcg_ctx->cpu_env); - /* Include the breakpoint location or the tb won't - * be flushed when it must be. */ + /* The address covered by the breakpoint must be included in + [tb->pc, tb->pc + tb->size) in order to for it to be + properly cleared -- thus we increment the PC here so that + the logic setting tb->size below does the right thing. */ ctx.pc += 4; goto done_generating; } diff --git a/qemu/target-sparc/translate.c b/qemu/target-sparc/translate.c index 51824750..a5b39c70 100644 --- a/qemu/target-sparc/translate.c +++ b/qemu/target-sparc/translate.c @@ -5425,6 +5425,7 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb) tcg_gen_insn_start(tcg_ctx, dc->pc, dc->npc); } num_insns++; + last_pc = dc->pc; if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) { if (dc->pc != pc_start) { @@ -5446,7 +5447,6 @@ void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb) gen_helper_power_down(tcg_ctx, tcg_ctx->cpu_env); break; } else { - last_pc = dc->pc; insn = cpu_ldl_code(env, dc->pc); }