]> git.proxmox.com Git - mirror_qemu.git/blobdiff - gdbstub.c
Merge remote-tracking branch 'jliu/or32' into staging
[mirror_qemu.git] / gdbstub.c
index a91709f27121ee2bcbf851d44345c41e702623b7..35ca7c2c1e7d134cf18dab7af4d4ec78f242483e 100644 (file)
--- a/gdbstub.c
+++ b/gdbstub.c
 
 #include "qemu.h"
 #else
-#include "monitor.h"
-#include "qemu-char.h"
-#include "sysemu.h"
-#include "gdbstub.h"
+#include "monitor/monitor.h"
+#include "sysemu/char.h"
+#include "sysemu/sysemu.h"
+#include "exec/gdbstub.h"
 #endif
 
 #define MAX_PACKET_LENGTH 4096
 
 #include "cpu.h"
-#include "qemu_socket.h"
-#include "kvm.h"
+#include "qemu/sockets.h"
+#include "sysemu/kvm.h"
+#include "qemu/bitops.h"
 
-#ifndef TARGET_CPU_MEMORY_RW_DEBUG
-static inline int target_memory_rw_debug(CPUArchState *env, target_ulong addr,
-                                         uint8_t *buf, int len, int is_write)
+static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
+                                         uint8_t *buf, int len, bool is_write)
 {
-    return cpu_memory_rw_debug(env, addr, buf, len, is_write);
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
+    if (cc->memory_rw_debug) {
+        return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
+    }
+    return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
 }
-#else
-/* target_memory_rw_debug() defined in cpu.h */
-#endif
 
 enum {
     GDB_SIGNAL_0 = 0,
@@ -286,9 +288,9 @@ enum RSState {
     RS_CHKSUM2,
 };
 typedef struct GDBState {
-    CPUArchState *c_cpu; /* current CPU for step/continue ops */
-    CPUArchState *g_cpu; /* current CPU for other ops */
-    CPUArchState *query_cpu; /* for q{f|s}ThreadInfo */
+    CPUState *c_cpu; /* current CPU for step/continue ops */
+    CPUState *g_cpu; /* current CPU for other ops */
+    CPUState *query_cpu; /* for q{f|s}ThreadInfo */
     enum RSState state; /* parsing state */
     char line_buf[MAX_PACKET_LENGTH];
     int line_buf_index;
@@ -370,7 +372,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
 }
 
@@ -780,7 +787,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;
@@ -1535,27 +1543,34 @@ static int cpu_gdb_write_register(CPUAlphaState *env, uint8_t *mem_buf, int n)
 }
 #elif defined (TARGET_S390X)
 
-#define NUM_CORE_REGS S390_NUM_TOTAL_REGS
+#define NUM_CORE_REGS  S390_NUM_REGS
 
 static int cpu_gdb_read_register(CPUS390XState *env, uint8_t *mem_buf, int n)
 {
+    uint64_t val;
+    int cc_op;
+
     switch (n) {
-        case S390_PSWM_REGNUM: GET_REGL(env->psw.mask); break;
-        case S390_PSWA_REGNUM: GET_REGL(env->psw.addr); break;
-        case S390_R0_REGNUM ... S390_R15_REGNUM:
-            GET_REGL(env->regs[n-S390_R0_REGNUM]); break;
-        case S390_A0_REGNUM ... S390_A15_REGNUM:
-            GET_REG32(env->aregs[n-S390_A0_REGNUM]); break;
-        case S390_FPC_REGNUM: GET_REG32(env->fpc); break;
-        case S390_F0_REGNUM ... S390_F15_REGNUM:
-            /* XXX */
-            break;
-        case S390_PC_REGNUM: GET_REGL(env->psw.addr); break;
-        case S390_CC_REGNUM:
-            env->cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst,
-                                 env->cc_vr);
-            GET_REG32(env->cc_op);
-            break;
+    case S390_PSWM_REGNUM:
+        cc_op = calc_cc(env, env->cc_op, env->cc_src, env->cc_dst, env->cc_vr);
+        val = deposit64(env->psw.mask, 44, 2, cc_op);
+        GET_REGL(val);
+        break;
+    case S390_PSWA_REGNUM:
+        GET_REGL(env->psw.addr);
+        break;
+    case S390_R0_REGNUM ... S390_R15_REGNUM:
+        GET_REGL(env->regs[n-S390_R0_REGNUM]);
+        break;
+    case S390_A0_REGNUM ... S390_A15_REGNUM:
+        GET_REG32(env->aregs[n-S390_A0_REGNUM]);
+        break;
+    case S390_FPC_REGNUM:
+        GET_REG32(env->fpc);
+        break;
+    case S390_F0_REGNUM ... S390_F15_REGNUM:
+        GET_REG64(env->fregs[n-S390_F0_REGNUM].ll);
+        break;
     }
 
     return 0;
