]> git.proxmox.com Git - qemu.git/blobdiff - gdbstub.c
Merge git://github.com/hw-claudio/qemu-aarch64-queue into tcg-next
[qemu.git] / gdbstub.c
index e62dc798c3136f1f0e152f9458fe50b3e18328c6..0ee82a944f9b4fca7ba50f0dd754da7ea5da4fe9 100644 (file)
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -30,7 +30,7 @@
 #include "qemu.h"
 #else
 #include "monitor/monitor.h"
-#include "char/char.h"
+#include "sysemu/char.h"
 #include "sysemu/sysemu.h"
 #include "exec/gdbstub.h"
 #endif
@@ -371,7 +371,12 @@ static inline void gdb_continue(GDBState *s)
 #ifdef CONFIG_USER_ONLY
     s->running_state = 1;
 #else
-    vm_start();
+    if (runstate_check(RUN_STATE_GUEST_PANICKED)) {
+        runstate_set(RUN_STATE_DEBUG);
+    }
+    if (!runstate_needs_reset()) {
+        vm_start();
+    }
 #endif
 }
 
@@ -781,7 +786,8 @@ static int cpu_gdb_write_register(CPUPPCState *env, uint8_t *mem_buf, int n)
             /* fpscr */
             if (gdb_has_xml)
                 return 0;
-            return 4;
+            store_fpscr(env, ldtul_p(mem_buf), 0xffffffff);
+            return sizeof(target_ulong);
         }
     }
     return 0;
@@ -1606,7 +1612,7 @@ static int cpu_gdb_write_register(CPUS390XState *env, uint8_t *mem_buf, int n)
 }
 #elif defined (TARGET_LM32)
 
-#include "hw/lm32_pic.h"
+#include "hw/lm32/lm32_pic.h"
 #define NUM_CORE_REGS (32 + 7)
 
 static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n)
