From nobody Tue Nov 11 15:56:13 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=linaro.org ARC-Seal: i=1; a=rsa-sha256; t=1564416524; cv=none; d=zoho.com; s=zohoarc; b=EU4YOItzkSVVsVMRzm4PCh2WJU6hERchTTUDZbKy9bDGaugOBYus5Ykm4B/3lsx1wwDYq6HA2eNhJmdnaaSOxo6rRhrrrWsSIA1atO9Q19sgsJZk6jXpOL4l3wBiI5idsReILPOG0V2mws6ihqpnYPIQqaYZiyPl/5N1R7pBmRc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1564416524; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:To:ARC-Authentication-Results; bh=ru0uVFC6IiRmZ/DVA8Zz8x2lZ8Y/563+2G8UveOEwTk=; b=ESPXiOIYfBhseiuJjgkbfejP9bs2O8/r6a5sxgSdYqVhC98p2fjj3O/OcPNvMOHXnwZT7dAGqRfH3AnzethLJ1z6ZLCVSTXpW79zO9xPdVohDyLgk9lXG5KOxqcBjFAB8ru2THN5bk8KbixQw+Rk2EASLq8GiORVSi438K5IAuw= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1564416524980586.5195035094439; Mon, 29 Jul 2019 09:08:44 -0700 (PDT) Received: from localhost ([::1]:54866 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hs8CU-00005p-1p for importer@patchew.org; Mon, 29 Jul 2019 12:08:38 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:55346) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hs8Bl-0007pe-8A for qemu-devel@nongnu.org; Mon, 29 Jul 2019 12:07:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hs8Bj-0003Q7-IM for qemu-devel@nongnu.org; Mon, 29 Jul 2019 12:07:53 -0400 Received: from mail-wm1-x343.google.com ([2a00:1450:4864:20::343]:38798) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1hs8Bj-0003OA-90 for qemu-devel@nongnu.org; Mon, 29 Jul 2019 12:07:51 -0400 Received: by mail-wm1-x343.google.com with SMTP id s15so32611143wmj.3 for ; Mon, 29 Jul 2019 09:07:50 -0700 (PDT) Received: from zen.linaroharston ([81.128.185.34]) by smtp.gmail.com with ESMTPSA id f3sm44986225wrt.56.2019.07.29.09.07.48 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Mon, 29 Jul 2019 09:07:48 -0700 (PDT) Received: from zen.linaroharston. (localhost [127.0.0.1]) by zen.linaroharston (Postfix) with ESMTP id 6DBD61FF87; Mon, 29 Jul 2019 17:07:48 +0100 (BST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=ru0uVFC6IiRmZ/DVA8Zz8x2lZ8Y/563+2G8UveOEwTk=; b=H/mUt4ZlT52Hyepi1NFxh+fRDn36pELhHAi3/oN8MTSvZrCJDRBYFbJ3RsZucM1Tjf zaFhlUffDh1O49yH+l6R/k8atHCqOlZsCnhjytie4yMjWiIlLJq0/EuxL8Lpa4AEnszB qEjEK2IyMfIjeoeE2vtTNE8hHtseCOiHoWQB1vA7ydMq96jJNVv8OPHDkCuZDJhGmi+q X/P4WwNmrPRjRaROjOZR0fghgADR7GbJwdaX/4fHZ8XsSkdT+zvWdSLgSum8la6h/Iz2 pEgg/u2LGAKhoOAeT08WHl8xtMWIGmoFm+HMm3McF3O8dWalNKyZS712x6m26PY9LFYh cGpg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=ru0uVFC6IiRmZ/DVA8Zz8x2lZ8Y/563+2G8UveOEwTk=; b=t7v7D6zL1nLRASjuhzw69znIf8Zd+URTjjq0Dad3oeHFcwPbfYUj+rqB5q/+DR2e0x sg8QOKh3WrINH3UvUKLk5uqTtzeDfFmOWY6atr/avDztuFLLyitVgKE2be4xNN3wX0lk 6OKothk6YGuJrsFRqW5FtjAwut+7raCJ/xyWv2OQVt8f9/EFv8ckK0Z9IIDJNmU5e0Y2 VT8MSNqGKy/Yr9BuuJ3p8nK+DB6fz/PqUbJfyvpXcA472WHZaPtBVA7kRwh6j7XIPHZ6 N9PKL+dr6v5TmsrmAO3CbA7U3ve4kl/YROj7O0uwhxSo5J3gaRuuwyT3yzwE0zXDCucc PsiQ== X-Gm-Message-State: APjAAAWH3kyjASRrGVK9WnOxovwUczQc3kHG9MkehIO068mX9I3DuQo6 rSwjW/AREbGUe18FjPAUPb1AHw== X-Google-Smtp-Source: APXvYqyIPbjXBy6CJvNnpeTNXG3vfK5fc4NcakaFwuVBXlxUE/IUI6pn3Z10i6NEZ9JDTHGuUQKakQ== X-Received: by 2002:a7b:c0d0:: with SMTP id s16mr70540624wmh.141.1564416469420; Mon, 29 Jul 2019 09:07:49 -0700 (PDT) From: =?UTF-8?q?Alex=20Benn=C3=A9e?= To: qemu-devel@nongnu.org Date: Mon, 29 Jul 2019 17:07:29 +0100 Message-Id: <20190729160729.19927-1-alex.bennee@linaro.org> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::343 Subject: [Qemu-devel] [RFC PATCH] tcg: add annotations to dissembler output (RFC, HACK, PoC) X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: vandersonmr2@gmail.com, richard.henderson@linaro.org, qemu-arm@nongnu.org, Paolo Bonzini , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Sometimes it can be a bit tricky to line up the final host assembly with the instructions being translated. This is made harder by the fact disassembly is somewhat grafted into QEMU to support multiple dissemblers. Attempt to add more information to the output by: - tracking TCGNotes as we generate the code - using this to annotate lines of host disassembly UNRESOLVED ISSUES: We are duplicating some of the tracking done for INDEX_op_insn_start. We should probably merge and have a common system that can be used for: a) required stuff (insn bounderies, resolving registers on faults) b) nice debug info (which ops are loads/stores/splills) The hacking in of extra info into the disassembly stream if fugly. Signed-off-by: Alex Benn=C3=A9e --- accel/tcg/translate-all.c | 5 +++-- disas.c | 17 +++++++++-------- include/disas/disas.h | 4 +++- include/exec/log.h | 6 ++++-- tcg/tcg.c | 39 ++++++++++++++++++++++++++++++++++++--- tcg/tcg.h | 17 +++++++++++++++++ 6 files changed, 72 insertions(+), 16 deletions(-) diff --git a/accel/tcg/translate-all.c b/accel/tcg/translate-all.c index 0394e989d06..2f7ade495e2 100644 --- a/accel/tcg/translate-all.c +++ b/accel/tcg/translate-all.c @@ -1775,6 +1775,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, tb->cflags =3D cflags; tb->trace_vcpu_dstate =3D *cpu->trace_dstate; tcg_ctx->tb_cflags =3D cflags; + tcg_ctx->notes =3D g_array_set_size(tcg_ctx->notes, 0); tb_overflow: =20 #ifdef CONFIG_PROFILER @@ -1896,7 +1897,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, size_t data_size =3D gen_code_size - code_size; size_t i; =20 - log_disas(tb->tc.ptr, code_size); + log_disas(tb->tc.ptr, code_size, tcg_ctx); =20 for (i =3D 0; i < data_size; i +=3D sizeof(tcg_target_ulong)) { if (sizeof(tcg_target_ulong) =3D=3D 8) { @@ -1910,7 +1911,7 @@ TranslationBlock *tb_gen_code(CPUState *cpu, } } } else { - log_disas(tb->tc.ptr, gen_code_size); + log_disas(tb->tc.ptr, gen_code_size, tcg_ctx); } qemu_log("\n"); qemu_log_flush(); diff --git a/disas.c b/disas.c index c0f57284a43..edf4462846f 100644 --- a/disas.c +++ b/disas.c @@ -342,7 +342,7 @@ static bool cap_disas_target(disassemble_info *info, ui= nt64_t pc, size_t size) } =20 /* Disassemble SIZE bytes at CODE for the host. */ -static bool cap_disas_host(disassemble_info *info, void *code, size_t size) +static bool cap_disas_host(disassemble_info *info, void *code, size_t size= , void *opaque) { csh handle; const uint8_t *cbuf; @@ -359,6 +359,7 @@ static bool cap_disas_host(disassemble_info *info, void= *code, size_t size) =20 while (cs_disasm_iter(handle, &cbuf, &size, &pc, insn)) { cap_dump_insn(info, insn); + tcg_disas_annotation(stderr, opaque, pc); } if (size !=3D 0) { (*info->fprintf_func)(info->stream, @@ -416,7 +417,7 @@ static bool cap_disas_monitor(disassemble_info *info, u= int64_t pc, int count) #endif /* !CONFIG_USER_ONLY */ #else # define cap_disas_target(i, p, s) false -# define cap_disas_host(i, p, s) false +# define cap_disas_host(i, p, s, o) false # define cap_disas_monitor(i, p, c) false #endif /* CONFIG_CAPSTONE */ =20 @@ -462,7 +463,6 @@ void target_disas(FILE *out, CPUState *cpu, target_ulon= g code, for (pc =3D code; size > 0; pc +=3D count, size -=3D count) { fprintf(out, "0x" TARGET_FMT_lx ": ", pc); count =3D s.info.print_insn(pc, &s.info); - fprintf(out, "\n"); if (count < 0) break; if (size < count) { @@ -477,7 +477,7 @@ void target_disas(FILE *out, CPUState *cpu, target_ulon= g code, =20 =20 /* Disassemble this for me please... (debugging). */ -void disas(FILE *out, void *code, unsigned long size) +void disas(FILE *out, void *code, unsigned long size, void *opaque) { uintptr_t pc; int count; @@ -555,7 +555,7 @@ void disas(FILE *out, void *code, unsigned long size) print_insn =3D print_insn_hppa; #endif =20 - if (s.info.cap_arch >=3D 0 && cap_disas_host(&s.info, code, size)) { + if (s.info.cap_arch >=3D 0 && cap_disas_host(&s.info, code, size, opaq= ue)) { return; } =20 @@ -565,9 +565,10 @@ void disas(FILE *out, void *code, unsigned long size) for (pc =3D (uintptr_t)code; size > 0; pc +=3D count, size -=3D count)= { fprintf(out, "0x%08" PRIxPTR ": ", pc); count =3D print_insn(pc, &s.info); - fprintf(out, "\n"); - if (count < 0) - break; + tcg_disas_annotation(out, opaque, pc); + fprintf(out, "\n"); + if (count < 0) + break; } } =20 diff --git a/include/disas/disas.h b/include/disas/disas.h index 15da511f49c..c2f75c759f1 100644 --- a/include/disas/disas.h +++ b/include/disas/disas.h @@ -5,8 +5,10 @@ #ifdef NEED_CPU_H #include "cpu.h" =20 +void tcg_disas_annotation(FILE *out, void *opaque, uintptr_t pc); + /* Disassemble this for me please... (debugging). */ -void disas(FILE *out, void *code, unsigned long size); +void disas(FILE *out, void *code, unsigned long size, void *s); void target_disas(FILE *out, CPUState *cpu, target_ulong code, target_ulong size); =20 diff --git a/include/exec/log.h b/include/exec/log.h index de067f173b8..9fe239fa8c3 100644 --- a/include/exec/log.h +++ b/include/exec/log.h @@ -43,11 +43,13 @@ static inline void log_target_disas(CPUState *cpu, targ= et_ulong start, target_disas(qemu_logfile, cpu, start, len); } =20 -static inline void log_disas(void *code, unsigned long size) +static inline void log_disas(void *code, unsigned long size, void *s) { - disas(qemu_logfile, code, size); + disas(qemu_logfile, code, size, s); } =20 +void tcg_disas_annotation(FILE *out, void *opaque, uintptr_t pc); + #if defined(CONFIG_USER_ONLY) /* page_dump() output to the log file: */ static inline void log_page_dump(void) diff --git a/tcg/tcg.c b/tcg/tcg.c index 46b31a2f68b..301408ff511 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -781,6 +781,8 @@ void tcg_register_thread(void) g_assert(n < ms->smp.max_cpus); atomic_set(&tcg_ctxs[n], s); =20 + s->notes =3D g_array_new(true, false, sizeof(TCGNote)); + tcg_ctx =3D s; qemu_mutex_lock(®ion.lock); err =3D tcg_region_initial_alloc__locked(tcg_ctx); @@ -977,6 +979,8 @@ void tcg_context_init(TCGContext *s) indirect_reg_alloc_order[i] =3D tcg_target_reg_alloc_order[i]; } =20 + s->notes =3D g_array_new(true, false, sizeof(TCGNote)); + tcg_ctx =3D s; /* * In user-mode we simply share the init context among threads, since = we @@ -1078,7 +1082,7 @@ void tcg_prologue_init(TCGContext *s) size_t data_size =3D prologue_size - code_size; size_t i; =20 - log_disas(buf0, code_size); + log_disas(buf0, code_size, s); =20 for (i =3D 0; i < data_size; i +=3D sizeof(tcg_target_ulong)) { if (sizeof(tcg_target_ulong) =3D=3D 8) { @@ -1092,7 +1096,7 @@ void tcg_prologue_init(TCGContext *s) } } } else { - log_disas(buf0, prologue_size); + log_disas(buf0, prologue_size, s); } qemu_log("\n"); qemu_log_flush(); @@ -3124,6 +3128,10 @@ static void temp_sync(TCGContext *s, TCGTemp *ts, TC= GRegSet allocated_regs, /* fallthrough */ =20 case TEMP_VAL_REG: + { + TCGNote n =3D { REGISTER_SPILL, s->code_ptr }; + g_array_append_val(s->notes, n); + =20 tcg_out_st(s, ts->type, ts->reg, ts->mem_base->reg, ts->mem_offset); =20 @@ -3132,7 +3140,7 @@ static void temp_sync(TCGContext *s, TCGTemp *ts, TCG= RegSet allocated_regs, atomic_inc(&s->current_tb->tb_stats->code.spills); } break; - + } case TEMP_VAL_MEM: break; =20 @@ -4133,6 +4141,9 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) tcg_reg_alloc_dup(s, op); break; case INDEX_op_insn_start: + { + TCGNote n =3D { INSN_START, s->code_ptr }; + g_array_append_val(s->notes, n); if (num_insns >=3D 0) { size_t off =3D tcg_current_code_size(s); s->gen_insn_end_off[num_insns] =3D off; @@ -4150,6 +4161,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) s->gen_insn_data[num_insns][i] =3D a; } break; + } case INDEX_op_discard: temp_dead(s, arg_temp(op->args[0])); break; @@ -4221,6 +4233,27 @@ void tcg_dump_info(void) dump_jit_profile_info(s); } =20 +void tcg_disas_annotation(FILE *out, void *opaque, uintptr_t pc) +{ + TCGContext *s =3D (TCGContext *) opaque; + int i; + + for (i =3D 0; i < s->notes->len; i++) { + TCGNote *n =3D &g_array_index(s->notes, TCGNote, i); + if (n->start =3D=3D (tcg_insn_unit *) pc) { + switch (n->e) { + case INSN_START: + fprintf(out, "\tinsn"); + break; + case REGISTER_SPILL: + fprintf(out, "\tspill"); + break; + } + } + } +} + + #ifdef ELF_HOST_MACHINE /* In order to use this feature, the backend needs to do three things: =20 diff --git a/tcg/tcg.h b/tcg/tcg.h index 026a066b9a1..b4fcf7f7170 100644 --- a/tcg/tcg.h +++ b/tcg/tcg.h @@ -653,6 +653,21 @@ typedef struct TCGProfile { int64_t table_op_count[NB_OPS]; } TCGProfile; =20 +/* + * TCGNote entries are used to track points in the outgoing instruction st= ream + * for better debug output. + */ + +typedef enum { + INSN_START, + REGISTER_SPILL +} TCGEvent; + +typedef struct { + TCGEvent e; + tcg_insn_unit *start; +} TCGNote; + struct TCGContext { uint8_t *pool_cur, *pool_end; TCGPool *pool_first, *pool_current, *pool_first_large; @@ -687,6 +702,8 @@ struct TCGContext { const TCGOpcode *vecop_list; #endif =20 + GArray *notes; + /* Code generation. Note that we specifically do not use tcg_insn_unit here, because there's too much arithmetic throughout that relies on addition and subtraction working on bytes. Rely on the GCC --=20 2.20.1