@@ -1570,25 +1585,35 @@ static int cpu_gdb_write_register(CPUS390XState *env, uint8_t *mem_buf, int n)
     tmp32 = ldl_p(mem_buf);
 
     switch (n) {
-        case S390_PSWM_REGNUM: env->psw.mask = tmpl; break;
-        case S390_PSWA_REGNUM: env->psw.addr = tmpl; break;
-        case S390_R0_REGNUM ... S390_R15_REGNUM:
-            env->regs[n-S390_R0_REGNUM] = tmpl; break;
-        case S390_A0_REGNUM ... S390_A15_REGNUM:
-            env->aregs[n-S390_A0_REGNUM] = tmp32; r=4; break;
-        case S390_FPC_REGNUM: env->fpc = tmp32; r=4; break;
-        case S390_F0_REGNUM ... S390_F15_REGNUM:
-            /* XXX */
-            break;
-        case S390_PC_REGNUM: env->psw.addr = tmpl; break;
-        case S390_CC_REGNUM: env->cc_op = tmp32; r=4; break;
+    case S390_PSWM_REGNUM:
+        env->psw.mask = tmpl;
+        env->cc_op = extract64(tmpl, 44, 2);
+        break;
+    case S390_PSWA_REGNUM:
+        env->psw.addr = tmpl;
+        break;
+    case S390_R0_REGNUM ... S390_R15_REGNUM:
+        env->regs[n-S390_R0_REGNUM] = tmpl;
+        break;
+    case S390_A0_REGNUM ... S390_A15_REGNUM:
+        env->aregs[n-S390_A0_REGNUM] = tmp32;
+        r = 4;
+        break;
+    case S390_FPC_REGNUM:
+        env->fpc = tmp32;
+        r = 4;
+        break;
+    case S390_F0_REGNUM ... S390_F15_REGNUM:
+        env->fregs[n-S390_F0_REGNUM].ll = tmpl;
+        break;
+    default:
+        return 0;
     }
-
     return r;
 }
 #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)
@@ -1696,6 +1721,10 @@ static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
         GET_REG32(env->uregs[reg->targno & 0xff]);
         break;
 
+    case 4: /*f*/
+        GET_REG32(float32_val(env->fregs[reg->targno & 0x0f]));
+        break;
+
     case 8: /*a*/
         GET_REG32(env->regs[reg->targno & 0x0f]);
         break;
@@ -1736,6 +1765,10 @@ static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
         env->uregs[reg->targno & 0xff] = tmp;
         break;
 
+    case 4: /*f*/
+        env->fregs[reg->targno & 0x0f] = make_float32(tmp);
+        break;
+
     case 8: /*a*/
         env->regs[reg->targno & 0x0f] = tmp;
         break;
@@ -1807,6 +1840,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;
+            CPUState *cpu = first_cpu;
 
             snprintf(target_xml, sizeof(target_xml),
                      "<?xml version=\"1.0\"?>"
@@ -1815,7 +1849,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 = cpu->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), "\"/>");
@@ -1833,14 +1867,15 @@ static const char *get_feature_xml(const char *p, const char **newp)
 }
 #endif
 
-static int gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int reg)
+static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg)
 {
+    CPUArchState *env = cpu->env_ptr;
     GDBRegisterState *r;
 
     if (reg < NUM_CORE_REGS)
         return cpu_gdb_read_register(env, mem_buf, reg);
 
-    for (r = env->gdb_regs; r; r = r->next) {
+    for (r = cpu->gdb_regs; r; r = r->next) {
         if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
             return r->get_reg(env, mem_buf, reg - r->base_reg);
         }
@@ -1848,14 +1883,15 @@ static int gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int reg)
     return 0;
 }
 
