From: Fabien Chouteau <chouteau@adacore.com>
To: qemu-devel@nongnu.org
Cc: blauwirbel@gmail.com
Subject: [Qemu-devel] [PATCH] [SPARC] Gdbstub: Fix back-trace on SPARC32
Date: Thu, 1 Sep 2011 16:17:26 +0200 [thread overview]
Message-ID: <1314886646-10714-1-git-send-email-chouteau@adacore.com> (raw)
Gdb expects all registers windows to be flushed in ram, which is not the case
in Qemu. Therefore the back-trace generation doesn't work. This patch adds a
function to handle reads/writes in stack frames as if windows were flushed.
Signed-off-by: Fabien Chouteau <chouteau@adacore.com>
---
gdbstub.c | 10 ++++--
target-sparc/cpu.h | 7 ++++
target-sparc/helper.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 99 insertions(+), 3 deletions(-)
diff --git a/gdbstub.c b/gdbstub.c
index 3b87c27..85d5ad7 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -41,6 +41,9 @@
#include "qemu_socket.h"
#include "kvm.h"
+#ifndef TARGET_CPU_MEMORY_RW_DEBUG
+#define TARGET_CPU_MEMORY_RW_DEBUG cpu_memory_rw_debug
+#endif
enum {
GDB_SIGNAL_0 = 0,
@@ -2013,7 +2016,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
if (*p == ',')
p++;
len = strtoull(p, NULL, 16);
- if (cpu_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 0) != 0) {
+ if (TARGET_CPU_MEMORY_RW_DEBUG(s->g_cpu, addr, mem_buf, len, 0) != 0) {
put_packet (s, "E14");
} else {
memtohex(buf, mem_buf, len);
@@ -2028,10 +2031,11 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
if (*p == ':')
p++;
hextomem(mem_buf, p, len);
- if (cpu_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 1) != 0)
+ if (TARGET_CPU_MEMORY_RW_DEBUG(s->g_cpu, addr, mem_buf, len, 1) != 0) {
put_packet(s, "E14");
- else
+ } else {
put_packet(s, "OK");
+ }
break;
case 'p':
/* Older gdb are really dumb, and don't use 'g' if 'p' is avaialable.
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 8654f26..3f76eaf 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -495,6 +495,13 @@ int cpu_sparc_handle_mmu_fault(CPUSPARCState *env1, target_ulong address, int rw
target_ulong mmu_probe(CPUSPARCState *env, target_ulong address, int mmulev);
void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env);
+#if !defined(TARGET_SPARC64)
+int sparc_cpu_memory_rw_debug(CPUState *env, target_ulong addr,
+ uint8_t *buf, int len, int is_write);
+#define TARGET_CPU_MEMORY_RW_DEBUG sparc_cpu_memory_rw_debug
+#endif
+
+
/* translate.c */
void gen_intermediate_code_init(CPUSPARCState *env);
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index 1fe1f07..2cf4e8b 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -358,6 +358,91 @@ void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUState *env)
}
}
+
+/* Gdb expects all registers windows to be flushed in ram. This function handles
+ * reads/writes in stack frames as if windows were flushed. We assume that the
+ * sparc ABI is followed.
+ */
+int sparc_cpu_memory_rw_debug(CPUState *env, target_ulong addr,
+ uint8_t *buf, int len, int is_write)
+{
+ int i;
+ int len1;
+ int cwp = env->cwp;
+
+ for (i = 0; i < env->nwindows; i++) {
+ int off;
+ target_ulong fp = env->regbase[cwp * 16 + 22];
+
+ /* Assume fp == 0 means end of frame. */
+ if (fp == 0) {
+ break;
+ }
+
+ cwp = cpu_cwp_inc(env, cwp + 1);
+
+ /* Invalid window ? */
+ if (env->wim & (1 << cwp)) {
+ break;
+ }
+
+ /* According to the ABI, the stack is growing downward. */
+ if (addr + len < fp) {
+ break;
+ }
+
+ /* Not in this frame. */
+ if (addr > fp + 64) {
+ continue;
+ }
+
+ /* Handle access before this window. */
+ if (addr < fp) {
+ len1 = fp - addr;
+ if (cpu_memory_rw_debug(env, addr, buf, len1, is_write) != 0) {
+ return -1;
+ }
+ addr += len1;
+ len -= len1;
+ buf += len1;
+ }
+
+ /* Access byte per byte to registers. Not very efficient but speed is
+ * not critical.
+ */
+ off = addr - fp;
+ len1 = 64 - off;
+
+ if (len1 > len) {
+ len1 = len;
+ }
+
+ for (; len1; len1--) {
+ int reg = cwp * 16 + 8 + (off >> 2);
+ union {
+ uint32_t v;
+ uint8_t c[4];
+ } u;
+ u.v = cpu_to_be32(env->regbase[reg]);
+ if (is_write) {
+ u.c[off & 3] = *buf++;
+ env->regbase[reg] = be32_to_cpu(u.v);
+ } else {
+ *buf++ = u.c[off & 3];
+ }
+ addr++;
+ len--;
+ off++;
+ }
+
+ if (len == 0) {
+ return 0;
+ }
+ }
+ return cpu_memory_rw_debug(env, addr, buf, len, is_write);
+}
+
+
#else /* !TARGET_SPARC64 */
// 41 bit physical address space
--
1.7.4.1
next reply other threads:[~2011-09-01 14:17 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-01 14:17 Fabien Chouteau [this message]
2011-09-03 9:25 ` [Qemu-devel] [PATCH] [SPARC] Gdbstub: Fix back-trace on SPARC32 Blue Swirl
2011-09-05 9:33 ` Fabien Chouteau
2011-09-05 19:22 ` Blue Swirl
2011-09-06 10:38 ` Fabien Chouteau
2011-09-07 19:02 ` Blue Swirl
2011-09-08 8:39 ` Fabien Chouteau
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=1314886646-10714-1-git-send-email-chouteau@adacore.com \
--to=chouteau@adacore.com \
--cc=blauwirbel@gmail.com \
--cc=qemu-devel@nongnu.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).