summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--cpu-all.h2
-rw-r--r--exec.c21
-rw-r--r--gdbstub.c17
3 files changed, 40 insertions, 0 deletions
diff --git a/cpu-all.h b/cpu-all.h
index 7e77f7656f..d71166c352 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -760,8 +760,10 @@ void cpu_reset_interrupt(CPUState *env, int mask);
 
 int cpu_watchpoint_insert(CPUState *env, target_ulong addr);
 int cpu_watchpoint_remove(CPUState *env, target_ulong addr);
+void cpu_watchpoint_remove_all(CPUState *env);
 int cpu_breakpoint_insert(CPUState *env, target_ulong pc);
 int cpu_breakpoint_remove(CPUState *env, target_ulong pc);
+void cpu_breakpoint_remove_all(CPUState *env);
 
 #define SSTEP_ENABLE  0x1  /* Enable simulated HW single stepping */
 #define SSTEP_NOIRQ   0x2  /* Do not use IRQ while single stepping */
diff --git a/exec.c b/exec.c
index ce2d5d9842..dc13c9bffe 100644
--- a/exec.c
+++ b/exec.c
@@ -1139,6 +1139,16 @@ int cpu_watchpoint_remove(CPUState *env, target_ulong addr)
     return -1;
 }
 
+/* Remove all watchpoints. */
+void cpu_watchpoint_remove_all(CPUState *env) {
+    int i;
+
+    for (i = 0; i < env->nb_watchpoints; i++) {
+        tlb_flush_page(env, env->watchpoint[i].vaddr);
+    }
+    env->nb_watchpoints = 0;
+}
+
 /* add a breakpoint. EXCP_DEBUG is returned by the CPU loop if a
    breakpoint is reached */
 int cpu_breakpoint_insert(CPUState *env, target_ulong pc)
@@ -1162,6 +1172,17 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc)
 #endif
 }
 
+/* remove all breakpoints */
+void cpu_breakpoint_remove_all(CPUState *env) {
+#if defined(TARGET_HAS_ICE)
+    int i;
+    for(i = 0; i < env->nb_breakpoints; i++) {
+        breakpoint_invalidate(env, env->breakpoints[i]);
+    }
+    env->nb_breakpoints = 0;
+#endif
+}
+
 /* remove a breakpoint */
 int cpu_breakpoint_remove(CPUState *env, target_ulong pc)
 {
diff --git a/gdbstub.c b/gdbstub.c
index 9a361e3251..1df598dc67 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -962,6 +962,12 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
         /* TODO: Make this return the correct value for user-mode.  */
         snprintf(buf, sizeof(buf), "S%02x", SIGTRAP);
         put_packet(s, buf);
+        /* Remove all the breakpoints when this query is issued,
+         * because gdb is doing and initial connect and the state
+         * should be cleaned up.
+         */
+        cpu_breakpoint_remove_all(env);
+        cpu_watchpoint_remove_all(env);
         break;
     case 'c':
         if (*p != '\0') {
@@ -985,6 +991,17 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
         }
         gdb_continue(s);
 	return RS_IDLE;
+    case 'k':
+        /* Kill the target */
+        fprintf(stderr, "\nQEMU: Terminated via GDBstub\n");
+        exit(0);
+    case 'D':
+        /* Detach packet */
+        cpu_breakpoint_remove_all(env);
+        cpu_watchpoint_remove_all(env);
+        gdb_continue(s);
+        put_packet(s, "OK");
+        break;
     case 's':
         if (*p != '\0') {
             addr = strtoull(p, (char **)&p, 16);