mirror of
https://github.com/qemu/qemu.git
synced 2024-11-27 22:03:35 +08:00
PPC: Add support for Apple gdb in gdbstub
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>
This commit is contained in:
parent
294d129289
commit
b3cad3abf6
@ -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,
|
||||
|
@ -21,6 +21,31 @@
|
||||
#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;
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user