amd64 support in cpu_gdb_read_registers()
PATCH 1/1 amd64 support in cpu_gdb_read_registers()
Hi,
earlier this week I needed to use gdb with QEMU to debug some software of mine that runs in a 64-bit code segment. But gdb only gave me nonsense data because QEMU sent it a normal i386 register dump.
The following patch fixes cpu_gdb_read_registers() so that it works for 64-bit code segments. It's based on the 32-bit version and I haven't verified if the byte swapping and floating point stuff is correct.
cpu_gdb_write_registers() also needs to be fixed, but I don't have any personal need for it right now and I also don't understand why it loads the segment registers only when CONFIG_USER_ONLY is defined. Seems to me like it should be the other way around, so I don't dare suggest a patch.
Index: gdbstub.c
===================================================================
RCS file: /sources/qemu/qemu/gdbstub.c,v
retrieving revision 1.63
gdbstub.c +47 -1
@@ -225,8 +225,54 @@static int cpu_gdb_read_registers (CPUState *env,uint8_t *mem_buf) { -uint32_t *registers = (uint32_t *)mem_buf;int i, fpus; +#ifdef TARGET_X86_64 +if (env->hflags &HF_CS64_MASK ) { +/* This corresponds with amd64_register_info[] in gdb/amd64-tdep.c */ +uint64_t *registers = (uint64_t *)mem_buf; + + registers[0 ] =tswap64 (env->regs[R_EAX ]); + registers[1 ] =tswap64 (env->regs[R_EBX ]); + registers[2 ] =tswap64 (env->regs[R_ECX ]); + registers[3 ] =tswap64 (env->regs[R_EDX ]); + registers[4 ] =tswap64 (env->regs[R_ESI ]); + registers[5 ] =tswap64 (env->regs[R_EDI ]); + registers[6 ] =tswap64 (env->regs[R_EBP ]); + registers[7 ] =tswap64 (env->regs[R_ESP ]); +for (i =8 ; i <16 ; i++) { + registers[i] =tswap64 (env->regs[i]); + } + registers[16 ] =tswap64 (env->eip); +uint32_t *registers32 = (uint32_t *) ®isters[17 ]; + registers32[0 ] =tswap32 (env->eflags); + registers32[1 ] =tswap32 (env->segs[R_CS ].selector); + registers32[2 ] =tswap32 (env->segs[R_SS ].selector); + registers32[3 ] =tswap32 (env->segs[R_DS ].selector); + registers32[4 ] =tswap32 (env->segs[R_ES ].selector); + registers32[5 ] =tswap32 (env->segs[R_FS ].selector); + registers32[6 ] =tswap32 (env->segs[R_GS ].selector); +/* XXX: convert floats */ +for (i =0 ; i <8 ; i++) { +memcpy (mem_buf +16 *8 +7 *4 + i *10 , &env->fpregs[i],10 ); + } + registers32[27 ] =tswap32 (env->fpuc);/* fctrl */ + fpus = (env->fpus & ~0x3800 ) | (env->fpstt &0x7 ) <<11 ; + registers32[28 ] =tswap32 (fpus);/* fstat */ + registers32[29 ] =0 ;/* ftag */ + registers32[30 ] =0 ;/* fiseg */ + registers32[31 ] =0 ;/* fioff */ + registers32[32 ] =0 ;/* foseg */ + registers32[33 ] =0 ;/* fooff */ + registers32[34 ] =0 ;/* fop */ +for (i =0 ; i <16 ; i++) { +memcpy (mem_buf +16 *8 +35 *4 + i *16 , &env->xmm_regs[i],16 ); + } + registers32[99 ] =tswap32 (env->mxcsr); + +return 8 *17 +4 *7 +10 *8 +4 *8 +16 *16 +4 ; + } +#endif +uint32_t *registers = (uint32_t *)mem_buf;for (i =0 ; i <8 ; i++) { registers[i] = env->regs[i];
Signature · 2 lines
Göran Weinholt <[email protected]> I was making donuts and now I'm on a bus!