All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] log disasm insns when nochain + in_asm enabled
@ 2015-11-03 12:13 Sergey Smolov
  2015-11-03 12:13 ` Sergey Smolov
  2015-11-09 17:31 ` Peter Maydell
  0 siblings, 2 replies; 3+ messages in thread
From: Sergey Smolov @ 2015-11-03 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Sergey Smolov

When 'nochain' and 'in_asm' debug options are enabled, QEMU
does not print records about every executed translation block
 (TB). For loop-containing programs it could be suitable to log
 every executed TB. This patch includes a mapping between TBs and
 disassembled instructions for this task to be implemented.

Sergey Smolov (1):
  log disasm insns when nochain + in_asm enabled

 cpu-exec.c            |   20 ++++++++++++++++++++
 disas.c               |   18 +++++++++++++++++-
 include/disas/disas.h |   14 ++++++++++++++
 qemu-log.c            |    2 +-
 4 files changed, 52 insertions(+), 2 deletions(-)

--
1.7.10.4

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Qemu-devel] [PATCH] log disasm insns when nochain + in_asm enabled
  2015-11-03 12:13 [Qemu-devel] [PATCH] log disasm insns when nochain + in_asm enabled Sergey Smolov
@ 2015-11-03 12:13 ` Sergey Smolov
  2015-11-09 17:31 ` Peter Maydell
  1 sibling, 0 replies; 3+ messages in thread
From: Sergey Smolov @ 2015-11-03 12:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: Sergey Smolov

When 'nochain' and 'in_asm' debug options are enabled,
disassembled forms of all executed translation blocks (TB)
 are printed to log. For this task a mapping between
disassembled instructions and executed TBs is created
and used.

Signed-off-by: Sergey Smolov <smolov@ispras.ru>
---
 cpu-exec.c            |   20 ++++++++++++++++++++
 disas.c               |   18 +++++++++++++++++-
 include/disas/disas.h |   14 ++++++++++++++
 qemu-log.c            |    2 +-
 4 files changed, 52 insertions(+), 2 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 7eef083..b9385f9 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -345,6 +345,9 @@ int cpu_exec(CPUState *cpu)
     uintptr_t next_tb;
     SyncClocks sc;
 
+    hwaddr pc_prev;
+    bool pc_prev_valid = false;
+
     if (cpu->halted) {
 #if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY)
         if (cpu->interrupt_request & CPU_INTERRUPT_POLL) {
@@ -474,6 +477,23 @@ int cpu_exec(CPUState *cpu)
                     qemu_log("Trace %p [" TARGET_FMT_lx "] %s\n",
                              tb->tc_ptr, tb->pc, lookup_symbol(tb->pc));
                 }
+                if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
+                    && qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)) {
+                    struct insninfo *s;
+                    for (s = insninfos; s != NULL; s = s->next) {
+                        if (s->insn_addr == tb->pc
+                                && pc_prev_valid
+                                && s->insn_addr != pc_prev) {
+                            qemu_log("%s\n", s->insn);
+                            pc_prev = s->insn_addr;
+                            if (!pc_prev_valid) {
+                                pc_prev_valid = true;
+                            }
+                        } else if (s->insn_addr == pc_prev) {
+                            pc_prev_valid = false;
+                        }
+                    }
+                }
                 /* see if we can patch the calling TB. When the TB
                    spans two pages, we cannot safely do a direct
                    jump. */
