From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56363) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZtbOl-00085v-TM for qemu-devel@nongnu.org; Tue, 03 Nov 2015 08:13:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZtbOh-00063D-3y for qemu-devel@nongnu.org; Tue, 03 Nov 2015 08:13:15 -0500 Received: from smtp.ispras.ru ([83.149.199.79]:44733) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZtbOg-00062r-ND for qemu-devel@nongnu.org; Tue, 03 Nov 2015 08:13:11 -0500 From: Sergey Smolov Date: Tue, 3 Nov 2015 16:13:43 +0400 Message-Id: <1446552823-10872-2-git-send-email-smolov@ispras.ru> In-Reply-To: <1446552823-10872-1-git-send-email-smolov@ispras.ru> References: <1446552823-10872-1-git-send-email-smolov@ispras.ru> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH] log disasm insns when nochain + in_asm enabled List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org 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 --- 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; =20 + hwaddr pc_prev; + bool pc_prev_valid =3D 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 =3D insninfos; s !=3D NULL; s =3D s->next) { + if (s->insn_addr =3D=3D tb->pc + && pc_prev_valid + && s->insn_addr !=3D pc_prev) { + qemu_log("%s\n", s->insn); + pc_prev =3D s->insn_addr; + if (!pc_prev_valid) { + pc_prev_valid =3D true; + } + } else if (s->insn_addr =3D=3D pc_prev) { + pc_prev_valid =3D 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 =3D NULL; =20 +/* 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_u= long code, } =20 for (pc =3D code; size > 0; pc +=3D count, size -=3D 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 =3D + (struct insninfo *)malloc( + sizeof(struct insninfo)); + s->insn_addr =3D pc; + + sprintf(s->insn, " " TARGET_FMT_lx " ", pc); + s->next =3D insninfos; + insninfos =3D s; + } else { + fprintf(out, "0x" TARGET_FMT_lx ": ", pc); + } count =3D 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 =20 #include "qemu-common.h" +#include "exec/hwaddr.h" =20 #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; =20 +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[] =3D { "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 }, }; --=20 1.7.10.4