The do_trigger_action() receives index of fired trigger as second parameter. However, in current implementation, the argument is hardcoded as DBG_ACTION_BP which is 0. This is a bug because we may match/fire any breakpoints or watchpoints at other index than 0.
Fix this bug by iterating cpu_breakpoint[] and cpu_watchpoint[] to compare and match necessary checkpoints. The index of the fired cpu_breakpoint or the cpu_watchpoint is the index of the trigger we want to provide to do_trigger_action(). Signed-off-by: Alvin Chang <[email protected]> Reviewed-by: Yu-Ming Chang <[email protected]> --- target/riscv/debug.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/target/riscv/debug.c b/target/riscv/debug.c index 5664466..f3bca8e 100644 --- a/target/riscv/debug.c +++ b/target/riscv/debug.c @@ -929,11 +929,24 @@ void riscv_cpu_debug_excp_handler(CPUState *cs) if (cs->watchpoint_hit) { if (cs->watchpoint_hit->flags & BP_CPU) { - do_trigger_action(env, DBG_ACTION_BP); + /* Search fired trigger and do its action */ + for (int i = 0; i < ARRAY_SIZE(env->cpu_watchpoint); i++) { + if (cs->watchpoint_hit == env->cpu_watchpoint[i]) { + do_trigger_action(env, i); + break; + } + } } } else { if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) { - do_trigger_action(env, DBG_ACTION_BP); + /* Search fired trigger and do its action */ + for (int i = 0; i < ARRAY_SIZE(env->cpu_breakpoint); i++) { + CPUBreakpoint *bp = env->cpu_breakpoint[i]; + if (bp && bp->pc == env->pc && (bp->flags & BP_CPU)) { + do_trigger_action(env, i); + break; + } + } } } } -- 2.43.0
