From: Jan Kiszka <jan.kiszka-kv7WeFo6aLtBDgjK7y7TUQ@public.gmane.org>
To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Subject: [PATCH] align gdbstub with QEMU
Date: Fri, 07 Dec 2007 14:24:04 +0100 [thread overview]
Message-ID: <47594974.4010805@siemens.com> (raw)
We've noticed some problems with current gdbstub in kvm's qemu:
# qemu-system-x86_64 -hda myimage -S -s &
# gdb
(gdb) tar re :1234
Remote debugging using :1234
Remote 'g' packet reply is too long:
000000000000000000000000000000000000[...]
This issue did not occur with QEMU from CVS. As I was aware of an
x86_64-related problem in QEMU's gdbstub, I merged its current state
into kvm - and things start to work again. Find the update patch below.
Signed-off-by: Jan Kiszka <jan.kiszka-kv7WeFo6aLtBDgjK7y7TUQ@public.gmane.org>
---
qemu/gdbstub.c | 290 ++++++++++++++++++++++++++++-----------------------------
1 file changed, 143 insertions(+), 147 deletions(-)
Index: kvm-54/qemu/gdbstub.c
===================================================================
--- kvm-54.orig/qemu/gdbstub.c
+++ kvm-54/qemu/gdbstub.c
@@ -222,146 +222,60 @@ static int put_packet(GDBState *s, char
return 0;
}
-#if defined(TARGET_X86_64)
+#if defined(TARGET_I386)
static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
{
- uint8_t *p = mem_buf;
int i, fpus;
+ uint32_t *registers = (uint32_t *)mem_buf;
-#define PUTREG(x) do { \
- target_ulong reg = tswapl(x); \
- memcpy(p, ®, sizeof reg); \
- p += sizeof reg; \
- } while (0)
-#define PUTREG32(x) do { \
- uint32_t reg = tswap32(x); \
- memcpy(p, ®, sizeof reg); \
- p += sizeof reg; \
- } while (0)
-#define PUTREGF(x) do { \
- memcpy(p, &(x), 10); \
- p += sizeof (x); \
- } while (0)
-
- PUTREG(env->regs[R_EAX]);
- PUTREG(env->regs[R_EBX]);
- PUTREG(env->regs[R_ECX]);
- PUTREG(env->regs[R_EDX]);
- PUTREG(env->regs[R_ESI]);
- PUTREG(env->regs[R_EDI]);
- PUTREG(env->regs[R_EBP]);
- PUTREG(env->regs[R_ESP]);
- PUTREG(env->regs[8]);
- PUTREG(env->regs[9]);
- PUTREG(env->regs[10]);
- PUTREG(env->regs[11]);
- PUTREG(env->regs[12]);
- PUTREG(env->regs[13]);
- PUTREG(env->regs[14]);
- PUTREG(env->regs[15]);
-
- PUTREG(env->eip);
- PUTREG32(env->eflags);
- PUTREG32(env->segs[R_CS].selector);
- PUTREG32(env->segs[R_SS].selector);
- PUTREG32(env->segs[R_DS].selector);
- PUTREG32(env->segs[R_ES].selector);
- PUTREG32(env->segs[R_FS].selector);
- PUTREG32(env->segs[R_GS].selector);
- /* XXX: convert floats */
- for(i = 0; i < 8; i++) {
- PUTREGF(env->fpregs[i]);
- }
- PUTREG32(env->fpuc);
- fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
- PUTREG32(fpus);
- PUTREG32(0); /* XXX: convert tags */
- PUTREG32(0); /* fiseg */
- PUTREG32(0); /* fioff */
- PUTREG32(0); /* foseg */
- PUTREG32(0); /* fooff */
- PUTREG32(0); /* fop */
-
-#undef PUTREG
-#undef PUTREG32
-#undef PUTREGF
-
- return p - mem_buf;
-}
+#ifdef TARGET_X86_64
+ /* This corresponds with amd64_register_info[] in gdb/amd64-tdep.c */
+ uint64_t *registers64 = (uint64_t *)mem_buf;
+
+ if (env->hflags & HF_CS64_MASK) {
+ registers64[0] = tswap64(env->regs[R_EAX]);
+ registers64[1] = tswap64(env->regs[R_EBX]);
+ registers64[2] = tswap64(env->regs[R_ECX]);
+ registers64[3] = tswap64(env->regs[R_EDX]);
+ registers64[4] = tswap64(env->regs[R_ESI]);
+ registers64[5] = tswap64(env->regs[R_EDI]);
+ registers64[6] = tswap64(env->regs[R_EBP]);
+ registers64[7] = tswap64(env->regs[R_ESP]);
+ for(i = 8; i < 16; i++) {
+ registers64[i] = tswap64(env->regs[i]);
+ }
+ registers64[16] = tswap64(env->eip);
-static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
-{
- uint8_t *p = mem_buf;
- uint32_t junk;
- int i, fpus;
+ registers = (uint32_t *)®isters64[17];
+ registers[0] = tswap32(env->eflags);
+ registers[1] = tswap32(env->segs[R_CS].selector);
+ registers[2] = tswap32(env->segs[R_SS].selector);
+ registers[3] = tswap32(env->segs[R_DS].selector);
+ registers[4] = tswap32(env->segs[R_ES].selector);
+ registers[5] = tswap32(env->segs[R_FS].selector);
+ registers[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);
+ }
+ registers[27] = tswap32(env->fpuc); /* fctrl */
+ fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
+ registers[28] = tswap32(fpus); /* fstat */
+ registers[29] = 0; /* ftag */
+ registers[30] = 0; /* fiseg */
+ registers[31] = 0; /* fioff */
+ registers[32] = 0; /* foseg */
+ registers[33] = 0; /* fooff */
+ registers[34] = 0; /* fop */
+ for(i = 0; i < 16; i++) {
+ memcpy(mem_buf + 16 * 8 + 35 * 4 + i * 16, &env->xmm_regs[i], 16);
+ }
+ registers[99] = tswap32(env->mxcsr);
-#define GETREG(x) do { \
- target_ulong reg; \
- memcpy(®, p, sizeof reg); \
- x = tswapl(reg); \
- p += sizeof reg; \
- } while (0)
-#define GETREG32(x) do { \
- uint32_t reg; \
- memcpy(®, p, sizeof reg); \
- x = tswap32(reg); \
- p += sizeof reg; \
- } while (0)
-#define GETREGF(x) do { \
- memcpy(&(x), p, 10); \
- p += 10; \
- } while (0)
-
- GETREG(env->regs[R_EAX]);
- GETREG(env->regs[R_EBX]);
- GETREG(env->regs[R_ECX]);
- GETREG(env->regs[R_EDX]);
- GETREG(env->regs[R_ESI]);
- GETREG(env->regs[R_EDI]);
- GETREG(env->regs[R_EBP]);
- GETREG(env->regs[R_ESP]);
- GETREG(env->regs[8]);
- GETREG(env->regs[9]);
- GETREG(env->regs[10]);
- GETREG(env->regs[11]);
- GETREG(env->regs[12]);
- GETREG(env->regs[13]);
- GETREG(env->regs[14]);
- GETREG(env->regs[15]);
-
- GETREG(env->eip);
- GETREG32(env->eflags);
- GETREG32(env->segs[R_CS].selector);
- GETREG32(env->segs[R_SS].selector);
- GETREG32(env->segs[R_DS].selector);
- GETREG32(env->segs[R_ES].selector);
- GETREG32(env->segs[R_FS].selector);
- GETREG32(env->segs[R_GS].selector);
- /* XXX: convert floats */
- for(i = 0; i < 8; i++) {
- GETREGF(env->fpregs[i]);
+ return 8 * 17 + 4 * 7 + 10 * 8 + 4 * 8 + 16 * 16 + 4;
}
- GETREG32(env->fpuc);
- GETREG32(fpus); /* XXX: convert fpus */
- GETREG32(junk); /* XXX: convert tags */
- GETREG32(junk); /* fiseg */
- GETREG32(junk); /* fioff */
- GETREG32(junk); /* foseg */
- GETREG32(junk); /* fooff */
- GETREG32(junk); /* fop */
-
-#undef GETREG
-#undef GETREG32
-#undef GETREGF
-}
-
-#elif defined(TARGET_I386)
-
-static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
-{
- uint32_t *registers = (uint32_t *)mem_buf;
- int i, fpus;
+#endif
for(i = 0; i < 8; i++) {
registers[i] = env->regs[i];
@@ -435,7 +349,7 @@ static int cpu_gdb_read_registers(CPUSta
}
/* nip, msr, ccr, lnk, ctr, xer, mq */
registers[96] = tswapl(env->nip);
- registers[97] = tswapl(do_load_msr(env));
+ registers[97] = tswapl(env->msr);
tmp = 0;
for (i = 0; i < 8; i++)
tmp |= env->crf[i] << (32 - ((i + 1) * 4));
@@ -464,7 +378,7 @@ static void cpu_gdb_write_registers(CPUS
}
/* nip, msr, ccr, lnk, ctr, xer, mq */
env->nip = tswapl(registers[96]);
- do_store_msr(env, tswapl(registers[97]));
+ ppc_store_msr(env, tswapl(registers[97]));
registers[98] = tswapl(registers[98]);
for (i = 0; i < 8; i++)
env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;
@@ -698,7 +612,7 @@ static int cpu_gdb_read_registers(CPUSta
ptr += sizeof(target_ulong);
}
- *(target_ulong *)ptr = tswapl(env->CP0_Status);
+ *(target_ulong *)ptr = (int32_t)tswap32(env->CP0_Status);
ptr += sizeof(target_ulong);
*(target_ulong *)ptr = tswapl(env->LO[0][env->current_tc]);
@@ -710,7 +624,7 @@ static int cpu_gdb_read_registers(CPUSta
*(target_ulong *)ptr = tswapl(env->CP0_BadVAddr);
ptr += sizeof(target_ulong);
- *(target_ulong *)ptr = tswapl(env->CP0_Cause);
+ *(target_ulong *)ptr = (int32_t)tswap32(env->CP0_Cause);
ptr += sizeof(target_ulong);
*(target_ulong *)ptr = tswapl(env->PC[env->current_tc]);
@@ -720,19 +634,34 @@ static int cpu_gdb_read_registers(CPUSta
{
for (i = 0; i < 32; i++)
{
- *(target_ulong *)ptr = tswapl(env->fpu->fpr[i].fs[FP_ENDIAN_IDX]);
+ if (env->CP0_Status & (1 << CP0St_FR))
+ *(target_ulong *)ptr = tswapl(env->fpu->fpr[i].d);
+ else
+ *(target_ulong *)ptr = tswap32(env->fpu->fpr[i].w[FP_ENDIAN_IDX]);
ptr += sizeof(target_ulong);
}
- *(target_ulong *)ptr = tswapl(env->fpu->fcr31);
+ *(target_ulong *)ptr = (int32_t)tswap32(env->fpu->fcr31);
+ ptr += sizeof(target_ulong);
+
+ *(target_ulong *)ptr = (int32_t)tswap32(env->fpu->fcr0);
ptr += sizeof(target_ulong);
+ }
+
+ /* "fp", pseudo frame pointer. Not yet implemented in gdb. */
+ *(target_ulong *)ptr = 0;
+ ptr += sizeof(target_ulong);
- *(target_ulong *)ptr = tswapl(env->fpu->fcr0);
+ /* Registers for embedded use, we just pad them. */
+ for (i = 0; i < 16; i++)
+ {
+ *(target_ulong *)ptr = 0;
ptr += sizeof(target_ulong);
}
- /* 32 FP registers, fsr, fir, fp. Not yet implemented. */
- /* what's 'fp' mean here? */
+ /* Processor ID. */
+ *(target_ulong *)ptr = (int32_t)tswap32(env->CP0_PRid);
+ ptr += sizeof(target_ulong);
return ptr - mem_buf;
}
@@ -782,15 +711,17 @@ static void cpu_gdb_write_registers(CPUS
{
for (i = 0; i < 32; i++)
{
- env->fpu->fpr[i].fs[FP_ENDIAN_IDX] = tswapl(*(target_ulong *)ptr);
+ if (env->CP0_Status & (1 << CP0St_FR))
+ env->fpu->fpr[i].d = tswapl(*(target_ulong *)ptr);
+ else
+ env->fpu->fpr[i].w[FP_ENDIAN_IDX] = tswapl(*(target_ulong *)ptr);
ptr += sizeof(target_ulong);
}
- env->fpu->fcr31 = tswapl(*(target_ulong *)ptr) & 0x0183FFFF;
+ env->fpu->fcr31 = tswapl(*(target_ulong *)ptr) & 0xFF83FFFF;
ptr += sizeof(target_ulong);
- env->fpu->fcr0 = tswapl(*(target_ulong *)ptr);
- ptr += sizeof(target_ulong);
+ /* The remaining registers are assumed to be read-only. */
/* set rounding mode */
RESTORE_ROUNDING_MODE;
@@ -863,6 +794,66 @@ static void cpu_gdb_write_registers(CPUS
for (i = 0; i < 8; i++) LOAD(env->gregs[i]);
for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]);
}
+#elif defined (TARGET_CRIS)
+
+static int cris_save_32 (unsigned char *d, uint32_t value)
+{
+ *d++ = (value);
+ *d++ = (value >>= 8);
+ *d++ = (value >>= 8);
+ *d++ = (value >>= 8);
+ return 4;
+}
+static int cris_save_16 (unsigned char *d, uint32_t value)
+{
+ *d++ = (value);
+ *d++ = (value >>= 8);
+ return 2;
+}
+static int cris_save_8 (unsigned char *d, uint32_t value)
+{
+ *d++ = (value);
+ return 1;
+}
+
+/* FIXME: this will bug on archs not supporting unaligned word accesses. */
+static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
+{
+ uint8_t *ptr = mem_buf;
+ uint8_t srs;
+ int i;
+
+ for (i = 0; i < 16; i++)
+ ptr += cris_save_32 (ptr, env->regs[i]);
+
+ srs = env->pregs[SR_SRS];
+
+ ptr += cris_save_8 (ptr, env->pregs[0]);
+ ptr += cris_save_8 (ptr, env->pregs[1]);
+ ptr += cris_save_32 (ptr, env->pregs[2]);
+ ptr += cris_save_8 (ptr, srs);
+ ptr += cris_save_16 (ptr, env->pregs[4]);
+
+ for (i = 5; i < 16; i++)
+ ptr += cris_save_32 (ptr, env->pregs[i]);
+
+ ptr += cris_save_32 (ptr, env->pc);
+
+ for (i = 0; i < 16; i++)
+ ptr += cris_save_32 (ptr, env->sregs[srs][i]);
+
+ return ((uint8_t *)ptr - mem_buf);
+}
+
+static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
+{
+ uint32_t *ptr = (uint32_t *)mem_buf;
+ int i;
+
+#define LOAD(x) (x)=*ptr++;
+ for (i = 0; i < 16; i++) LOAD(env->regs[i]);
+ LOAD (env->pc);
+}
#else
static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
{
@@ -880,7 +871,7 @@ static int gdb_handle_packet(GDBState *s
const char *p;
int ch, reg_size, type;
char buf[4096];
- uint8_t mem_buf[2000];
+ uint8_t mem_buf[4096];
uint32_t *registers;
target_ulong addr, len;
@@ -914,6 +905,8 @@ static int gdb_handle_packet(GDBState *s
env->pc = addr;
#elif defined (TARGET_MIPS)
env->PC[env->current_tc] = addr;
+#elif defined (TARGET_CRIS)
+ env->pc = addr;
#endif
}
#ifdef CONFIG_USER_ONLY
@@ -941,6 +934,8 @@ static int gdb_handle_packet(GDBState *s
env->pc = addr;
#elif defined (TARGET_MIPS)
env->PC[env->current_tc] = addr;
+#elif defined (TARGET_CRIS)
+ env->pc = addr;
#endif
}
cpu_single_step(env, 1);
@@ -1070,7 +1065,8 @@ static int gdb_handle_packet(GDBState *s
TaskState *ts = env->opaque;
sprintf(buf,
- "Text=" TARGET_FMT_lx ";Data=" TARGET_FMT_lx ";Bss=" TARGET_FMT_lx,
+ "Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx
+ ";Bss=" TARGET_ABI_FMT_lx,
ts->info->code_offset,
ts->info->data_offset,
ts->info->data_offset);
--
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux
-------------------------------------------------------------------------
SF.Net email is sponsored by:
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
next reply other threads:[~2007-12-07 13:24 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-12-07 13:24 Jan Kiszka [this message]
[not found] ` <47594974.4010805-kv7WeFo6aLtBDgjK7y7TUQ@public.gmane.org>
2007-12-14 11:57 ` [PATCH] align gdbstub with QEMU Jan Kiszka
[not found] ` <47626F8F.8010806-kv7WeFo6aLtBDgjK7y7TUQ@public.gmane.org>
2007-12-14 14:18 ` Avi Kivity
[not found] ` <476290CA.2040001-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-12-14 14:27 ` Jan Kiszka
[not found] ` <476292CD.3020703-kv7WeFo6aLtBDgjK7y7TUQ@public.gmane.org>
2007-12-14 14:31 ` Avi Kivity
2007-12-20 14:57 ` Jan Kiszka
[not found] ` <476A82D5.8040306-kv7WeFo6aLtBDgjK7y7TUQ@public.gmane.org>
2007-12-20 15:06 ` Avi Kivity
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=47594974.4010805@siemens.com \
--to=jan.kiszka-kv7wefo6altbdgjk7y7tuq@public.gmane.org \
--cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.