Jason Wessel wrote: > This patch fixes the registers for the 'g' and 'G' packets for the > qemu-system-x86_64 target. It allows gdb 6.5 to debug a linux kernel > and get a stack back trace. Here comes a corrected (RBX and RDX were mixed) and slightly enhanced (segment register reading, don't know how writing should look like) version of this patch. Tested successfully with qemu-0.9.0 and gdb-6.6. Would be nice to see this support in the next qemu release. Jan Index: qemu-0.9.0/gdbstub.c =================================================================== --- qemu-0.9.0.orig/gdbstub.c +++ qemu-0.9.0/gdbstub.c @@ -220,9 +220,78 @@ static int put_packet(GDBState *s, char } return 0; } +#if defined(TARGET_X86_64) +/* Defines from GDB register struct numbers */ +#define _RAX 0 +#define _RBX 1 +#define _RCX 2 +#define _RDX 3 +#define _RSI 4 +#define _RDI 5 +#define _RBP 6 +#define _RSP 7 +#define _R8 8 +#define _R15 15 +#define _PC 16 +#define _PS 17 +#define _CS 18 +#define _SS 19 +#define _DS 20 +#define _ES 21 +#define _FS 22 +#define _GS 23 +#define _NREGS 24 -#if defined(TARGET_I386) +static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) +{ + uint64_t *registers = (uint64_t *)mem_buf; + int i; + + registers[_RAX] = env->regs[R_EAX]; + registers[_RBX] = env->regs[R_EBX]; + registers[_RCX] = env->regs[R_ECX]; + registers[_RDX] = env->regs[R_EDX]; + registers[_RSI] = env->regs[R_ESI]; + registers[_RDI] = env->regs[R_EDI]; + registers[_RBP] = env->regs[R_EBP]; + registers[_RSP] = env->regs[R_ESP]; + for (i = 8; i < 16; i++) + registers[i] = env->regs[i]; + registers[_PC] = env->eip; + registers[_PS] = env->eflags; + registers[_CS] = env->segs[R_CS].selector; + registers[_SS] = env->segs[R_SS].selector; + registers[_DS] = env->segs[R_DS].selector; + registers[_ES] = env->segs[R_ES].selector; + registers[_FS] = env->segs[R_FS].selector; + registers[_GS] = env->segs[R_GS].selector; + + for(i = 0; i < _NREGS; i++) + tswapl(registers[i]); + + return _NREGS * 8; +} + +static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) +{ + uint32_t *registers = (uint32_t *)mem_buf; + int i; + + env->regs[R_EAX] = tswapl(registers[_RAX]); + env->regs[R_EBX] = tswapl(registers[_RBX]); + env->regs[R_ECX] = tswapl(registers[_RCX]); + env->regs[R_EDX] = tswapl(registers[_RDX]); + env->regs[R_ESI] = tswapl(registers[_RSI]); + env->regs[R_EDI] = tswapl(registers[_RDI]); + env->regs[R_EBP] = tswapl(registers[_RBP]); + env->regs[R_ESP] = tswapl(registers[_RSP]); + for (i = 8; i < 16; i++) + env->regs[i] = tswapl(registers[i]); + env->eip = tswapl(registers[_PC]); + env->eflags = tswapl(registers[_PS]); +} +#elif defined(TARGET_I386) static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) { uint32_t *registers = (uint32_t *)mem_buf;