softmmu: Check watchpoints for read+write at once
Atomic operations are read-modify-write, and we'd like to be able to test both read and write with one call. This is easy enough, with BP_MEM_READ | BP_MEM_WRITE. Add BP_HIT_SHIFT to make it easy to set BP_WATCHPOINT_HIT_*. Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
0953674ed0
commit
019a98083a
@ -923,9 +923,10 @@ void cpu_single_step(CPUState *cpu, int enabled);
|
|||||||
#define BP_GDB 0x10
|
#define BP_GDB 0x10
|
||||||
#define BP_CPU 0x20
|
#define BP_CPU 0x20
|
||||||
#define BP_ANY (BP_GDB | BP_CPU)
|
#define BP_ANY (BP_GDB | BP_CPU)
|
||||||
#define BP_WATCHPOINT_HIT_READ 0x40
|
#define BP_HIT_SHIFT 6
|
||||||
#define BP_WATCHPOINT_HIT_WRITE 0x80
|
#define BP_WATCHPOINT_HIT_READ (BP_MEM_READ << BP_HIT_SHIFT)
|
||||||
#define BP_WATCHPOINT_HIT (BP_WATCHPOINT_HIT_READ | BP_WATCHPOINT_HIT_WRITE)
|
#define BP_WATCHPOINT_HIT_WRITE (BP_MEM_WRITE << BP_HIT_SHIFT)
|
||||||
|
#define BP_WATCHPOINT_HIT (BP_MEM_ACCESS << BP_HIT_SHIFT)
|
||||||
|
|
||||||
int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags,
|
int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags,
|
||||||
CPUBreakpoint **breakpoint);
|
CPUBreakpoint **breakpoint);
|
||||||
|
@ -162,9 +162,12 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
|
|||||||
/* this is currently used only by ARM BE32 */
|
/* this is currently used only by ARM BE32 */
|
||||||
addr = cc->tcg_ops->adjust_watchpoint_address(cpu, addr, len);
|
addr = cc->tcg_ops->adjust_watchpoint_address(cpu, addr, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert((flags & ~BP_MEM_ACCESS) == 0);
|
||||||
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
|
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
|
||||||
if (watchpoint_address_matches(wp, addr, len)
|
int hit_flags = wp->flags & flags;
|
||||||
&& (wp->flags & flags)) {
|
|
||||||
|
if (hit_flags && watchpoint_address_matches(wp, addr, len)) {
|
||||||
if (replay_running_debug()) {
|
if (replay_running_debug()) {
|
||||||
/*
|
/*
|
||||||
* replay_breakpoint reads icount.
|
* replay_breakpoint reads icount.
|
||||||
@ -184,16 +187,14 @@ void cpu_check_watchpoint(CPUState *cpu, vaddr addr, vaddr len,
|
|||||||
replay_breakpoint();
|
replay_breakpoint();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (flags == BP_MEM_READ) {
|
|
||||||
wp->flags |= BP_WATCHPOINT_HIT_READ;
|
wp->flags |= hit_flags << BP_HIT_SHIFT;
|
||||||
} else {
|
|
||||||
wp->flags |= BP_WATCHPOINT_HIT_WRITE;
|
|
||||||
}
|
|
||||||
wp->hitaddr = MAX(addr, wp->vaddr);
|
wp->hitaddr = MAX(addr, wp->vaddr);
|
||||||
wp->hitattrs = attrs;
|
wp->hitattrs = attrs;
|
||||||
|
|
||||||
if (wp->flags & BP_CPU && cc->tcg_ops->debug_check_watchpoint &&
|
if (wp->flags & BP_CPU
|
||||||
!cc->tcg_ops->debug_check_watchpoint(cpu, wp)) {
|
&& cc->tcg_ops->debug_check_watchpoint
|
||||||
|
&& !cc->tcg_ops->debug_check_watchpoint(cpu, wp)) {
|
||||||
wp->flags &= ~BP_WATCHPOINT_HIT;
|
wp->flags &= ~BP_WATCHPOINT_HIT;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user