@@ -1833,6 +1839,7 @@ static const char *get_feature_xml(const char *p, const char **newp)
         /* Generate the XML description for this CPU.  */
         if (!target_xml[0]) {
             GDBRegisterState *r;
+            CPUArchState *env = first_cpu->env_ptr;
 
             snprintf(target_xml, sizeof(target_xml),
                      "<?xml version=\"1.0\"?>"
@@ -1841,7 +1848,7 @@ static const char *get_feature_xml(const char *p, const char **newp)
                      "<xi:include href=\"%s\"/>",
                      GDB_CORE_XML);
 
-            for (r = first_cpu->gdb_regs; r; r = r->next) {
+            for (r = env->gdb_regs; r; r = r->next) {
                 pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
                 pstrcat(target_xml, sizeof(target_xml), r->xml);
                 pstrcat(target_xml, sizeof(target_xml), "\"/>");
@@ -1943,6 +1950,7 @@ static const int xlat_gdb_type[] = {
 
 static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
 {
+    CPUState *cpu;
     CPUArchState *env;
     int err = 0;
 
@@ -1952,7 +1960,8 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
     switch (type) {
     case GDB_BREAKPOINT_SW:
     case GDB_BREAKPOINT_HW:
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+            env = cpu->env_ptr;
             err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
             if (err)
                 break;
@@ -1962,7 +1971,8 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
     case GDB_WATCHPOINT_WRITE:
     case GDB_WATCHPOINT_READ:
     case GDB_WATCHPOINT_ACCESS:
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+            env = cpu->env_ptr;
             err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
                                         NULL);
             if (err)
@@ -1977,6 +1987,7 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
 
 static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
 {
+    CPUState *cpu;
     CPUArchState *env;
     int err = 0;
 
@@ -1986,7 +1997,8 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
     switch (type) {
     case GDB_BREAKPOINT_SW:
     case GDB_BREAKPOINT_HW:
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+            env = cpu->env_ptr;
             err = cpu_breakpoint_remove(env, addr, BP_GDB);
             if (err)
                 break;
@@ -1996,7 +2008,8 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
     case GDB_WATCHPOINT_WRITE:
     case GDB_WATCHPOINT_READ:
     case GDB_WATCHPOINT_ACCESS:
-        for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+            env = cpu->env_ptr;
             err = cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
             if (err)
                 break;
@@ -2010,14 +2023,16 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
 
 static void gdb_breakpoint_remove_all(void)
 {
+    CPUState *cpu;
     CPUArchState *env;
 
     if (kvm_enabled()) {
-        kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
+        kvm_remove_all_breakpoints(ENV_GET_CPU(gdbserver_state->c_cpu));
         return;
     }
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        env = cpu->env_ptr;
         cpu_breakpoint_remove_all(env, BP_GDB);
 #ifndef CONFIG_USER_ONLY
         cpu_watchpoint_remove_all(env, BP_GDB);
@@ -2027,7 +2042,7 @@ static void gdb_breakpoint_remove_all(void)
 
 static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
 {
-    cpu_synchronize_state(s->c_cpu);
+    cpu_synchronize_state(ENV_GET_CPU(s->c_cpu));
 #if defined(TARGET_I386)
     s->c_cpu->eip = pc;
 #elif defined (TARGET_PPC)
@@ -2065,11 +2080,11 @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
 
 static CPUArchState *find_cpu(uint32_t thread_id)
 {
-    CPUArchState *env;
+    CPUState *cpu;
 
-    for (env = first_cpu; env != NULL; env = env->next_cpu) {
-        if (cpu_index(env) == thread_id) {
-            return env;
+    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        if (cpu_index(cpu) == thread_id) {
+            return cpu->env_ptr;
         }
     }
 
@@ -2096,7 +2111,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
     case '?':
         /* TODO: Make this return the correct value for user-mode.  */
         snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP,
-                 cpu_index(s->c_cpu));
+                 cpu_index(ENV_GET_CPU(s->c_cpu)));
         put_packet(s, buf);
         /* Remove all the breakpoints when this query is issued,
          * because gdb is doing and initial connect and the state
@@ -2224,7 +2239,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         }
         break;
     case 'g':
-        cpu_synchronize_state(s->g_cpu);
+        cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
         env = s->g_cpu;
         len = 0;
         for (addr = 0; addr < num_g_regs; addr++) {
@@ -2235,7 +2250,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         put_packet(s, buf);
         break;
     case 'G':
-        cpu_synchronize_state(s->g_cpu);
+        cpu_synchronize_state(ENV_GET_CPU(s->g_cpu));
         env = s->g_cpu;
         registers = mem_buf;
         len = strlen(p) / 2;
@@ -2386,14 +2401,15 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             put_packet(s, "QC1");
             break;
         } else if (strcmp(p,"fThreadInfo") == 0) {
-            s->query_cpu = first_cpu;
+            s->query_cpu = first_cpu->env_ptr;
             goto report_cpuinfo;
         } else if (strcmp(p,"sThreadInfo") == 0) {
         report_cpuinfo:
             if (s->query_cpu) {
-                snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu));
+                snprintf(buf, sizeof(buf), "m%x",
+                         cpu_index(ENV_GET_CPU(s->query_cpu)));
                 put_packet(s, buf);
-                s->query_cpu = s->query_cpu->next_cpu;
+                s->query_cpu = ENV_GET_CPU(s->query_cpu)->next_cpu->env_ptr;
             } else
                 put_packet(s, "l");
             break;
@@ -2401,10 +2417,11 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             thread = strtoull(p+16, (char **)&p, 16);
             env = find_cpu(thread);
             if (env != NULL) {
-                cpu_synchronize_state(env);
+                CPUState *cpu = ENV_GET_CPU(env);
+                cpu_synchronize_state(cpu);
                 len = snprintf((char *)mem_buf, sizeof(mem_buf),
-                               "CPU#%d [%s]", env->cpu_index,
-                               env->halted ? "halted " : "running");
+                               "CPU#%d [%s]", cpu->cpu_index,
+                               cpu->halted ? "halted " : "running");
                 memtohex(buf, mem_buf, len);
                 put_packet(s, buf);
             }
@@ -2500,8 +2517,10 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
     return RS_IDLE;
 }
 
-void gdb_set_stop_cpu(CPUArchState *env)
+void gdb_set_stop_cpu(CPUState *cpu)
 {
+    CPUArchState *env = cpu->env_ptr;
+
     gdbserver_state->c_cpu = env;
     gdbserver_state->g_cpu = env;
 }
@@ -2511,6 +2530,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
 {
     GDBState *s = gdbserver_state;
     CPUArchState *env = s->c_cpu;
+    CPUState *cpu = ENV_GET_CPU(env);
     char buf[256];
     const char *type;
     int ret;
@@ -2539,7 +2559,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
             }
             snprintf(buf, sizeof(buf),
                      "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
-                     GDB_SIGNAL_TRAP, cpu_index(env), type,
+                     GDB_SIGNAL_TRAP, cpu_index(cpu), type,
                      env->watchpoint_hit->vaddr);
             env->watchpoint_hit = NULL;
             goto send_packet;
@@ -2572,7 +2592,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
         ret = GDB_SIGNAL_UNKNOWN;
         break;
     }
-    snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_index(env));
+    snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_index(cpu));
 
 send_packet:
     put_packet(s, buf);
@@ -2648,7 +2668,7 @@ void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
        is still in the running state, which can cause packets to be dropped
        and state transition 'T' packets to be sent while the syscall is still
        being processed.  */
-    cpu_exit(s->c_cpu);
+    cpu_exit(ENV_GET_CPU(s->c_cpu));
 #endif
 }
 
@@ -2836,7 +2856,7 @@ static void gdb_accept(void)
     GDBState *s;
     struct sockaddr_in sockaddr;
     socklen_t len;
-    int val, fd;
+    int fd;
 
     for(;;) {
         len = sizeof(sockaddr);
@@ -2853,12 +2873,11 @@ static void gdb_accept(void)
     }
 
     /* set short latency */
-    val = 1;
-    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
+    socket_set_nodelay(fd);
 
     s = g_malloc0(sizeof(GDBState));
-    s->c_cpu = first_cpu;
-    s->g_cpu = first_cpu;
+    s->c_cpu = first_cpu->env_ptr;
+    s->g_cpu = first_cpu->env_ptr;
     s->fd = fd;
     gdb_has_xml = 0;
 
@@ -2883,7 +2902,7 @@ static int gdbserver_open(int port)
 
     /* allow fast reuse */
     val = 1;
-    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
+    qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
 
     sockaddr.sin_family = AF_INET;
     sockaddr.sin_port = htons(port);
@@ -3020,6 +3039,7 @@ int gdbserver_start(const char *device)
         if (!chr)
             return -1;
 
+        qemu_chr_fe_claim_no_fail(chr);
         qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
                               gdb_chr_event, NULL);
     }
@@ -3041,8 +3061,8 @@ int gdbserver_start(const char *device)
         mon_chr = s->mon_chr;
         memset(s, 0, sizeof(GDBState));
     }
-    s->c_cpu = first_cpu;
-    s->g_cpu = first_cpu;
+    s->c_cpu = first_cpu->env_ptr;
+    s->g_cpu = first_cpu->env_ptr;
     s->chr = chr;
     s->state = chr ? RS_IDLE : RS_INACTIVE;
     s->mon_chr = mon_chr;