]> git.proxmox.com Git - qemu.git/blobdiff - gdbstub.c
mips jazz: do not raise data bus exception when accessing invalid addresses
[qemu.git] / gdbstub.c
index c858b7f2b64b462a3395acaa58793dba26a0431a..e8ab0b2992581ff9cd058aab62654fc2a76ef3a4 100644 (file)
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -40,7 +40,6 @@
 #include "cpu.h"
 #include "qemu/sockets.h"
 #include "sysemu/kvm.h"
-#include "qemu/bitops.h"
 
 static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
                                          uint8_t *buf, int len, bool is_write)
@@ -316,10 +315,7 @@ static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER;
 
 static GDBState *gdbserver_state;
 
-/* This is an ugly hack to cope with both new and old gdb.
-   If gdb sends qXfer:features:read then assume we're talking to a newish
-   gdb that understands target descriptions.  */
-static int gdb_has_xml;
+bool gdb_has_xml;
 
 #ifdef CONFIG_USER_ONLY
 /* XXX: This is not thread safe.  Do we care?  */
@@ -372,9 +368,6 @@ static inline void gdb_continue(GDBState *s)
 #ifdef CONFIG_USER_ONLY
     s->running_state = 1;
 #else
-    if (runstate_check(RUN_STATE_GUEST_PANICKED)) {
-        runstate_set(RUN_STATE_DEBUG);
-    }
     if (!runstate_needs_reset()) {
         vm_start();
     }
@@ -489,1097 +482,6 @@ static int put_packet(GDBState *s, const char *buf)
     return put_packet_binary(s, buf, strlen(buf));
 }
 
