Signed-off-by: Mihail Abakumov <mikhail.abaku...@ispras.ru> Signed-off-by: Pavel Dovgalyuk <dovga...@ispras.ru> Signed-off-by: Dmitriy Koltunov <koltu...@ispras.ru> --- windbgstub-utils.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+)
diff --git a/windbgstub-utils.c b/windbgstub-utils.c index e33789725e..05caf98c0c 100755 --- a/windbgstub-utils.c +++ b/windbgstub-utils.c @@ -294,11 +294,71 @@ static KDData *kd; static int windbg_hw_breakpoint_insert(CPUState *cpu, int index) { + CPUArchState *env = cpu->env_ptr; + + if (!IS_BP_ENABLED(env->dr[7], index)) { + return 0; + } + + target_ulong addr = env->dr[index]; + int type = BP_TYPE(env->dr[7], index); + int len = BP_LEN(env->dr[7], index); + int err = 0; + + switch (type) { + case DR7_TYPE_DATA_WR: + err = cpu_watchpoint_insert(cpu, addr, len, BP_MEM_WRITE | BP_GDB, + &env->cpu_watchpoint[index]); + break; + case DR7_TYPE_DATA_RW: + err = cpu_watchpoint_insert(cpu, addr, len, BP_MEM_ACCESS | BP_GDB, + &env->cpu_watchpoint[index]); + break; + case DR7_TYPE_BP_INST: + err = cpu_breakpoint_insert(cpu, addr, BP_GDB, + &env->cpu_breakpoint[index]); + break; + case DR7_TYPE_IO_RW: + return HF_IOBPT_MASK; + default: + return 0; + } + + if (!err) { + WINDBG_DEBUG("hw_breakpoint_insert: index(%d), " FMT_ADDR, + index, addr); + } else { + env->cpu_breakpoint[index] = NULL; + WINDBG_ERROR("hw_breakpoint_insert: index(%d), " FMT_ADDR ", " FMT_ERR, + index, addr, err); + } return 0; } static int windbg_hw_breakpoint_remove(CPUState *cpu, int index) { + CPUArchState *env = cpu->env_ptr; + int type = BP_TYPE(env->dr[7], index); + + switch (type) { + case DR7_TYPE_BP_INST: + if (env->cpu_breakpoint[index]) { + cpu_breakpoint_remove_by_ref(cpu, env->cpu_breakpoint[index]); + } + break; + case DR7_TYPE_DATA_WR: + case DR7_TYPE_DATA_RW: + if (env->cpu_watchpoint[index]) { + cpu_watchpoint_remove_by_ref(cpu, env->cpu_watchpoint[index]); + } + break; + default: + return 0; + } + + env->cpu_breakpoint[index] = NULL; + WINDBG_DEBUG("hw_breakpoint_remove: index(%d), " FMT_ADDR, + index, env->dr[index]); return 0; }