diff --git a/disas.c b/disas.c
index 4e11944..51bf68f 100644
--- a/disas.c
+++ b/disas.c
@@ -16,6 +16,9 @@ typedef struct CPUDebug {
 /* Filled in by elfload.c.  Simplistic, but will do for now. */
 struct syminfo *syminfos = NULL;
 
+/* Filled in here. */
+struct insninfo *insninfos;
+
 /* Get LENGTH bytes from info's buffer, at target address memaddr.
    Transfer them to myaddr.  */
 int
@@ -236,7 +239,20 @@ void target_disas(FILE *out, CPUState *cpu, target_ulong code,
     }
 
     for (pc = code; size > 0; pc += count, size -= count) {
-	fprintf(out, "0x" TARGET_FMT_lx ":  ", pc);
+
+        if (qemu_loglevel_mask(CPU_LOG_TB_NOCHAIN)
+            && qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
+            struct insninfo *s =
+                (struct insninfo *)malloc(
+                        sizeof(struct insninfo));
+            s->insn_addr = pc;
+
+            sprintf(s->insn, " " TARGET_FMT_lx " ", pc);
+            s->next = insninfos;
+            insninfos = s;
+        } else {
+            fprintf(out, "0x" TARGET_FMT_lx ":  ", pc);
+        }
 	count = s.info.print_insn(pc, &s.info);
 #if 0
         {
diff --git a/include/disas/disas.h b/include/disas/disas.h
index 2b9293b..75a4c73 100644
--- a/include/disas/disas.h
+++ b/include/disas/disas.h
@@ -2,6 +2,7 @@
 #define _QEMU_DISAS_H
 
 #include "qemu-common.h"
+#include "exec/hwaddr.h"
 
 #ifdef NEED_CPU_H
 /* Disassemble this for me please... (debugging). */
@@ -40,4 +41,17 @@ struct syminfo {
 /* Filled in by elfload.c.  Simplistic, but will do for now. */
 extern struct syminfo *syminfos;
 
+struct insninfo {
+
+    /* Instruction address. */
+    hwaddr insn_addr;
+
+    /* Instruction string representation. */
+    char insn[256];
+    struct insninfo *next;
+};
+
+/* Filled in by disas.c - Information about instructions. */
+extern struct insninfo *insninfos;
+
 #endif /* _QEMU_DISAS_H */
diff --git a/qemu-log.c b/qemu-log.c
index efd07c8..bbc10e3 100644
--- a/qemu-log.c
+++ b/qemu-log.c
@@ -120,7 +120,7 @@ const QEMULogItem qemu_log_items[] = {
       "log when the guest OS does something invalid (eg accessing a\n"
       "non-existent register)" },
     { CPU_LOG_TB_NOCHAIN, "nochain",
-      "do not chain compiled TBs so that \"exec\" and \"cpu\" show\n"
+      "do not chain compiled TBs so that \"exec\", \"in_asm\" and \"cpu\" show\n"
       "complete traces" },
     { 0, NULL, NULL },
 };
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [Qemu-devel] [PATCH] log disasm insns when nochain + in_asm enabled
  2015-11-03 12:13 [Qemu-devel] [PATCH] log disasm insns when nochain + in_asm enabled Sergey Smolov
  2015-11-03 12:13 ` Sergey Smolov
@ 2015-11-09 17:31 ` Peter Maydell
  1 sibling, 0 replies; 3+ messages in thread
From: Peter Maydell @ 2015-11-09 17:31 UTC (permalink / raw)
  To: Sergey Smolov; +Cc: QEMU Developers

On 3 November 2015 at 12:13, Sergey Smolov <smolov@ispras.ru> wrote:
> When 'nochain' and 'in_asm' debug options are enabled, QEMU
> does not print records about every executed translation block
>  (TB). For loop-containing programs it could be suitable to log
>  every executed TB. This patch includes a mapping between TBs and
>  disassembled instructions for this task to be implemented.
>
> Sergey Smolov (1):
>   log disasm insns when nochain + in_asm enabled

Hmm. I'm not entirely sure about this feature. in_asm is
supposed to print the disassembly of the target code when we
translate it (the help text says "for each compiled TB").
If I understand this patch right it just reprints the TB disassembly
on execution, so it doesn't give you any information you couldn't
get by looking backwards in the logfile for where the TB was
translated. What you'd really want for a "disassembly-of-insns
at execute time" is to only print the insns that actually get
run, ie if we have a TB and take an exception halfway through it
then don't print the second half with unexecuted insns, if we
actually don't run the TB because we too an early TB_EXIT code
path instead then don't print any insns, etc. Implementing that would
be a lot trickier, though...

Thanks for sending in the patch, though.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-11-09 17:32 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-03 12:13 [Qemu-devel] [PATCH] log disasm insns when nochain + in_asm enabled Sergey Smolov
2015-11-03 12:13 ` Sergey Smolov
2015-11-09 17:31 ` Peter Maydell

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.