-static int gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int reg)
+static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
 {
+    CPUArchState *env = cpu->env_ptr;
     GDBRegisterState *r;
 
     if (reg < NUM_CORE_REGS)
         return cpu_gdb_write_register(env, mem_buf, reg);
 
-    for (r = env->gdb_regs; r; r = r->next) {
+    for (r = cpu->gdb_regs; r; r = r->next) {
         if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
             return r->set_reg(env, mem_buf, reg - r->base_reg);
         }
@@ -1870,15 +1906,15 @@ static int gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int reg)
    gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
  */
 
-void gdb_register_coprocessor(CPUArchState * env,
-                             gdb_reg_cb get_reg, gdb_reg_cb set_reg,
-                             int num_regs, const char *xml, int g_pos)
+void gdb_register_coprocessor(CPUState *cpu,
+                              gdb_reg_cb get_reg, gdb_reg_cb set_reg,
+                              int num_regs, const char *xml, int g_pos)
 {
     GDBRegisterState *s;
     GDBRegisterState **p;
     static int last_reg = NUM_CORE_REGS;
 
-    p = &env->gdb_regs;
+    p = &cpu->gdb_regs;
     while (*p) {
         /* Check for duplicates.  */
         if (strcmp((*p)->xml, xml) == 0)
@@ -1917,16 +1953,19 @@ 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;
 
-    if (kvm_enabled())
+    if (kvm_enabled()) {
         return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, 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;
@@ -1936,7 +1975,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)
@@ -1951,16 +1991,19 @@ 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;
 
-    if (kvm_enabled())
+    if (kvm_enabled()) {
         return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, 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;
@@ -1970,7 +2013,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;
@@ -1984,6 +2028,7 @@ 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()) {
@@ -1991,7 +2036,8 @@ static void gdb_breakpoint_remove_all(void)
         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);
@@ -2001,49 +2047,22 @@ static void gdb_breakpoint_remove_all(void)
 
 static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
 {
-    cpu_synchronize_state(s->c_cpu);
-#if defined(TARGET_I386)
-    s->c_cpu->eip = pc;
-#elif defined (TARGET_PPC)
-    s->c_cpu->nip = pc;
-#elif defined (TARGET_SPARC)
-    s->c_cpu->pc = pc;
-    s->c_cpu->npc = pc + 4;
-#elif defined (TARGET_ARM)
-    s->c_cpu->regs[15] = pc;
-#elif defined (TARGET_SH4)
-    s->c_cpu->pc = pc;
-#elif defined (TARGET_MIPS)
-    s->c_cpu->active_tc.PC = pc & ~(target_ulong)1;
-    if (pc & 1) {
-        s->c_cpu->hflags |= MIPS_HFLAG_M16;
-    } else {
-        s->c_cpu->hflags &= ~(MIPS_HFLAG_M16);
+    CPUState *cpu = s->c_cpu;
+    CPUClass *cc = CPU_GET_CLASS(cpu);
+
+    cpu_synchronize_state(cpu);
+    if (cc->set_pc) {
+        cc->set_pc(cpu, pc);
     }
-#elif defined (TARGET_MICROBLAZE)
-    s->c_cpu->sregs[SR_PC] = pc;
-#elif defined(TARGET_OPENRISC)
-    s->c_cpu->pc = pc;
-#elif defined (TARGET_CRIS)
-    s->c_cpu->pc = pc;
-#elif defined (TARGET_ALPHA)
-    s->c_cpu->pc = pc;
-#elif defined (TARGET_S390X)
-    s->c_cpu->psw.addr = pc;
-#elif defined (TARGET_LM32)
-    s->c_cpu->pc = pc;
-#elif defined(TARGET_XTENSA)
-    s->c_cpu->pc = pc;
-#endif
 }
 
-static CPUArchState *find_cpu(uint32_t thread_id)
+static CPUState *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;
         }
     }
 
@@ -2052,7 +2071,10 @@ static CPUArchState *find_cpu(uint32_t thread_id)
 
 static int gdb_handle_packet(GDBState *s, const char *line_buf)
 {
+#ifdef TARGET_XTENSA
     CPUArchState *env;
+#endif
+    CPUState *cpu;
     const char *p;
     uint32_t thread;
     int ch, reg_size, type, res;
@@ -2132,12 +2154,12 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             }
             if (res) {
                 if (res_thread != -1 && res_thread != 0) {
-                    env = find_cpu(res_thread);
-                    if (env == NULL) {
+                    cpu = find_cpu(res_thread);
+                    if (cpu == NULL) {
                         put_packet(s, "E22");
                         break;
                     }
-                    s->c_cpu = env;
+                    s->c_cpu = cpu;
                 }
                 if (res == 's') {
                     cpu_single_step(s->c_cpu, sstep_flags);
@@ -2199,7 +2221,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         break;
     case 'g':
         cpu_synchronize_state(s->g_cpu);
-        env = s->g_cpu;
+#ifdef TARGET_XTENSA
+        env = s->g_cpu->env_ptr;
+#endif
         len = 0;
         for (addr = 0; addr < num_g_regs; addr++) {
             reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
@@ -2210,7 +2234,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         break;
     case 'G':
         cpu_synchronize_state(s->g_cpu);
-        env = s->g_cpu;
+#ifdef TARGET_XTENSA
+        env = s->g_cpu->env_ptr;
+#endif
         registers = mem_buf;
         len = strlen(p) / 2;
         hextomem((uint8_t *)registers, p, len);
@@ -2226,7 +2252,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         if (*p == ',')
             p++;
         len = strtoull(p, NULL, 16);
-        if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 0) != 0) {
+        if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, false) != 0) {
             put_packet (s, "E14");
         } else {
             memtohex(buf, mem_buf, len);
@@ -2241,7 +2267,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         if (*p == ':')
             p++;
         hextomem(mem_buf, p, len);
-        if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 1) != 0) {
+        if (target_memory_rw_debug(s->g_cpu, addr, mem_buf, len,
+                                   true) != 0) {
             put_packet(s, "E14");
         } else {
             put_packet(s, "OK");
@@ -2300,18 +2327,18 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             put_packet(s, "OK");
             break;
         }
-        env = find_cpu(thread);
-        if (env == NULL) {
+        cpu = find_cpu(thread);
+        if (cpu == NULL) {
             put_packet(s, "E22");
             break;
         }
         switch (type) {
         case 'c':
-            s->c_cpu = env;
+            s->c_cpu = cpu;
             put_packet(s, "OK");
             break;
         case 'g':
-            s->g_cpu = env;
+            s->g_cpu = cpu;
             put_packet(s, "OK");
             break;
         default:
@@ -2321,9 +2348,9 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         break;
     case 'T':
         thread = strtoull(p, (char **)&p, 16);
-        env = find_cpu(thread);
+        cpu = find_cpu(thread);
 
-        if (env != NULL) {
+        if (cpu != NULL) {
             put_packet(s, "OK");
         } else {
             put_packet(s, "E22");
@@ -2373,12 +2400,12 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             break;
         } else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) {
             thread = strtoull(p+16, (char **)&p, 16);
-            env = find_cpu(thread);
-            if (env != NULL) {
-                cpu_synchronize_state(env);
+            cpu = find_cpu(thread);
+            if (cpu != NULL) {
+                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);
             }
@@ -2386,7 +2413,8 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         }
 #ifdef CONFIG_USER_ONLY
         else if (strncmp(p, "Offsets", 7) == 0) {
-            TaskState *ts = s->c_cpu->opaque;
+            CPUArchState *env = s->c_cpu->env_ptr;
+            TaskState *ts = env->opaque;
 
             snprintf(buf, sizeof(buf),
                      "Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx
@@ -2474,17 +2502,18 @@ 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)
 {
-    gdbserver_state->c_cpu = env;
-    gdbserver_state->g_cpu = env;
+    gdbserver_state->c_cpu = cpu;
+    gdbserver_state->g_cpu = cpu;
 }
 
 #ifndef CONFIG_USER_ONLY
 static void gdb_vm_state_change(void *opaque, int running, RunState state)
 {
     GDBState *s = gdbserver_state;
-    CPUArchState *env = s->c_cpu;
+    CPUArchState *env = s->c_cpu->env_ptr;
+    CPUState *cpu = s->c_cpu;
     char buf[256];
     const char *type;
     int ret;
@@ -2513,7 +2542,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;
@@ -2546,13 +2575,13 @@ 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);
 
     /* disable single step if it was enabled */
-    cpu_single_step(env, 0);
+    cpu_single_step(cpu, 0);
 }
 #endif
 
@@ -2743,66 +2772,67 @@ gdb_queuesig (void)
 }
 
 int
-gdb_handlesig (CPUArchState *env, int sig)
+gdb_handlesig(CPUState *cpu, int sig)
 {
-  GDBState *s;
-  char buf[256];
-  int n;
+    CPUArchState *env = cpu->env_ptr;
+    GDBState *s;
+    char buf[256];
+    int n;
 
-  s = gdbserver_state;
-  if (gdbserver_fd < 0 || s->fd < 0)
-    return sig;
+    s = gdbserver_state;
+    if (gdbserver_fd < 0 || s->fd < 0) {
+        return sig;
+    }
 
-  /* disable single step if it was enabled */
-  cpu_single_step(env, 0);
-  tb_flush(env);
+    /* disable single step if it was enabled */
+    cpu_single_step(cpu, 0);
+    tb_flush(env);
 
-  if (sig != 0)
-    {
-      snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb (sig));
-      put_packet(s, buf);
-    }
-  /* put_packet() might have detected that the peer terminated the 
-     connection.  */
-  if (s->fd < 0)
-      return sig;
-
-  sig = 0;
-  s->state = RS_IDLE;
-  s->running_state = 0;
-  while (s->running_state == 0) {
-      n = read (s->fd, buf, 256);
-      if (n > 0)
-        {
-          int i;
+    if (sig != 0) {
+        snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb(sig));
+        put_packet(s, buf);
+    }
+    /* put_packet() might have detected that the peer terminated the
+       connection.  */
+    if (s->fd < 0) {
+        return sig;
+    }
 
-          for (i = 0; i < n; i++)
-            gdb_read_byte (s, buf[i]);
-        }
-      else if (n == 0 || errno != EAGAIN)
-        {
-          /* XXX: Connection closed.  Should probably wait for another
-             connection before continuing.  */
-          return sig;
+    sig = 0;
+    s->state = RS_IDLE;
+    s->running_state = 0;
+    while (s->running_state == 0) {
+        n = read(s->fd, buf, 256);
+        if (n > 0) {
+            int i;
+
+            for (i = 0; i < n; i++) {
+                gdb_read_byte(s, buf[i]);
+            }
+        } else if (n == 0 || errno != EAGAIN) {
+            /* XXX: Connection closed.  Should probably wait for another
+               connection before continuing.  */
+            return sig;
         }
-  }
-  sig = s->signal;
-  s->signal = 0;
-  return sig;
+    }
+    sig = s->signal;
+    s->signal = 0;
+    return sig;
 }
 
 /* Tell the remote gdb that the process has exited due to SIG.  */
 void gdb_signalled(CPUArchState *env, int sig)
 {
-  GDBState *s;
-  char buf[4];
+    GDBState *s;
+    char buf[4];
 
-  s = gdbserver_state;
-  if (gdbserver_fd < 0 || s->fd < 0)
-    return;
+    s = gdbserver_state;
+    if (gdbserver_fd < 0 || s->fd < 0) {
+        return;
+    }
 
-  snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb (sig));
-  put_packet(s, buf);
+    snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb(sig));
+    put_packet(s, buf);
 }
 
 static void gdb_accept(void)
@@ -2810,7 +2840,7 @@ static void gdb_accept(void)
     GDBState *s;
     struct sockaddr_in sockaddr;
     socklen_t len;
-    int val, fd;
+    int fd;
 
     for(;;) {
         len = sizeof(sockaddr);
@@ -2827,8 +2857,7 @@ 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;
@@ -2857,7 +2886,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);
@@ -2994,6 +3023,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);
     }