-/* The GDB remote protocol transfers values in target byte order.  This means
-   we can use the raw memory access routines to access the value buffer.
-   Conveniently, these also handle the case where the buffer is mis-aligned.
- */
-#define GET_REG8(val) do { \
-    stb_p(mem_buf, val); \
-    return 1; \
-    } while(0)
-#define GET_REG16(val) do { \
-    stw_p(mem_buf, val); \
-    return 2; \
-    } while(0)
-#define GET_REG32(val) do { \
-    stl_p(mem_buf, val); \
-    return 4; \
-    } while(0)
-#define GET_REG64(val) do { \
-    stq_p(mem_buf, val); \
-    return 8; \
-    } while(0)
-
-#if TARGET_LONG_BITS == 64
-#define GET_REGL(val) GET_REG64(val)
-#define ldtul_p(addr) ldq_p(addr)
-#else
-#define GET_REGL(val) GET_REG32(val)
-#define ldtul_p(addr) ldl_p(addr)
-#endif
-
-#if defined(TARGET_I386)
-
-#include "target-i386/gdbstub.c"
-
-#elif defined (TARGET_PPC)
-
-#if defined (TARGET_PPC64)
-#define GDB_CORE_XML "power64-core.xml"
-#else
-#define GDB_CORE_XML "power-core.xml"
-#endif
-
-#include "target-ppc/gdbstub.c"
-
-#elif defined (TARGET_SPARC)
-
-#ifdef TARGET_ABI32
-#define GET_REGA(val) GET_REG32(val)
-#else
-#define GET_REGA(val) GET_REGL(val)
-#endif
-
-static int cpu_gdb_read_register(CPUSPARCState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 8) {
-        /* g0..g7 */
-        GET_REGA(env->gregs[n]);
-    }
-    if (n < 32) {
-        /* register window */
-        GET_REGA(env->regwptr[n - 8]);
-    }
-#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
-    if (n < 64) {
-        /* fprs */
-        if (n & 1) {
-            GET_REG32(env->fpr[(n - 32) / 2].l.lower);
-        } else {
-            GET_REG32(env->fpr[(n - 32) / 2].l.upper);
-        }
-    }
-    /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
-    switch (n) {
-    case 64:
-        GET_REGA(env->y);
-    case 65:
-        GET_REGA(cpu_get_psr(env));
-    case 66:
-        GET_REGA(env->wim);
-    case 67:
-        GET_REGA(env->tbr);
-    case 68:
-        GET_REGA(env->pc);
-    case 69:
-        GET_REGA(env->npc);
-    case 70:
-        GET_REGA(env->fsr);
-    case 71:
-        GET_REGA(0); /* csr */
-    default:
-        GET_REGA(0);
-    }
-#else
-    if (n < 64) {
-        /* f0-f31 */
-        if (n & 1) {
-            GET_REG32(env->fpr[(n - 32) / 2].l.lower);
-        } else {
-            GET_REG32(env->fpr[(n - 32) / 2].l.upper);
-        }
-    }
-    if (n < 80) {
-        /* f32-f62 (double width, even numbers only) */
-        GET_REG64(env->fpr[(n - 32) / 2].ll);
-    }
-    switch (n) {
-    case 80:
-        GET_REGL(env->pc);
-    case 81:
-        GET_REGL(env->npc);
-    case 82:
-        GET_REGL((cpu_get_ccr(env) << 32) |
-                 ((env->asi & 0xff) << 24) |
-                 ((env->pstate & 0xfff) << 8) |
-                 cpu_get_cwp64(env));
-    case 83:
-        GET_REGL(env->fsr);
-    case 84:
-        GET_REGL(env->fprs);
-    case 85:
-        GET_REGL(env->y);
-    }
-#endif
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUSPARCState *env, uint8_t *mem_buf, int n)
-{
-#if defined(TARGET_ABI32)
-    abi_ulong tmp;
-
-    tmp = ldl_p(mem_buf);
-#else
-    target_ulong tmp;
-
-    tmp = ldtul_p(mem_buf);
-#endif
-
-    if (n < 8) {
-        /* g0..g7 */
-        env->gregs[n] = tmp;
-    } else if (n < 32) {
-        /* register window */
-        env->regwptr[n - 8] = tmp;
-    }
-#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
-    else if (n < 64) {
-        /* fprs */
-        /* f0-f31 */
-        if (n & 1) {
-            env->fpr[(n - 32) / 2].l.lower = tmp;
-        } else {
-            env->fpr[(n - 32) / 2].l.upper = tmp;
-        }
-    } else {
-        /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
-        switch (n) {
-        case 64:
-            env->y = tmp;
-            break;
-        case 65:
-            cpu_put_psr(env, tmp);
-            break;
-        case 66:
-            env->wim = tmp;
-            break;
-        case 67:
-            env->tbr = tmp;
-            break;
-        case 68:
-            env->pc = tmp;
-            break;
-        case 69:
-            env->npc = tmp;
-            break;
-        case 70:
-            env->fsr = tmp;
-            break;
-        default:
-            return 0;
-        }
-    }
-    return 4;
-#else
-    else if (n < 64) {
-        /* f0-f31 */
-        tmp = ldl_p(mem_buf);
-        if (n & 1) {
-            env->fpr[(n - 32) / 2].l.lower = tmp;
-        } else {
-            env->fpr[(n - 32) / 2].l.upper = tmp;
-        }
-        return 4;
-    } else if (n < 80) {
-        /* f32-f62 (double width, even numbers only) */
-        env->fpr[(n - 32) / 2].ll = tmp;
-    } else {
-        switch (n) {
-        case 80:
-            env->pc = tmp;
-            break;
-        case 81:
-            env->npc = tmp;
-            break;
-        case 82:
-            cpu_put_ccr(env, tmp >> 32);
-            env->asi = (tmp >> 24) & 0xff;
-            env->pstate = (tmp >> 8) & 0xfff;
-            cpu_put_cwp64(env, tmp & 0xff);
-            break;
-        case 83:
-            env->fsr = tmp;
-            break;
-        case 84:
-            env->fprs = tmp;
-            break;
-        case 85:
-            env->y = tmp;
-            break;
-        default:
-            return 0;
-        }
-    }
-    return 8;
-#endif
-}
-#elif defined (TARGET_ARM)
-
-/* Old gdb always expect FPA registers.  Newer (xml-aware) gdb only expect
-   whatever the target description contains.  Due to a historical mishap
-   the FPA registers appear in between core integer regs and the CPSR.
-   We hack round this by giving the FPA regs zero size when talking to a
-   newer gdb.  */
-#define GDB_CORE_XML "arm-core.xml"
-
-static int cpu_gdb_read_register(CPUARMState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 16) {
-        /* Core integer register.  */
-        GET_REG32(env->regs[n]);
-    }
-    if (n < 24) {
-        /* FPA registers.  */
-        if (gdb_has_xml) {
-            return 0;
-        }
-        memset(mem_buf, 0, 12);
-        return 12;
-    }
-    switch (n) {
-    case 24:
-        /* FPA status register.  */
-        if (gdb_has_xml) {
-            return 0;
-        }
-        GET_REG32(0);
-    case 25:
-        /* CPSR */
-        GET_REG32(cpsr_read(env));
-    }
-    /* Unknown register.  */
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUARMState *env, uint8_t *mem_buf, int n)
-{
-    uint32_t tmp;
-
-    tmp = ldl_p(mem_buf);
-
-    /* Mask out low bit of PC to workaround gdb bugs.  This will probably
-       cause problems if we ever implement the Jazelle DBX extensions.  */
-    if (n == 15) {
-        tmp &= ~1;
-    }
-
-    if (n < 16) {
-        /* Core integer register.  */
-        env->regs[n] = tmp;
-        return 4;
-    }
-    if (n < 24) { /* 16-23 */
-        /* FPA registers (ignored).  */
-        if (gdb_has_xml) {
-            return 0;
-        }
-        return 12;
-    }
-    switch (n) {
-    case 24:
-        /* FPA status register (ignored).  */
-        if (gdb_has_xml) {
-            return 0;
-        }
-        return 4;
-    case 25:
-        /* CPSR */
-        cpsr_write(env, tmp, 0xffffffff);
-        return 4;
-    }
-    /* Unknown register.  */
-    return 0;
-}
-
-#elif defined (TARGET_M68K)
-
-#define GDB_CORE_XML "cf-core.xml"
-
-static int cpu_gdb_read_register(CPUM68KState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 8) {
-        /* D0-D7 */
-        GET_REG32(env->dregs[n]);
-    } else if (n < 16) {
-        /* A0-A7 */
-        GET_REG32(env->aregs[n - 8]);
-    } else {
-        switch (n) {
-        case 16:
-            GET_REG32(env->sr);
-        case 17:
-            GET_REG32(env->pc);
-        }
-    }
-    /* FP registers not included here because they vary between
-       ColdFire and m68k.  Use XML bits for these.  */
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUM68KState *env, uint8_t *mem_buf, int n)
-{
-    uint32_t tmp;
-
-    tmp = ldl_p(mem_buf);
-
-    if (n < 8) {
-        /* D0-D7 */
-        env->dregs[n] = tmp;
-    } else if (n < 16) {
-        /* A0-A7 */
-        env->aregs[n - 8] = tmp;
-    } else {
-        switch (n) {
-        case 16:
-            env->sr = tmp;
-            break;
-        case 17:
-            env->pc = tmp;
-            break;
-        default:
-            return 0;
-        }
-    }
-    return 4;
-}
-#elif defined (TARGET_MIPS)
-
-static int cpu_gdb_read_register(CPUMIPSState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-        GET_REGL(env->active_tc.gpr[n]);
-    }
-    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
-        if (n >= 38 && n < 70) {
-            if (env->CP0_Status & (1 << CP0St_FR)) {
-                GET_REGL(env->active_fpu.fpr[n - 38].d);
-            } else {
-                GET_REGL(env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX]);
-            }
-        }
-        switch (n) {
-        case 70:
-            GET_REGL((int32_t)env->active_fpu.fcr31);
-        case 71:
-            GET_REGL((int32_t)env->active_fpu.fcr0);
-        }
-    }
-    switch (n) {
-    case 32:
-        GET_REGL((int32_t)env->CP0_Status);
-    case 33:
-        GET_REGL(env->active_tc.LO[0]);
-    case 34:
-        GET_REGL(env->active_tc.HI[0]);
-    case 35:
-        GET_REGL(env->CP0_BadVAddr);
-    case 36:
-        GET_REGL((int32_t)env->CP0_Cause);
-    case 37:
-        GET_REGL(env->active_tc.PC | !!(env->hflags & MIPS_HFLAG_M16));
-    case 72:
-        GET_REGL(0); /* fp */
-    case 89:
-        GET_REGL((int32_t)env->CP0_PRid);
-    }
-    if (n >= 73 && n <= 88) {
-        /* 16 embedded regs.  */
-        GET_REGL(0);
-    }
-
-    return 0;
-}
-
-/* convert MIPS rounding mode in FCR31 to IEEE library */
-static unsigned int ieee_rm[] = {
-    float_round_nearest_even,
-    float_round_to_zero,
-    float_round_up,
-    float_round_down
-};
-#define RESTORE_ROUNDING_MODE \
-    set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], \
-                            &env->active_fpu.fp_status)
-
-static int cpu_gdb_write_register(CPUMIPSState *env, uint8_t *mem_buf, int n)
-{
-    target_ulong tmp;
-
-    tmp = ldtul_p(mem_buf);
-
-    if (n < 32) {
-        env->active_tc.gpr[n] = tmp;
-        return sizeof(target_ulong);
-    }
-    if (env->CP0_Config1 & (1 << CP0C1_FP)
-            && n >= 38 && n < 73) {
-        if (n < 70) {
-            if (env->CP0_Status & (1 << CP0St_FR)) {
-                env->active_fpu.fpr[n - 38].d = tmp;
-            } else {
-                env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX] = tmp;
-            }
-        }
-        switch (n) {
-        case 70:
-            env->active_fpu.fcr31 = tmp & 0xFF83FFFF;
-            /* set rounding mode */
-            RESTORE_ROUNDING_MODE;
-            break;
-        case 71:
-            env->active_fpu.fcr0 = tmp;
-            break;
-        }
-        return sizeof(target_ulong);
-    }
-    switch (n) {
-    case 32:
-        env->CP0_Status = tmp;
-        break;
-    case 33:
-        env->active_tc.LO[0] = tmp;
-        break;
-    case 34:
-        env->active_tc.HI[0] = tmp;
-        break;
-    case 35:
-        env->CP0_BadVAddr = tmp;
-        break;
-    case 36:
-        env->CP0_Cause = tmp;
-        break;
-    case 37:
-        env->active_tc.PC = tmp & ~(target_ulong)1;
-        if (tmp & 1) {
-            env->hflags |= MIPS_HFLAG_M16;
-        } else {
-            env->hflags &= ~(MIPS_HFLAG_M16);
-        }
-        break;
-    case 72: /* fp, ignored */
-        break;
-    default:
-        if (n > 89) {
-            return 0;
-        }
-        /* Other registers are readonly.  Ignore writes.  */
-        break;
-    }
-
-    return sizeof(target_ulong);
-}
-#elif defined(TARGET_OPENRISC)
-
-static int cpu_gdb_read_register(CPUOpenRISCState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-        GET_REG32(env->gpr[n]);
-    } else {
-        switch (n) {
-        case 32:    /* PPC */
-            GET_REG32(env->ppc);
-
-        case 33:    /* NPC */
-            GET_REG32(env->npc);
-
-        case 34:    /* SR */
-            GET_REG32(env->sr);
-
-        default:
-            break;
-        }
-    }
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUOpenRISCState *env,
-                                  uint8_t *mem_buf, int n)
-{
-    OpenRISCCPU *cpu = openrisc_env_get_cpu(env);
-    CPUClass *cc = CPU_GET_CLASS(cpu);
-    uint32_t tmp;
-
-    if (n > cc->gdb_num_core_regs) {
-        return 0;
-    }
-
-    tmp = ldl_p(mem_buf);
-
-    if (n < 32) {
-        env->gpr[n] = tmp;
-    } else {
-        switch (n) {
-        case 32: /* PPC */
-            env->ppc = tmp;
-            break;
-
-        case 33: /* NPC */
-            env->npc = tmp;
-            break;
-
-        case 34: /* SR */
-            env->sr = tmp;
-            break;
-
-        default:
-            break;
-        }
-    }
-    return 4;
-}
-#elif defined (TARGET_SH4)
-
-/* Hint: Use "set architecture sh4" in GDB to see fpu registers */
-/* FIXME: We should use XML for this.  */
-
-static int cpu_gdb_read_register(CPUSH4State *env, uint8_t *mem_buf, int n)
-{
-    switch (n) {
-    case 0 ... 7:
-        if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
-            GET_REGL(env->gregs[n + 16]);
-        } else {
-            GET_REGL(env->gregs[n]);
-        }
-    case 8 ... 15:
-        GET_REGL(env->gregs[n]);
-    case 16:
-        GET_REGL(env->pc);
-    case 17:
-        GET_REGL(env->pr);
-    case 18:
-        GET_REGL(env->gbr);
-    case 19:
-        GET_REGL(env->vbr);
-    case 20:
-        GET_REGL(env->mach);
-    case 21:
-        GET_REGL(env->macl);
-    case 22:
-        GET_REGL(env->sr);
-    case 23:
-        GET_REGL(env->fpul);
-    case 24:
-        GET_REGL(env->fpscr);
-    case 25 ... 40:
-        if (env->fpscr & FPSCR_FR) {
-            stfl_p(mem_buf, env->fregs[n - 9]);
-        } else {
-            stfl_p(mem_buf, env->fregs[n - 25]);
-        }
-        return 4;
-    case 41:
-        GET_REGL(env->ssr);
-    case 42:
-        GET_REGL(env->spc);
-    case 43 ... 50:
-        GET_REGL(env->gregs[n - 43]);
-    case 51 ... 58:
-        GET_REGL(env->gregs[n - (51 - 16)]);
-    }
-
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUSH4State *env, uint8_t *mem_buf, int n)
-{
-    switch (n) {
-    case 0 ... 7:
-        if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
-            env->gregs[n + 16] = ldl_p(mem_buf);
-        } else {
-            env->gregs[n] = ldl_p(mem_buf);
-        }
-        break;
-    case 8 ... 15:
-        env->gregs[n] = ldl_p(mem_buf);
-        break;
-    case 16:
-        env->pc = ldl_p(mem_buf);
-        break;
-    case 17:
-        env->pr = ldl_p(mem_buf);
-        break;
-    case 18:
-        env->gbr = ldl_p(mem_buf);
-        break;
-    case 19:
-        env->vbr = ldl_p(mem_buf);
-        break;
-    case 20:
-        env->mach = ldl_p(mem_buf);
-        break;
-    case 21:
-        env->macl = ldl_p(mem_buf);
-        break;
-    case 22:
-        env->sr = ldl_p(mem_buf);
-        break;
-    case 23:
-        env->fpul = ldl_p(mem_buf);
-        break;
-    case 24:
-        env->fpscr = ldl_p(mem_buf);
-        break;
-    case 25 ... 40:
-        if (env->fpscr & FPSCR_FR) {
-            env->fregs[n - 9] = ldfl_p(mem_buf);
-        } else {
-            env->fregs[n - 25] = ldfl_p(mem_buf);
-        }
-        break;
-    case 41:
-        env->ssr = ldl_p(mem_buf);
-        break;
-    case 42:
-        env->spc = ldl_p(mem_buf);
-        break;
-    case 43 ... 50:
-        env->gregs[n - 43] = ldl_p(mem_buf);
-        break;
-    case 51 ... 58:
-        env->gregs[n - (51 - 16)] = ldl_p(mem_buf);
-        break;
-    default:
-        return 0;
-    }
-
-    return 4;
-}
-#elif defined (TARGET_MICROBLAZE)
-
-static int cpu_gdb_read_register(CPUMBState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-        GET_REG32(env->regs[n]);
-    } else {
-        GET_REG32(env->sregs[n - 32]);
-    }
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUMBState *env, uint8_t *mem_buf, int n)
-{
-    MicroBlazeCPU *cpu = mb_env_get_cpu(env);
-    CPUClass *cc = CPU_GET_CLASS(cpu);
-    uint32_t tmp;
-
-    if (n > cc->gdb_num_core_regs) {
-        return 0;
-    }
-
-    tmp = ldl_p(mem_buf);
-
-    if (n < 32) {
-        env->regs[n] = tmp;
-    } else {
-        env->sregs[n - 32] = tmp;
-    }
-    return 4;
-}
-#elif defined (TARGET_CRIS)
-
-static int
-read_register_crisv10(CPUCRISState *env, uint8_t *mem_buf, int n)
-{
-    if (n < 15) {
-        GET_REG32(env->regs[n]);
-    }
-
-    if (n == 15) {
-        GET_REG32(env->pc);
-    }
-
-    if (n < 32) {
-        switch (n) {
-        case 16:
-            GET_REG8(env->pregs[n - 16]);
-        case 17:
-            GET_REG8(env->pregs[n - 16]);
-        case 20:
-        case 21:
-            GET_REG16(env->pregs[n - 16]);
-        default:
-            if (n >= 23) {
-                GET_REG32(env->pregs[n - 16]);
-            }
-            break;
-        }
-    }
-    return 0;
-}
-
-static int cpu_gdb_read_register(CPUCRISState *env, uint8_t *mem_buf, int n)
-{
-    uint8_t srs;
-
-    if (env->pregs[PR_VR] < 32) {
-        return read_register_crisv10(env, mem_buf, n);
-    }
-
-    srs = env->pregs[PR_SRS];
-    if (n < 16) {
-        GET_REG32(env->regs[n]);
-    }
-
-    if (n >= 21 && n < 32) {
-        GET_REG32(env->pregs[n - 16]);
-    }
-    if (n >= 33 && n < 49) {
-        GET_REG32(env->sregs[srs][n - 33]);
-    }
-    switch (n) {
-    case 16:
-        GET_REG8(env->pregs[0]);
-    case 17:
-        GET_REG8(env->pregs[1]);
-    case 18:
-        GET_REG32(env->pregs[2]);
-    case 19:
-        GET_REG8(srs);
-    case 20:
-        GET_REG16(env->pregs[4]);
-    case 32:
-        GET_REG32(env->pc);
-    }
-
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUCRISState *env, uint8_t *mem_buf, int n)
-{
-    uint32_t tmp;
-
-    if (n > 49) {
-        return 0;
-    }
-
-    tmp = ldl_p(mem_buf);
-
-    if (n < 16) {
-        env->regs[n] = tmp;
-    }
-
-    if (n >= 21 && n < 32) {
-        env->pregs[n - 16] = tmp;
-    }
-
-    /* FIXME: Should support function regs be writable?  */
-    switch (n) {
-    case 16:
-        return 1;
-    case 17:
-        return 1;
-    case 18:
-        env->pregs[PR_PID] = tmp;
-        break;
-    case 19:
-        return 1;
-    case 20:
-        return 2;
-    case 32:
-        env->pc = tmp;
-        break;
-    }
-
-    return 4;
-}
-#elif defined (TARGET_ALPHA)
-
-static int cpu_gdb_read_register(CPUAlphaState *env, uint8_t *mem_buf, int n)
-{
-    uint64_t val;
-    CPU_DoubleU d;
-
-    switch (n) {
-    case 0 ... 30:
-        val = env->ir[n];
-        break;
-    case 32 ... 62:
-        d.d = env->fir[n - 32];
-        val = d.ll;
-        break;
-    case 63:
-        val = cpu_alpha_load_fpcr(env);
-        break;
-    case 64:
-        val = env->pc;
-        break;
-    case 66:
-        val = env->unique;
-        break;
-    case 31:
-    case 65:
-        /* 31 really is the zero register; 65 is unassigned in the
-           gdb protocol, but is still required to occupy 8 bytes. */
-        val = 0;
-        break;
-    default:
-        return 0;
-    }
-    GET_REGL(val);
-}
-
-static int cpu_gdb_write_register(CPUAlphaState *env, uint8_t *mem_buf, int n)
-{
-    target_ulong tmp = ldtul_p(mem_buf);
-    CPU_DoubleU d;
-
-    switch (n) {
-    case 0 ... 30:
-        env->ir[n] = tmp;
-        break;
-    case 32 ... 62:
-        d.ll = tmp;
-        env->fir[n - 32] = d.d;
-        break;
-    case 63:
-        cpu_alpha_store_fpcr(env, tmp);
-        break;
-    case 64:
-        env->pc = tmp;
-        break;
-    case 66:
-        env->unique = tmp;
-        break;
-    case 31:
-    case 65:
-        /* 31 really is the zero register; 65 is unassigned in the
-           gdb protocol, but is still required to occupy 8 bytes. */
-        break;
-    default:
-        return 0;
-    }
-    return 8;
-}
-#elif defined (TARGET_S390X)
-
-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:
-        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);
-    case S390_PSWA_REGNUM:
-        GET_REGL(env->psw.addr);
-    case S390_R0_REGNUM ... S390_R15_REGNUM:
-        GET_REGL(env->regs[n-S390_R0_REGNUM]);
-    case S390_A0_REGNUM ... S390_A15_REGNUM:
-        GET_REG32(env->aregs[n-S390_A0_REGNUM]);
-    case S390_FPC_REGNUM:
-        GET_REG32(env->fpc);
-    case S390_F0_REGNUM ... S390_F15_REGNUM:
-        GET_REG64(env->fregs[n-S390_F0_REGNUM].ll);
-    }
-
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUS390XState *env, uint8_t *mem_buf, int n)
-{
-    target_ulong tmpl;
-    uint32_t tmp32;
-    int r = 8;
-    tmpl = ldtul_p(mem_buf);
-    tmp32 = ldl_p(mem_buf);
-
-    switch (n) {
-    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/lm32_pic.h"
-
-static int cpu_gdb_read_register(CPULM32State *env, uint8_t *mem_buf, int n)
-{
-    if (n < 32) {
-        GET_REG32(env->regs[n]);
-    } else {
-        switch (n) {
-        case 32:
-            GET_REG32(env->pc);
-        /* FIXME: put in right exception ID */
-        case 33:
-            GET_REG32(0);
-        case 34:
-            GET_REG32(env->eba);
-        case 35:
-            GET_REG32(env->deba);
-        case 36:
-            GET_REG32(env->ie);
-        case 37:
-            GET_REG32(lm32_pic_get_im(env->pic_state));
-        case 38:
-            GET_REG32(lm32_pic_get_ip(env->pic_state));
-        }
-    }
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPULM32State *env, uint8_t *mem_buf, int n)
-{
-    LM32CPU *cpu = lm32_env_get_cpu(env);
-    CPUClass *cc = CPU_GET_CLASS(cpu);
-    uint32_t tmp;
-
-    if (n > cc->gdb_num_core_regs) {
-        return 0;
-    }
-
-    tmp = ldl_p(mem_buf);
-
-    if (n < 32) {
-        env->regs[n] = tmp;
-    } else {
-        switch (n) {
-        case 32:
-            env->pc = tmp;
-            break;
-        case 34:
-            env->eba = tmp;
-            break;
-        case 35:
-            env->deba = tmp;
-            break;
-        case 36:
-            env->ie = tmp;
-            break;
-        case 37:
-            lm32_pic_set_im(env->pic_state, tmp);
-            break;
-        case 38:
-            lm32_pic_set_ip(env->pic_state, tmp);
-            break;
-        }
-    }
-    return 4;
-}
-#elif defined(TARGET_XTENSA)
-
-static int cpu_gdb_read_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
-{
-    const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
-
-    if (n < 0 || n >= env->config->gdb_regmap.num_regs) {
-        return 0;
-    }
-
-    switch (reg->type) {
-    case 9: /*pc*/
-        GET_REG32(env->pc);
-
-    case 1: /*ar*/
-        xtensa_sync_phys_from_window(env);
-        GET_REG32(env->phys_regs[(reg->targno & 0xff) % env->config->nareg]);
-
-    case 2: /*SR*/
-        GET_REG32(env->sregs[reg->targno & 0xff]);
-
-    case 3: /*UR*/
-        GET_REG32(env->uregs[reg->targno & 0xff]);
-
-    case 4: /*f*/
-        GET_REG32(float32_val(env->fregs[reg->targno & 0x0f]));
-
-    case 8: /*a*/
-        GET_REG32(env->regs[reg->targno & 0x0f]);
-
-    default:
-        qemu_log("%s from reg %d of unsupported type %d\n",
-                 __func__, n, reg->type);
-        return 0;
-    }
-}
-
-static int cpu_gdb_write_register(CPUXtensaState *env, uint8_t *mem_buf, int n)
-{
-    uint32_t tmp;
-    const XtensaGdbReg *reg = env->config->gdb_regmap.reg + n;
-
-    if (n < 0 || n >= env->config->gdb_regmap.num_regs) {
-        return 0;
-    }
-
-    tmp = ldl_p(mem_buf);
-
-    switch (reg->type) {
-    case 9: /*pc*/
-        env->pc = tmp;
-        break;
-
-    case 1: /*ar*/
-        env->phys_regs[(reg->targno & 0xff) % env->config->nareg] = tmp;
-        xtensa_sync_window_from_phys(env);
-        break;
-
-    case 2: /*SR*/
-        env->sregs[reg->targno & 0xff] = tmp;
-        break;
-
-    case 3: /*UR*/
-        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;
-
-    default:
-        qemu_log("%s to reg %d of unsupported type %d\n",
-                 __func__, n, reg->type);
-        return 0;
-    }
-
-    return 4;
-}
-#else
-
-static int cpu_gdb_read_register(CPUArchState *env, uint8_t *mem_buf, int n)
-{
-    return 0;
-}
-
-static int cpu_gdb_write_register(CPUArchState *env, uint8_t *mem_buf, int n)
-{
-    return 0;
-}
-
-#endif
-
-#ifdef GDB_CORE_XML
 /* Encode data using the encoding for 'x' packets.  */
 static int memtox(char *buf, const char *mem, int len)
 {
@@ -1601,7 +503,8 @@ static int memtox(char *buf, const char *mem, int len)
     return p - buf;
 }
 
-static const char *get_feature_xml(const char *p, const char **newp)
+static const char *get_feature_xml(const char *p, const char **newp,
+                                   CPUClass *cc)
 {
     size_t len;
     int i;
@@ -1625,7 +528,7 @@ static const char *get_feature_xml(const char *p, const char **newp)
                      "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
                      "<target>"
                      "<xi:include href=\"%s\"/>",
-                     GDB_CORE_XML);
+                     cc->gdb_core_xml_file);
 
             for (r = cpu->gdb_regs; r; r = r->next) {
                 pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
@@ -1643,7 +546,6 @@ static const char *get_feature_xml(const char *p, const char **newp)
     }
     return name ? xml_builtin[i][1] : NULL;
 }
