hw/eeprom93xx.c: substitute structure dump with discrete dump in eeprom_save/load
[qemu] / gdbstub.c
index 27e887e..518c939 100644 (file)
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -39,6 +39,7 @@
 #define MAX_PACKET_LENGTH 4096
 
 #include "qemu_socket.h"
+#include "kvm.h"
 
 
 enum {
@@ -264,6 +265,7 @@ typedef struct GDBRegisterState {
 } GDBRegisterState;
 
 enum RSState {
+    RS_INACTIVE,
     RS_IDLE,
     RS_GETLINE,
     RS_CHKSUM1,
@@ -1418,13 +1420,6 @@ void gdb_register_coprocessor(CPUState * env,
     }
 }
 
-/* GDB breakpoint/watchpoint types */
-#define GDB_BREAKPOINT_SW        0
-#define GDB_BREAKPOINT_HW        1
-#define GDB_WATCHPOINT_WRITE     2
-#define GDB_WATCHPOINT_READ      3
-#define GDB_WATCHPOINT_ACCESS    4
-
 #ifndef CONFIG_USER_ONLY
 static const int xlat_gdb_type[] = {
     [GDB_WATCHPOINT_WRITE]  = BP_GDB | BP_MEM_WRITE,
@@ -1438,6 +1433,9 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
     CPUState *env;
     int err = 0;
 
+    if (kvm_enabled())
+        return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type);
+
     switch (type) {
     case GDB_BREAKPOINT_SW:
     case GDB_BREAKPOINT_HW:
@@ -1469,6 +1467,9 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
     CPUState *env;
     int err = 0;
 
+    if (kvm_enabled())
+        return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type);
+
     switch (type) {
     case GDB_BREAKPOINT_SW:
     case GDB_BREAKPOINT_HW:
@@ -1498,6 +1499,11 @@ static void gdb_breakpoint_remove_all(void)
 {
     CPUState *env;
 
+    if (kvm_enabled()) {
+        kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
+        return;
+    }
+
     for (env = first_cpu; env != NULL; env = env->next_cpu) {
         cpu_breakpoint_remove_all(env, BP_GDB);
 #ifndef CONFIG_USER_ONLY
@@ -1538,6 +1544,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             addr = strtoull(p, (char **)&p, 16);
 #if defined(TARGET_I386)
             s->c_cpu->eip = addr;
+            cpu_synchronize_state(s->c_cpu, 1);
 #elif defined (TARGET_PPC)
             s->c_cpu->nip = addr;
 #elif defined (TARGET_SPARC)
@@ -1579,6 +1586,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             addr = strtoull(p, (char **)&p, 16);
 #if defined(TARGET_I386)
             s->c_cpu->eip = addr;
+            cpu_synchronize_state(s->c_cpu, 1);
 #elif defined (TARGET_PPC)
             s->c_cpu->nip = addr;
 #elif defined (TARGET_SPARC)
@@ -1624,6 +1632,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         }
         break;
     case 'g':
+        cpu_synchronize_state(s->g_cpu, 0);
         len = 0;
         for (addr = 0; addr < num_g_regs; addr++) {
             reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
@@ -1641,6 +1650,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             len -= reg_size;
             registers += reg_size;
         }
+        cpu_synchronize_state(s->g_cpu, 1);
         put_packet(s, "OK");
         break;
     case 'm':
@@ -1799,6 +1809,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             thread = strtoull(p+16, (char **)&p, 16);
             for (env = first_cpu; env != NULL; env = env->next_cpu)
                 if (env->cpu_index + 1 == thread) {
+                    cpu_synchronize_state(env, 0);
                     len = snprintf((char *)mem_buf, sizeof(mem_buf),
                                    "CPU#%d [%s]", env->cpu_index,
                                    env->halted ? "halted " : "running");
@@ -1808,7 +1819,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
                 }
             break;
         }
-#ifdef CONFIG_LINUX_USER
+#ifdef CONFIG_USER_ONLY
         else if (strncmp(p, "Offsets", 7) == 0) {
             TaskState *ts = s->c_cpu->opaque;
 
@@ -1821,7 +1832,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             put_packet(s, buf);
             break;
         }
-#else /* !CONFIG_LINUX_USER */
+#else /* !CONFIG_USER_ONLY */
         else if (strncmp(p, "Rcmd,", 5) == 0) {
             int len = strlen(p + 5);
 
@@ -1836,7 +1847,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             put_packet(s, "OK");
             break;
         }
-#endif /* !CONFIG_LINUX_USER */
+#endif /* !CONFIG_USER_ONLY */
         if (strncmp(p, "Supported", 9) == 0) {
             snprintf(buf, sizeof(buf), "PacketSize=%x", MAX_PACKET_LENGTH);
 #ifdef GDB_CORE_XML
@@ -1914,7 +1925,7 @@ static void gdb_vm_state_change(void *opaque, int running, int reason)
     int ret;
 
     if (running || (reason != EXCP_DEBUG && reason != EXCP_INTERRUPT) ||
-        s->state == RS_SYSCALL)
+        s->state == RS_INACTIVE || s->state == RS_SYSCALL)
         return;
 
     /* disable single step if it was enable */
@@ -2012,7 +2023,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
 #ifdef CONFIG_USER_ONLY
     gdb_handlesig(s->c_cpu, 0);
 #else
-    cpu_interrupt(s->c_cpu, CPU_INTERRUPT_EXIT);
+    cpu_exit(s->c_cpu);
 #endif
 }
 
@@ -2206,8 +2217,6 @@ static void gdb_accept(void)
     setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
 
     s = qemu_mallocz(sizeof(GDBState));
-
-    memset (s, 0, sizeof (GDBState));
     s->c_cpu = first_cpu;
     s->g_cpu = first_cpu;
     s->fd = fd;
@@ -2334,36 +2343,50 @@ int gdbserver_start(const char *port)
     char gdbstub_port_name[128];
     int port_num;
     char *p;
-    CharDriverState *chr;
+    CharDriverState *chr = NULL;
+    CharDriverState *mon_chr;
 
     if (!port || !*port)
       return -1;
+    if (strcmp(port, "none") != 0) {
+        port_num = strtol(port, &p, 10);
+        if (*p == 0) {
+            /* A numeric value is interpreted as a port number.  */
+            snprintf(gdbstub_port_name, sizeof(gdbstub_port_name),
+                     "tcp::%d,nowait,nodelay,server", port_num);
+            port = gdbstub_port_name;
+        }
+
+        chr = qemu_chr_open("gdb", port, NULL);
+        if (!chr)
+            return -1;
 
-    port_num = strtol(port, &p, 10);
-    if (*p == 0) {
-        /* A numeric value is interpreted as a port number.  */
-        snprintf(gdbstub_port_name, sizeof(gdbstub_port_name),
-                 "tcp::%d,nowait,nodelay,server", port_num);
-        port = gdbstub_port_name;
+        qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
+                              gdb_chr_event, NULL);
     }
 
-    chr = qemu_chr_open("gdb", port, NULL);
-    if (!chr)
-        return -1;
+    s = gdbserver_state;
+    if (!s) {
+        s = qemu_mallocz(sizeof(GDBState));
+        gdbserver_state = s;
 
-    s = qemu_mallocz(sizeof(GDBState));
+        qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
+
+        /* Initialize a monitor terminal for gdb */
+        mon_chr = qemu_mallocz(sizeof(*mon_chr));
+        mon_chr->chr_write = gdb_monitor_write;
+        monitor_init(mon_chr, 0);
+    } else {
+        if (s->chr)
+            qemu_chr_close(s->chr);
+        mon_chr = s->mon_chr;
+        memset(s, 0, sizeof(GDBState));
+    }
     s->c_cpu = first_cpu;
     s->g_cpu = first_cpu;
     s->chr = chr;
-    gdbserver_state = s;
-    qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
-                          gdb_chr_event, NULL);
-    qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
-
-    /* Initialize a monitor terminal for gdb */
-    s->mon_chr = qemu_mallocz(sizeof(*s->mon_chr));
-    s->mon_chr->chr_write = gdb_monitor_write;
-    monitor_init(s->mon_chr, 0);
+    s->state = chr ? RS_IDLE : RS_INACTIVE;
+    s->mon_chr = mon_chr;
 
     return 0;
 }