diff options
-rw-r--r-- | cpu-all.h | 2 | ||||
-rw-r--r-- | exec.c | 21 | ||||
-rw-r--r-- | gdbstub.c | 17 |
3 files changed, 40 insertions, 0 deletions
@@ -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 */ @@ -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) { @@ -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); |