PPC: Add support for Apple gdb in gdbstub
authorAlexander Graf <agraf@suse.de>
Mon, 23 Jun 2014 13:23:08 +0000 (15:23 +0200)
committerAlexander Graf <agraf@suse.de>
Fri, 27 Jun 2014 11:48:22 +0000 (13:48 +0200)
The Apple gdbstub protocol is different from the normal gdbstub protocol
used on PowerPC. Add support for the different variant, so that we can use
Apple's gdb to debug guest code.

Keep in mind that the switch is a compile time option. We can't detect
during runtime whether a gdb connecting to us is an upstream gdb or an
Apple gdb.

Signed-off-by: Alexander Graf <agraf@suse.de>
target-ppc/cpu-qom.h
target-ppc/gdbstub.c
target-ppc/translate_init.c

index 13c70312652db5a61e691707fa180dd299d6993a..f1f0a52998a9dccbe35b319410e8fcedbafe85fb 100644 (file)
@@ -119,7 +119,9 @@ void ppc_cpu_dump_statistics(CPUState *cpu, FILE *f,
                              fprintf_function cpu_fprintf, int flags);
 hwaddr ppc_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
 int ppc_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
+int ppc_cpu_gdb_read_register_apple(CPUState *cpu, uint8_t *buf, int reg);
 int ppc_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+int ppc_cpu_gdb_write_register_apple(CPUState *cpu, uint8_t *buf, int reg);
 int ppc64_cpu_write_elf64_qemunote(WriteCoreDumpFunction f,
                                    CPUState *cpu, void *opaque);
 int ppc64_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cs,
index 381a3c7e315d1dffb2ad3574385ac6b51051b1c1..694d303e199df43977107d87b5b060c1bd6f3e94 100644 (file)
 #include "qemu-common.h"
 #include "exec/gdbstub.h"
 
+static int ppc_gdb_register_len_apple(int n)
+{
+    switch (n) {
+    case 0 ... 31:
+        /* gprs */
+        return 8;
+    case 32 ... 63:
+        /* fprs */
+        return 8;
+    case 64 ... 95:
+        return 16;
+    case 64+32: /* nip */
+    case 65+32: /* msr */
+    case 67+32: /* lr */
+    case 68+32: /* ctr */
+    case 69+32: /* xer */
+    case 70+32: /* fpscr */
+        return 8;
+    case 66+32: /* cr */
+        return 4;
+    default:
+        return 0;
+    }
+}
+
 static int ppc_gdb_register_len(int n)
 {
     switch (n) {
@@ -132,6 +157,65 @@ int ppc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n)
     return r;
 }
 
+int ppc_cpu_gdb_read_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+    int r = ppc_gdb_register_len_apple(n);
+
+    if (!r) {
+        return r;
+    }
+
+    if (n < 32) {
+        /* gprs */
+        gdb_get_reg64(mem_buf, env->gpr[n]);
+    } else if (n < 64) {
+        /* fprs */
+        stfq_p(mem_buf, env->fpr[n-32]);
+    } else if (n < 96) {
+        /* Altivec */
+        stq_p(mem_buf, n - 64);
+        stq_p(mem_buf + 8, 0);
+    } else {
+        switch (n) {
+        case 64 + 32:
+            gdb_get_reg64(mem_buf, env->nip);
+            break;
+        case 65 + 32:
+            gdb_get_reg64(mem_buf, env->msr);
+            break;
+        case 66 + 32:
+            {
+                uint32_t cr = 0;
+                int i;
+                for (i = 0; i < 8; i++) {
+                    cr |= env->crf[i] << (32 - ((i + 1) * 4));
+                }
+                gdb_get_reg32(mem_buf, cr);
+                break;
+            }
+        case 67 + 32:
+            gdb_get_reg64(mem_buf, env->lr);
+            break;
+        case 68 + 32:
+            gdb_get_reg64(mem_buf, env->ctr);
+            break;
+        case 69 + 32:
+            gdb_get_reg64(mem_buf, env->xer);
+            break;
+        case 70 + 32:
+            gdb_get_reg64(mem_buf, env->fpscr);
+            break;
+        }
+    }
+    if (msr_le) {
+        /* If cpu is in LE mode, convert memory contents to LE. */
+        ppc_gdb_swap_register(mem_buf, n, r);
+    }
+    return r;
+}
+
 int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
@@ -185,3 +269,56 @@ int ppc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
     }
     return r;
 }
+int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n)
+{
+    PowerPCCPU *cpu = POWERPC_CPU(cs);
+    CPUPPCState *env = &cpu->env;
+    int r = ppc_gdb_register_len_apple(n);
+
+    if (!r) {
+        return r;
+    }
+    if (msr_le) {
+        /* If cpu is in LE mode, convert memory contents to LE. */
+        ppc_gdb_swap_register(mem_buf, n, r);
+    }
+    if (n < 32) {
+        /* gprs */
+        env->gpr[n] = ldq_p(mem_buf);
+    } else if (n < 64) {
+        /* fprs */
+        env->fpr[n-32] = ldfq_p(mem_buf);
+    } else {
+        switch (n) {
+        case 64 + 32:
+            env->nip = ldq_p(mem_buf);
+            break;
+        case 65 + 32:
+            ppc_store_msr(env, ldq_p(mem_buf));
+            break;
+        case 66 + 32:
+            {
+                uint32_t cr = ldl_p(mem_buf);
+                int i;
+                for (i = 0; i < 8; i++) {
+                    env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
+                }
+                break;
+            }
+        case 67 + 32:
+            env->lr = ldq_p(mem_buf);
+            break;
+        case 68 + 32:
+            env->ctr = ldq_p(mem_buf);
+            break;
+        case 69 + 32:
+            env->xer = ldq_p(mem_buf);
+            break;
+        case 70 + 32:
+            /* fpscr */
+            store_fpscr(env, ldq_p(mem_buf), 0xffffffff);
+            break;
+        }
+    }
+    return r;
+}
index 85581c953762affcf24d417be1a6129ea1a1af32..594f7ac8d1d16435da44b25a9bc667475df8ff33 100644 (file)
@@ -34,6 +34,7 @@
 //#define PPC_DUMP_CPU
 //#define PPC_DEBUG_SPR
 //#define PPC_DUMP_SPR_ACCESSES
+/* #define USE_APPLE_GDB */
 
 /* For user-mode emulation, we don't emulate any IRQ controller */
 #if defined(CONFIG_USER_ONLY)
@@ -9667,6 +9668,13 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
 #endif
 
     cc->gdb_num_core_regs = 71;
+
+#ifdef USE_APPLE_GDB
+    cc->gdb_read_register = ppc_cpu_gdb_read_register_apple;
+    cc->gdb_write_register = ppc_cpu_gdb_write_register_apple;
+    cc->gdb_num_core_regs = 71 + 32;
+#endif
+
 #if defined(TARGET_PPC64)
     cc->gdb_core_xml_file = "power64-core.xml";
 #else