Since force_dr6_update is set exclusively for breakpoints, replace force_dr6_update with wp_hit == NULL.
Use the value of wp_hit to notice which watchpoint is hit. Signed-off-by: Richard Henderson <[email protected]> --- target/i386/tcg/helper-tcg.h | 2 +- target/i386/tcg/bpt_helper.c | 2 +- target/i386/tcg/system/bpt_helper.c | 32 ++++++++++++----------------- 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/target/i386/tcg/helper-tcg.h b/target/i386/tcg/helper-tcg.h index 01f4a8bcd0..2227712e2e 100644 --- a/target/i386/tcg/helper-tcg.h +++ b/target/i386/tcg/helper-tcg.h @@ -114,7 +114,7 @@ int exception_has_error_code(int intno); void do_smm_enter(X86CPU *cpu); /* system/bpt_helper.c */ -bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update); +bool check_hw_breakpoints(CPUX86State *env, CPUBreakpoint *wp_hit); /* * Do the tasks usually performed by gen_eob(). Callers of this function diff --git a/target/i386/tcg/bpt_helper.c b/target/i386/tcg/bpt_helper.c index bc34ac27fe..bcb9869c86 100644 --- a/target/i386/tcg/bpt_helper.c +++ b/target/i386/tcg/bpt_helper.c @@ -25,7 +25,7 @@ G_NORETURN void helper_single_step(CPUX86State *env) { #ifndef CONFIG_USER_ONLY - check_hw_breakpoints(env, true); + check_hw_breakpoints(env, NULL); env->dr[6] |= DR6_BS; #endif raise_exception(env, EXCP01_DB); diff --git a/target/i386/tcg/system/bpt_helper.c b/target/i386/tcg/system/bpt_helper.c index 8ba5dfcfc1..5dab77b2c4 100644 --- a/target/i386/tcg/system/bpt_helper.c +++ b/target/i386/tcg/system/bpt_helper.c @@ -160,34 +160,27 @@ void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7) env->hflags = (env->hflags & ~HF_IOBPT_MASK) | iobpt; } -bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update) +bool check_hw_breakpoints(CPUX86State *env, CPUBreakpoint *wp_hit) { - target_ulong dr6; - int reg; + target_ulong dr6 = env->dr[6] & ~0xf; + bool force_dr6_update = wp_hit == NULL; bool hit_enabled = false; - dr6 = env->dr[6] & ~0xf; - for (reg = 0; reg < DR7_MAX_BP; reg++) { - bool bp_match = false; - bool wp_match = false; + for (int reg = 0; reg < DR7_MAX_BP; reg++) { + bool match = false; switch (hw_breakpoint_type(env->dr[7], reg)) { case DR7_TYPE_BP_INST: - if (env->dr[reg] == env->eip) { - bp_match = true; - } + match = env->dr[reg] == env->eip; break; case DR7_TYPE_DATA_WR: case DR7_TYPE_DATA_RW: - if (env->cpu_watchpoint[reg] && - env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT) { - wp_match = true; - } + match = wp_hit == env->cpu_watchpoint[reg]; break; case DR7_TYPE_IO_RW: break; } - if (bp_match || wp_match) { + if (match) { dr6 |= 1 << reg; if (hw_breakpoint_enabled(env->dr[7], reg)) { hit_enabled = true; @@ -207,10 +200,11 @@ void breakpoint_handler(CPUState *cs, CPUBreakpoint *hit) X86CPU *cpu = X86_CPU(cs); CPUX86State *env = &cpu->env; - if (cs->watchpoint_hit) { - if (cs->watchpoint_hit->flags & BP_CPU) { + hit = cs->watchpoint_hit; + if (hit) { + if (hit->flags & BP_CPU) { cs->watchpoint_hit = NULL; - if (check_hw_breakpoints(env, false)) { + if (check_hw_breakpoints(env, hit)) { /* * FIXME: #DB should be delayed by one instruction if * INHIBIT_IRQ is set (STI cannot trigger a watchpoint). @@ -224,7 +218,7 @@ void breakpoint_handler(CPUState *cs, CPUBreakpoint *hit) } } else { if (cpu_breakpoint_test(cs, env->eip, BP_CPU)) { - check_hw_breakpoints(env, true); + check_hw_breakpoints(env, NULL); raise_exception(env, EXCP01_DB); } } -- 2.43.0
