From: Jan Kiszka <jan.kiszka@siemens.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 8/15] Respect length of watchpoints
Date: Mon, 23 Jun 2008 16:28:48 +0200 [thread overview]
Message-ID: <485FB320.5060406@siemens.com> (raw)
In-Reply-To: <485FB18E.1090801@siemens.com>
This adds length support for watchpoints. To keep things simple, only
aligned watchpoints are accepted.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
cpu-defs.h | 2 +-
exec.c | 28 ++++++++++++++++++----------
2 files changed, 19 insertions(+), 11 deletions(-)
Index: b/exec.c
===================================================================
--- a/exec.c
+++ b/exec.c
@@ -1145,14 +1145,19 @@ static void breakpoint_invalidate(CPUSta
int cpu_watchpoint_insert(CPUState *env, target_ulong addr, target_ulong len,
int flags, CPUWatchpoint **watchpoint)
{
+ target_ulong len_mask = ~(len - 1);
CPUWatchpoint *wp;
+ /* sanity checks: allow power-of-2 lengths, deny unaligned watchpoints */
+ if ((len != 1 && len != 2 && len != 4) || (addr & ~len_mask))
+ return -EINVAL;
+
wp = qemu_malloc(sizeof(*wp));
if (!wp)
return -ENOBUFS;
wp->vaddr = addr;
- wp->len = len;
+ wp->len_mask = len_mask;
wp->flags = flags;
wp->next = env->watchpoints;
@@ -1176,10 +1181,12 @@ int cpu_watchpoint_insert(CPUState *env,
int cpu_watchpoint_remove(CPUState *env, target_ulong addr, target_ulong len,
int flags)
{
+ target_ulong len_mask = ~(len - 1);
CPUWatchpoint *wp;
for (wp = env->watchpoints; wp != NULL; wp = wp->next) {
- if (addr == wp->vaddr && len == wp->len && flags == wp->flags) {
+ if (addr == wp->vaddr && len_mask == wp->len_mask
+ && flags == wp->flags) {
cpu_watchpoint_remove_by_ref(env, wp);
return 0;
}
@@ -2273,7 +2280,7 @@ static CPUWriteMemoryFunc *notdirty_mem_
};
/* Generate a debug exception if a watchpoint has been hit. */
-static void check_watchpoint(int offset, int flags)
+static void check_watchpoint(int offset, int len_mask, int flags)
{
CPUState *env = cpu_single_env;
target_ulong vaddr;
@@ -2281,7 +2288,8 @@ static void check_watchpoint(int offset,
vaddr = (env->mem_access_vaddr & TARGET_PAGE_MASK) + offset;
for (wp = env->watchpoints; wp != NULL; wp = wp->next) {
- if (vaddr == wp->vaddr && (wp->flags & flags)) {
+ if ((vaddr == (wp->vaddr & len_mask) ||
+ (vaddr & wp->len_mask) == wp->vaddr) && (wp->flags & flags)) {
env->watchpoint_hit = wp;
cpu_interrupt(env, CPU_INTERRUPT_DEBUG);
break;
@@ -2294,40 +2302,40 @@ static void check_watchpoint(int offset,
phys routines. */
static uint32_t watch_mem_readb(void *opaque, target_phys_addr_t addr)
{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, BP_MEM_READ);
+ check_watchpoint(addr & ~TARGET_PAGE_MASK, ~0x0, BP_MEM_READ);
return ldub_phys(addr);
}
static uint32_t watch_mem_readw(void *opaque, target_phys_addr_t addr)
{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, BP_MEM_READ);
+ check_watchpoint(addr & ~TARGET_PAGE_MASK, ~0x1, BP_MEM_READ);
return lduw_phys(addr);
}
static uint32_t watch_mem_readl(void *opaque, target_phys_addr_t addr)
{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, BP_MEM_READ);
+ check_watchpoint(addr & ~TARGET_PAGE_MASK, ~0x3, BP_MEM_READ);
return ldl_phys(addr);
}
static void watch_mem_writeb(void *opaque, target_phys_addr_t addr,
uint32_t val)
{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, BP_MEM_WRITE);
+ check_watchpoint(addr & ~TARGET_PAGE_MASK, ~0x0, BP_MEM_WRITE);
stb_phys(addr, val);
}
static void watch_mem_writew(void *opaque, target_phys_addr_t addr,
uint32_t val)
{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, BP_MEM_WRITE);
+ check_watchpoint(addr & ~TARGET_PAGE_MASK, ~0x1, BP_MEM_WRITE);
stw_phys(addr, val);
}
static void watch_mem_writel(void *opaque, target_phys_addr_t addr,
uint32_t val)
{
- check_watchpoint(addr & ~TARGET_PAGE_MASK, BP_MEM_WRITE);
+ check_watchpoint(addr & ~TARGET_PAGE_MASK, ~0x3, BP_MEM_WRITE);
stl_phys(addr, val);
}
Index: b/cpu-defs.h
===================================================================
--- a/cpu-defs.h
+++ b/cpu-defs.h
@@ -136,7 +136,7 @@ typedef struct CPUBreakpoint {
typedef struct CPUWatchpoint {
target_ulong vaddr;
- target_ulong len;
+ target_ulong len_mask;
int flags; /* BP_* */
struct CPUWatchpoint *prev, *next;
} CPUWatchpoint;
next prev parent reply other threads:[~2008-06-23 14:35 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-06-23 14:22 [Qemu-devel] [PATCH 0/15] Enhance debugging support Jan Kiszka
2008-06-23 14:23 ` [Qemu-devel] [PATCH 1/15] Convert remaining __builtin_expect to likely/unlikely Jan Kiszka
2008-06-23 14:24 ` [Qemu-devel] [PATCH 2/15] Introduce SSTEP_INTERNAL Jan Kiszka
2008-06-23 14:24 ` [Qemu-devel] [PATCH 3/15] Replace CF_SINGLE_INSN with SSTEP_INTERNAL - v2 Jan Kiszka
2008-06-23 14:25 ` [Qemu-devel] [PATCH 4/15] Remove unused TB cflags Jan Kiszka
2008-06-23 14:26 ` [Qemu-devel] [PATCH 5/15] Return appropriate watch message to gdb Jan Kiszka
2008-06-23 14:26 ` [Qemu-devel] [PATCH 6/15] Refactor and enhance break/watchpoint API - v5 Jan Kiszka
2008-06-23 14:27 ` [Qemu-devel] [PATCH 7/15] Extend mem_write_* to mem_access_* Jan Kiszka
2008-06-23 14:28 ` Jan Kiszka [this message]
2008-06-23 14:29 ` [Qemu-devel] [PATCH 9/15] Restore pc on watchpoint hits Jan Kiszka
2008-06-23 14:30 ` [Qemu-devel] [PATCH 10/15] Remove premature memop TB terminations Jan Kiszka
2008-06-23 14:31 ` [Qemu-devel] [PATCH 11/15] Improve debugging of SMP guests - v2 Jan Kiszka
2008-06-23 14:32 ` [Qemu-devel] [PATCH 12/15] Introduce BP_WATCHPOINT_HIT flag Jan Kiszka
2008-06-23 14:32 ` [Qemu-devel] [PATCH 13/15] Add debug exception hook Jan Kiszka
2008-06-23 14:33 ` [Qemu-devel] [PATCH 14/15] Introduce BP_CPU as a breakpoint type Jan Kiszka
2008-06-23 14:33 ` [Qemu-devel] [PATCH 15/15] x86: Debug register emulation Jan Kiszka
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=485FB320.5060406@siemens.com \
--to=jan.kiszka@siemens.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.