diff options
author | Alex Bennée <alex.bennee@linaro.org> | 2020-05-13 18:51:34 +0100 |
---|---|---|
committer | Alex Bennée <alex.bennee@linaro.org> | 2020-05-15 15:25:16 +0100 |
commit | 5f0df0333b20be816ae54a3fa6476f79f9da160e (patch) | |
tree | f38ea43cf96fed585bdf73beea3b0bda9589e485 | |
parent | 16b22e02b57e403568b471511e0b2a70789c94df (diff) |
translate-all: include guest address in out_asm output
We already have information about where each guest instructions
representation starts stored in the tcg_ctx->gen_insn_data so we can
rectify the PC for faults. We can re-use this information to annotate
the out_asm output with guest instruction address which makes it a bit
easier to work out where you are especially with longer blocks. A
minor wrinkle is that some instructions get optimised away so we have
to scan forward until we find some actual generated code.
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
Message-Id: <20200513175134.19619-11-alex.bennee@linaro.org>
-rw-r--r-- | accel/tcg/translate-all.c | 39 |
1 files changed, 33 insertions, 6 deletions
diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index cdf58bb420..42ce1dfcff 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -1794,14 +1794,43 @@ TranslationBlock *tb_gen_code(CPUState *cpu, if (qemu_loglevel_mask(CPU_LOG_TB_OUT_ASM) && qemu_log_in_addr_range(tb->pc)) { FILE *logfile = qemu_log_lock(); + int code_size, data_size = 0; + g_autoptr(GString) note = g_string_new("[tb header & initial instruction]"); + size_t chunk_start = 0; + int insn = 0; qemu_log("OUT: [size=%d]\n", gen_code_size); if (tcg_ctx->data_gen_ptr) { - size_t code_size = tcg_ctx->data_gen_ptr - tb->tc.ptr; - size_t data_size = gen_code_size - code_size; - size_t i; + code_size = tcg_ctx->data_gen_ptr - tb->tc.ptr; + data_size = gen_code_size - code_size; + } else { + code_size = gen_code_size; + } - log_disas(tb->tc.ptr, code_size, NULL); + /* Dump header and the first instruction */ + chunk_start = tcg_ctx->gen_insn_end_off[insn]; + log_disas(tb->tc.ptr, chunk_start, note->str); + /* + * Dump each instruction chunk, wrapping up empty chunks into + * the next instruction. The whole array is offset so the + * first entry is the beginning of the 2nd instruction. + */ + while (insn <= tb->icount && chunk_start < code_size) { + size_t chunk_end = tcg_ctx->gen_insn_end_off[insn]; + if (chunk_end > chunk_start) { + g_string_printf(note, "[guest addr: " TARGET_FMT_lx "]", + tcg_ctx->gen_insn_data[insn][0]); + log_disas(tb->tc.ptr + chunk_start, chunk_end - chunk_start, + note->str); + chunk_start = chunk_end; + } + insn++; + } + + /* Finally dump any data we may have after the block */ + if (data_size) { + int i; + qemu_log(" data: [size=%d]\n", data_size); for (i = 0; i < data_size; i += sizeof(tcg_target_ulong)) { if (sizeof(tcg_target_ulong) == 8) { qemu_log("0x%08" PRIxPTR ": .quad 0x%016" PRIx64 "\n", @@ -1813,8 +1842,6 @@ TranslationBlock *tb_gen_code(CPUState *cpu, *(uint32_t *)(tcg_ctx->data_gen_ptr + i)); } } - } else { - log_disas(tb->tc.ptr, gen_code_size, NULL); } qemu_log("\n"); qemu_log_flush(); |