-#endif
 
 static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg)
 {
@@ -1652,7 +554,7 @@ static int gdb_read_register(CPUState *cpu, uint8_t *mem_buf, int reg)
     GDBRegisterState *r;
 
     if (reg < cc->gdb_num_core_regs) {
-        return cpu_gdb_read_register(env, mem_buf, reg);
+        return cc->gdb_read_register(cpu, mem_buf, reg);
     }
 
     for (r = cpu->gdb_regs; r; r = r->next) {
@@ -1670,7 +572,7 @@ static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg)
     GDBRegisterState *r;
 
     if (reg < cc->gdb_num_core_regs) {
-        return cpu_gdb_write_register(env, mem_buf, reg);
+        return cc->gdb_write_register(cpu, mem_buf, reg);
     }
 
     for (r = cpu->gdb_regs; r; r = r->next) {
@@ -1716,6 +618,8 @@ void gdb_register_coprocessor(CPUState *cpu,
         if (g_pos != s->base_reg) {
             fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n"
                     "Expected %d got %d\n", xml, g_pos, s->base_reg);
+        } else {
+            cpu->gdb_num_g_regs = cpu->gdb_num_regs;
         }
     }
 }
@@ -1741,7 +645,7 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
     switch (type) {
     case GDB_BREAKPOINT_SW:
     case GDB_BREAKPOINT_HW:
-        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPU_FOREACH(cpu) {
             env = cpu->env_ptr;
             err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
             if (err)
@@ -1752,7 +656,7 @@ 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 (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPU_FOREACH(cpu) {
             env = cpu->env_ptr;
             err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
                                         NULL);
@@ -1779,7 +683,7 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
     switch (type) {
     case GDB_BREAKPOINT_SW:
     case GDB_BREAKPOINT_HW:
-        for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPU_FOREACH(cpu) {
             env = cpu->env_ptr;
             err = cpu_breakpoint_remove(env, addr, BP_GDB);
             if (err)
@@ -1790,7 +694,7 @@ 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 (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+        CPU_FOREACH(cpu) {
             env = cpu->env_ptr;
             err = cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
             if (err)
@@ -1813,7 +717,7 @@ static void gdb_breakpoint_remove_all(void)
         return;
     }
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         env = cpu->env_ptr;
         cpu_breakpoint_remove_all(env, BP_GDB);
 #ifndef CONFIG_USER_ONLY
@@ -1837,7 +741,7 @@ static CPUState *find_cpu(uint32_t thread_id)
 {
     CPUState *cpu;
 
-    for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) {
+    CPU_FOREACH(cpu) {
         if (cpu_index(cpu) == thread_id) {
             return cpu;
         }
@@ -1849,6 +753,7 @@ static CPUState *find_cpu(uint32_t thread_id)
 static int gdb_handle_packet(GDBState *s, const char *line_buf)
 {
     CPUState *cpu;
+    CPUClass *cc;
     const char *p;
     uint32_t thread;
     int ch, reg_size, type, res;
@@ -1996,7 +901,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
     case 'g':
         cpu_synchronize_state(s->g_cpu);
         len = 0;
-        for (addr = 0; addr < s->g_cpu->gdb_num_regs; addr++) {
+        for (addr = 0; addr < s->g_cpu->gdb_num_g_regs; addr++) {
             reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
             len += reg_size;
         }
@@ -2008,7 +913,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
         registers = mem_buf;
         len = strlen(p) / 2;
         hextomem((uint8_t *)registers, p, len);
-        for (addr = 0; addr < s->g_cpu->gdb_num_regs && len > 0; addr++) {
+        for (addr = 0; addr < s->g_cpu->gdb_num_g_regs && len > 0; addr++) {
             reg_size = gdb_write_register(s->g_cpu, registers, addr);
             len -= reg_size;
             registers += reg_size;
@@ -2162,7 +1067,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             if (s->query_cpu) {
                 snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu));
                 put_packet(s, buf);
-                s->query_cpu = s->query_cpu->next_cpu;
+                s->query_cpu = CPU_NEXT(s->query_cpu);
             } else
                 put_packet(s, "l");
             break;
@@ -2211,20 +1116,25 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
 #endif /* !CONFIG_USER_ONLY */
         if (strncmp(p, "Supported", 9) == 0) {
             snprintf(buf, sizeof(buf), "PacketSize=%x", MAX_PACKET_LENGTH);
-#ifdef GDB_CORE_XML
-            pstrcat(buf, sizeof(buf), ";qXfer:features:read+");
-#endif
+            cc = CPU_GET_CLASS(first_cpu);
+            if (cc->gdb_core_xml_file != NULL) {
+                pstrcat(buf, sizeof(buf), ";qXfer:features:read+");
+            }
             put_packet(s, buf);
             break;
         }
-#ifdef GDB_CORE_XML
         if (strncmp(p, "Xfer:features:read:", 19) == 0) {
             const char *xml;
             target_ulong total_len;
 
-            gdb_has_xml = 1;
+            cc = CPU_GET_CLASS(first_cpu);
+            if (cc->gdb_core_xml_file == NULL) {
+                goto unknown_command;
+            }
+
+            gdb_has_xml = true;
             p += 19;
-            xml = get_feature_xml(p, &p);
+            xml = get_feature_xml(p, &p, cc);
             if (!xml) {
                 snprintf(buf, sizeof(buf), "E00");
                 put_packet(s, buf);
@@ -2256,7 +1166,6 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
             put_packet_binary(s, buf, len + 1);
             break;
         }
-#endif
         /* Unrecognised 'q' command.  */
         goto unknown_command;
 
@@ -2631,7 +1540,7 @@ static void gdb_accept(void)
     s->c_cpu = first_cpu;
     s->g_cpu = first_cpu;
     s->fd = fd;
-    gdb_has_xml = 0;
+    gdb_has_xml = false;
 
     gdbserver_state = s;
 
@@ -2641,7 +1550,7 @@ static void gdb_accept(void)
 static int gdbserver_open(int port)
 {
     struct sockaddr_in sockaddr;
-    int fd, val, ret;
+    int fd, ret;
 
     fd = socket(PF_INET, SOCK_STREAM, 0);
     if (fd < 0) {
@@ -2652,9 +1561,7 @@ static int gdbserver_open(int port)
     fcntl(fd, F_SETFD, FD_CLOEXEC);
 #endif
 
-    /* allow fast reuse */
-    val = 1;
-    qemu_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
+    socket_set_fast_reuse(fd);
 
     sockaddr.sin_family = AF_INET;
     sockaddr.sin_port = htons(port);
@@ -2717,7 +1624,7 @@ static void gdb_chr_event(void *opaque, int event)
     switch (event) {
     case CHR_EVENT_OPENED:
         vm_stop(RUN_STATE_PAUSED);
-        gdb_has_xml = 0;
+        gdb_has_xml = false;
         break;
     default:
         break;