qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 06/12] Restore pc on watchpoint hits


From: Jan Kiszka
Subject: [Qemu-devel] [PATCH 06/12] Restore pc on watchpoint hits
Date: Mon, 03 Nov 2008 11:36:04 +0100
User-agent: quilt/0.46_cvs20080326-19.1

In order to provide accurate information about the triggering
instruction, this patch adds the required bits to restore the pc if the
access happened inside a TB. With the BP_STOP_BEFORE_ACCESS flag, the
watchpoint user can control if the debug trap should be issued on or
after the accessing instruction.

Signed-off-by: Jan Kiszka <address@hidden>
---
 cpu-all.h |    1 +
 exec.c    |   24 ++++++++++++++++++++++--
 2 files changed, 23 insertions(+), 2 deletions(-)

Index: b/exec.c
===================================================================
--- a/exec.c
+++ b/exec.c
@@ -2497,16 +2497,36 @@ static CPUWriteMemoryFunc *notdirty_mem_
 static void check_watchpoint(int offset, int len_mask, int flags)
 {
     CPUState *env = cpu_single_env;
+    TBCPUState cpu_state;
+    TranslationBlock *tb;
     target_ulong vaddr;
     CPUWatchpoint *wp;
 
+    if (env->watchpoint_hit) {
+        /* We re-entered the check after replacing the TB. Now raise
+         * the debug interrupt so that is will trigger after the
+         * current instruction. */
+        cpu_interrupt(env, CPU_INTERRUPT_DEBUG);
+        return;
+    }
     vaddr = (env->mem_io_vaddr & TARGET_PAGE_MASK) + offset;
     for (wp = env->watchpoints; wp != NULL; wp = wp->next) {
         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;
+            tb = tb_find_pc(env->mem_io_pc);
+            if (!tb) {
+                cpu_abort(env, "check_watchpoint: could not find TB for pc=%p",
+                         (void *)env->mem_io_pc);
+            }
+            cpu_restore_state(tb, env, env->mem_io_pc, NULL);
+            tb_phys_invalidate(tb, -1);
+            if (wp->flags & BP_STOP_BEFORE_ACCESS)
+                env->exception_index = EXCP_DEBUG;
+            else {
+                cpu_get_tb_cpu_state(env, &cpu_state);
+                tb_gen_code(env, &cpu_state, 1);
+            } cpu_resume_from_signal(env, NULL);
         }
     }
 }
Index: b/cpu-all.h
===================================================================
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -765,6 +765,7 @@ void cpu_reset_interrupt(CPUState *env,
 #define BP_MEM_READ           0x01
 #define BP_MEM_WRITE          0x02
 #define BP_MEM_ACCESS         (BP_MEM_READ | BP_MEM_WRITE)
+#define BP_STOP_BEFORE_ACCESS 0x04
 #define BP_GDB                0x10
 
 int cpu_breakpoint_insert(CPUState *env, target_ulong pc, int flags,





reply via email to

[Prev in Thread] Current Thread [Next in Thread]