Message ID | 150642403148.3900.7920017116044093005.stgit@Misha-PC.lan02.inno |
---|---|
State | New |
Headers | show |
Series | Windbg supporting | expand |
On Tue, Sep 26, 2017 at 1:07 PM, Mihail Abakumov <mikhail.abakumov@ispras.ru> wrote: > Signed-off-by: Mihail Abakumov <mikhail.abakumov@ispras.ru> > Signed-off-by: Pavel Dovgalyuk <dovgaluk@ispras.ru> > Signed-off-by: Dmitriy Koltunov <koltunov@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)) { nit: This is already checked by both callers. > + 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; > } > >
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; }