aboutsummaryrefslogtreecommitdiff
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);