From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1HfJkD-0002nl-Qu for qemu-devel@nongnu.org; Sat, 21 Apr 2007 13:51:33 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1HfJkA-0002nZ-TS for qemu-devel@nongnu.org; Sat, 21 Apr 2007 13:51:32 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1HfJkA-0002nW-RN for qemu-devel@nongnu.org; Sat, 21 Apr 2007 13:51:30 -0400 Received: from fmmailgate03.web.de ([217.72.192.234]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1HfJex-0008Bv-Rd for qemu-devel@nongnu.org; Sat, 21 Apr 2007 13:46:08 -0400 Message-ID: <462A4DCB.5050909@web.de> Date: Sat, 21 Apr 2007 19:45:47 +0200 From: Jan Kiszka MIME-Version: 1.0 Subject: Re: [Qemu-devel] Re: [PATCH] x86_64 debug registers for gdb References: <45105864.9090902@windriver.com> <200704201355.14379.paul@codesourcery.com> <46293B99.8000909@web.de> <200704210013.40931.paul@codesourcery.com> In-Reply-To: <200704210013.40931.paul@codesourcery.com> Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="------------enigEB2A2923EA6C2690C8A82C84" Sender: jan.kiszka@web.de Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Paul Brook Cc: qemu-devel@nongnu.org This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enigEB2A2923EA6C2690C8A82C84 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Paul Brook wrote: >>> These are all wrong on x86-64. >> Then what about pointing me to the correct information to fix this, hm= m? >> I browsed gdb code and docs but found no obvious packet format >> description. Constructive help is welcome, likely I'm just blind. >=20 > gdb/amd64-tdep.c is the authorative source. Specifically amd64_register= _info. > Similar information also in gdb/regformats/reg-x86-64.dat >=20 Yep, I was blind. Here comes another try. Please have a look/comment on the following specifically: - Why is there no fpu-related code in cpu_gdb_write_registers()? Is fpu debugging only partially supported yet? - I included xmm and mxcsr regs into cpu_gdb_read_registers(), but I'm not sure if it's correct (byte ordering, format of mxcsr) - If I understood gdb correctly, fpu registers (st0..7) are always encoded in an arch-neutral format, no conversion on exchange is needed. Thus, is it correct to remove the related "XXX" comment from cpu_gdb_read_registers()? - Would it be simple to get the remaining fpu control registers right? Just to take the chance and finalise this code if we are already at it. Jan --- gdbstub.c | 118 ++++++++++++++++++++++++++++++++++++++-----------------= ------- 1 file changed, 73 insertions(+), 45 deletions(-) Index: qemu-0.9.0/gdbstub.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D --- qemu-0.9.0.orig/gdbstub.c +++ qemu-0.9.0/gdbstub.c @@ -222,64 +222,92 @@ static int put_packet(GDBState *s, char=20 } =20 #if defined(TARGET_I386) +struct x86_gdb_regs { + target_ulong gp[CPU_NB_REGS]; + target_ulong ip; + uint32_t flags; + uint32_t segm[6]; + uint8_t fpreg[8][10]; + uint32_t fpctrl[8]; + uint64_t xmm[CPU_NB_REGS][2]; + uint32_t mxcsr; +} __attribute__((packed)); =20 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) { - uint32_t *registers =3D (uint32_t *)mem_buf; + struct x86_gdb_regs *regs =3D (struct x86_gdb_regs *)mem_buf; int i, fpus; =20 - for(i =3D 0; i < 8; i++) { - registers[i] =3D env->regs[i]; - } - registers[8] =3D env->eip; - registers[9] =3D env->eflags; - registers[10] =3D env->segs[R_CS].selector; - registers[11] =3D env->segs[R_SS].selector; - registers[12] =3D env->segs[R_DS].selector; - registers[13] =3D env->segs[R_ES].selector; - registers[14] =3D env->segs[R_FS].selector; - registers[15] =3D env->segs[R_GS].selector; - /* XXX: convert floats */ - for(i =3D 0; i < 8; i++) { - memcpy(mem_buf + 16 * 4 + i * 10, &env->fpregs[i], 10); - } - registers[36] =3D env->fpuc; + for(i =3D 0; i < CPU_NB_REGS; i++) + regs->gp[i] =3D tswapl(env->regs[i]); +#if defined(TARGET_X86_64) + /* Fix-up register mapping */ + regs->gp[1] =3D tswapl(env->regs[R_EBX]); + regs->gp[2] =3D tswapl(env->regs[R_ECX]); + regs->gp[3] =3D tswapl(env->regs[R_EDX]); +#endif + + regs->ip =3D tswapl(env->eip); + regs->flags =3D tswap32(env->eflags); + + regs->segm[0] =3D tswap32(env->segs[R_CS].selector); + regs->segm[1] =3D tswap32(env->segs[R_SS].selector); + regs->segm[2] =3D tswap32(env->segs[R_DS].selector); + regs->segm[3] =3D tswap32(env->segs[R_ES].selector); + regs->segm[4] =3D tswap32(env->segs[R_FS].selector); + regs->segm[5] =3D tswap32(env->segs[R_GS].selector); + + for (i =3D 0; i < 8; i++) + memcpy(regs->fpreg[i], &env->fpregs[i], 10); + + regs->fpctrl[0] =3D tswap32(env->fpuc); fpus =3D (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; - registers[37] =3D fpus; - registers[38] =3D 0; /* XXX: convert tags */ - registers[39] =3D 0; /* fiseg */ - registers[40] =3D 0; /* fioff */ - registers[41] =3D 0; /* foseg */ - registers[42] =3D 0; /* fooff */ - registers[43] =3D 0; /* fop */ - =20 - for(i =3D 0; i < 16; i++) - tswapls(®isters[i]); - for(i =3D 36; i < 44; i++) - tswapls(®isters[i]); - return 44 * 4; + regs->fpctrl[1] =3D tswap32(fpus); + regs->fpctrl[2] =3D 0; /* XXX: convert tags */ + regs->fpctrl[3] =3D 0; /* fiseg */ + regs->fpctrl[4] =3D 0; /* fioff */ + regs->fpctrl[5] =3D 0; /* foseg */ + regs->fpctrl[6] =3D 0; /* fooff */ + regs->fpctrl[7] =3D 0; /* fop */ + + for (i =3D 0; i < CPU_NB_REGS; i++) { + regs->xmm[i][0] =3D tswap64(&env->xmm_regs[i].XMM_Q(0)); + regs->xmm[i][1] =3D tswap64(&env->xmm_regs[i].XMM_Q(1)); + } + + regs->mxcsr =3D tswap32(env->mxcsr); + + return sizeof(struct x86_gdb_regs); } =20 static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int= size) { - uint32_t *registers =3D (uint32_t *)mem_buf; + struct x86_gdb_regs *regs =3D (struct x86_gdb_regs *)mem_buf; int i; =20 - for(i =3D 0; i < 8; i++) { - env->regs[i] =3D tswapl(registers[i]); - } - env->eip =3D tswapl(registers[8]); - env->eflags =3D tswapl(registers[9]); + for (i =3D 0; i < CPU_NB_REGS; i++) + env->regs[i] =3D tswapl(regs->gp[i]); +#if defined(TARGET_X86_64) + /* Fix-up register mapping */ + env->regs[R_EBX] =3D tswapl(regs->gp[1]); + env->regs[R_ECX] =3D tswapl(regs->gp[2]); + env->regs[R_EDX] =3D tswapl(regs->gp[3]); +#endif + + env->eip =3D tswapl(regs->ip); + env->eflags =3D tswap32(regs->flags); + #if defined(CONFIG_USER_ONLY) -#define LOAD_SEG(index, sreg)\ - if (tswapl(registers[index]) !=3D env->segs[sreg].selector)\= - cpu_x86_load_seg(env, sreg, tswapl(registers[index])); - LOAD_SEG(10, R_CS); - LOAD_SEG(11, R_SS); - LOAD_SEG(12, R_DS); - LOAD_SEG(13, R_ES); - LOAD_SEG(14, R_FS); - LOAD_SEG(15, R_GS); +#define LOAD_SEG(index, sreg) \ + if (tswap32(regs->segm[index]) !=3D env->segs[sreg].selector) \ + cpu_x86_load_seg(env, sreg, tswap32(regs->segm[index])); + + LOAD_SEG(0, R_CS); + LOAD_SEG(1, R_SS); + LOAD_SEG(2, R_DS); + LOAD_SEG(3, R_ES); + LOAD_SEG(4, R_FS); + LOAD_SEG(5, R_GS); #endif } =20 --------------enigEB2A2923EA6C2690C8A82C84 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.5 (GNU/Linux) Comment: Using GnuPG with SUSE - http://enigmail.mozdev.org iD8DBQFGKk3QniDOoMHTA+kRAtEJAJ4jO/bvq/dIPrJ6xZ4fq3TfNzhuuQCfQGe3 TN+wUoEa04quN/HA4CsxrmA= =iQuC -----END PGP SIGNATURE----- --------------enigEB2A2923EA6C2690C8A82C84--