From nobody Tue May 7 16:10:13 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.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 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510057463659746.0904548625558; Tue, 7 Nov 2017 04:24:23 -0800 (PST) Received: from localhost ([::1]:52956 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eC2vJ-0007h2-Nj for importer@patchew.org; Tue, 07 Nov 2017 07:24:09 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41873) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eC2uQ-0007N6-8H for qemu-devel@nongnu.org; Tue, 07 Nov 2017 07:23:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eC2uG-0004md-7l for qemu-devel@nongnu.org; Tue, 07 Nov 2017 07:23:14 -0500 Received: from mail-wr0-x243.google.com ([2a00:1450:400c:c0c::243]:50166) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eC2uF-0004ld-VZ for qemu-devel@nongnu.org; Tue, 07 Nov 2017 07:23:04 -0500 Received: by mail-wr0-x243.google.com with SMTP id o88so838068wrb.6 for ; Tue, 07 Nov 2017 04:23:03 -0800 (PST) Received: from cloudburst.local (tmo-097-15.customers.d1-online.com. [80.187.97.15]) by smtp.gmail.com with ESMTPSA id 10sm1078645wml.27.2017.11.07.04.23.01 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 07 Nov 2017 04:23:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=bfAQ2yQr6PvXFnkTZcTggGt9Hq3L4y7mdonLePtVO7c=; b=HyREKu6AMXdLqiW8OqhB64SU8EvoJ8Ijs+eTk/BfZZEkjeY3eqPilYj7PEsXteF75k vO6Zwvr7wPvfaH2BEOxfz0jV1K+n2JiibDE8pEDx9vhTUCsgsDom39zy1BBmJZEmD75H YWHnJIgZvabHnQoADPILx1aQ47ffl9KlxcIrU= 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; bh=bfAQ2yQr6PvXFnkTZcTggGt9Hq3L4y7mdonLePtVO7c=; b=f9GXuO8ezXhP6i2dzK8HdYVomS4c+MvFDEMsT0+4uy3FCm78D/EyYUNw8kmCKywiH6 PI+eaaLrFhvSGFd4CFuNLJdbe3TkfqoK4StNiiR9Bz+xvRdTIpauLeL6/loupyAx6ixE oo672C3aLbrQpWs6m4Wc21j6gXD7sctK3iqKT+i9WnFNjeGrSlh/CyeRFkYJioEYlIdC AUN1BCqonoKRM6CqcEyM1QLXNfe6//ooM4eJpba56+KkOIPbVyn49cHgKfOdZe6iLh9K NbE/0nwCk/2ExBi8dl/CcCcgE84eQCLuSXM39dyjP4qOB/NUOZvkxC8PPS0y3RjlCQ1O 4inw== X-Gm-Message-State: AMCzsaVHodkDdXfm4Qb0Nz+/j9YsVgeHYbtu+eHUb/LZhLfvGZBofROZ ulIGhojH5aLCtKe1PZDw8e1XG3zQDdOemQ== X-Google-Smtp-Source: ABhQp+SBZ8/+w5Xd8KPgkgXi+Mj6Mkv25pad5Yr2lcSPtwLY+ZTZi3qe9qwW5v7yYKvn4zQPyadh3Q== X-Received: by 10.223.136.170 with SMTP id f39mr13624158wrf.162.1510057382380; Tue, 07 Nov 2017 04:23:02 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Tue, 7 Nov 2017 13:22:34 +0100 Message-Id: <20171107122234.8439-1-richard.henderson@linaro.org> X-Mailer: git-send-email 2.13.6 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::243 Subject: [Qemu-devel] [PATCH] disas: Dump insn bytes along with capstone disassembly X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This feature is present for some targets in the bfd disassembler(s). Implement it generically for all capstone users. Suggested-by: Peter Maydell Signed-off-by: Richard Henderson --- include/disas/bfd.h | 2 ++ disas.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++---= ---- target/arm/cpu.c | 6 ++++ target/i386/cpu.c | 2 ++ 4 files changed, 94 insertions(+), 12 deletions(-) diff --git a/include/disas/bfd.h b/include/disas/bfd.h index 1f88c9e9d5..46c7ec3376 100644 --- a/include/disas/bfd.h +++ b/include/disas/bfd.h @@ -374,6 +374,8 @@ typedef struct disassemble_info { /* Options for Capstone disassembly. */ int cap_arch; int cap_mode; + int cap_insn_unit; + int cap_insn_split; =20 } disassemble_info; =20 diff --git a/disas.c b/disas.c index 92b389d25f..d4ad1089ef 100644 --- a/disas.c +++ b/disas.c @@ -220,6 +220,77 @@ static cs_err cap_disas_start(disassemble_info *info, = csh *handle) return CS_ERR_OK; } =20 +static void cap_dump_insn_units(disassemble_info *info, cs_insn *insn, + int i, int n) +{ + fprintf_function print =3D info->fprintf_func; + FILE *stream =3D info->stream; + + switch (info->cap_insn_unit) { + case 4: + if (info->endian =3D=3D BFD_ENDIAN_BIG) { + for (; i < n; i +=3D 4) { + print(stream, " %08x", ldl_be_p(insn->bytes + i)); + + } + } else { + for (; i < n; i +=3D 4) { + print(stream, " %08x", ldl_le_p(insn->bytes + i)); + } + } + break; + + case 2: + if (info->endian =3D=3D BFD_ENDIAN_BIG) { + for (; i < n; i +=3D 2) { + print(stream, " %04x", lduw_be_p(insn->bytes + i)); + } + } else { + for (; i < n; i +=3D 2) { + print(stream, " %04x", lduw_le_p(insn->bytes + i)); + } + } + break; + + default: + for (; i < n; i++) { + print(stream, " %02x", insn->bytes[i]); + } + break; + } +} + +static void cap_dump_insn(disassemble_info *info, cs_insn *insn) +{ + fprintf_function print =3D info->fprintf_func; + int i, n, split; + + print(info->stream, "0x%08" PRIx64 ": ", insn->address); + + n =3D insn->size; + split =3D info->cap_insn_split; + + /* Dump the first SPLIT bytes of the instruction. */ + cap_dump_insn_units(info, insn, 0, MIN(n, split)); + + /* Add padding up to SPLIT so that mnemonics line up. */ + if (n < split) { + int width =3D (split - n) / info->cap_insn_unit; + width *=3D (2 * info->cap_insn_unit + 1); + print(info->stream, "%*s", width, ""); + } + + /* Print the actual instruction. */ + print(info->stream, " %-8s %s\n", insn->mnemonic, insn->op_str); + + /* Dump any remaining part of the insn on subsequent lines. */ + for (i =3D split; i < n; i +=3D split) { + print(info->stream, "0x%08" PRIx64 ": ", insn->address + i); + cap_dump_insn_units(info, insn, i, MIN(n, i + split)); + print(info->stream, "\n"); + } +} + /* Disassemble SIZE bytes at PC for the target. */ static bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t s= ize) { @@ -242,10 +313,7 @@ static bool cap_disas_target(disassemble_info *info, u= int64_t pc, size_t size) size -=3D tsize; =20 while (cs_disasm_iter(handle, &cbuf, &csize, &pc, insn)) { - (*info->fprintf_func)(info->stream, - "0x%08" PRIx64 ": %-12s %s\n", - insn->address, insn->mnemonic, - insn->op_str); + cap_dump_insn(info, insn); } =20 /* If the target memory is not consumed, go back for more... */ @@ -290,10 +358,7 @@ static bool cap_disas_host(disassemble_info *info, voi= d *code, size_t size) pc =3D (uintptr_t)code; =20 while (cs_disasm_iter(handle, &cbuf, &size, &pc, insn)) { - (*info->fprintf_func)(info->stream, - "0x%08" PRIx64 ": %-12s %s\n", - insn->address, insn->mnemonic, - insn->op_str); + cap_dump_insn(info, insn); } if (size !=3D 0) { (*info->fprintf_func)(info->stream, @@ -337,10 +402,7 @@ static bool cap_disas_monitor(disassemble_info *info, = uint64_t pc, int count) csize +=3D tsize; =20 if (cs_disasm_iter(handle, &cbuf, &csize, &pc, insn)) { - (*info->fprintf_func)(info->stream, - "0x%08" PRIx64 ": %-12s %s\n", - insn->address, insn->mnemonic, - insn->op_str); + cap_dump_insn(info, insn); if (--count <=3D 0) { break; } @@ -376,6 +438,8 @@ void target_disas(FILE *out, CPUState *cpu, target_ulon= g code, s.info.print_address_func =3D generic_print_address; s.info.cap_arch =3D -1; s.info.cap_mode =3D 0; + s.info.cap_insn_unit =3D 4; + s.info.cap_insn_split =3D 4; =20 #ifdef TARGET_WORDS_BIGENDIAN s.info.endian =3D BFD_ENDIAN_BIG; @@ -427,6 +491,8 @@ void disas(FILE *out, void *code, unsigned long size) s.info.buffer_length =3D size; s.info.cap_arch =3D -1; s.info.cap_mode =3D 0; + s.info.cap_insn_unit =3D 4; + s.info.cap_insn_split =3D 4; =20 #ifdef HOST_WORDS_BIGENDIAN s.info.endian =3D BFD_ENDIAN_BIG; @@ -440,11 +506,15 @@ void disas(FILE *out, void *code, unsigned long size) print_insn =3D print_insn_i386; s.info.cap_arch =3D CS_ARCH_X86; s.info.cap_mode =3D CS_MODE_32; + s.info.cap_insn_unit =3D 1; + s.info.cap_insn_split =3D 8; #elif defined(__x86_64__) s.info.mach =3D bfd_mach_x86_64; print_insn =3D print_insn_i386; s.info.cap_arch =3D CS_ARCH_X86; s.info.cap_mode =3D CS_MODE_64; + s.info.cap_insn_unit =3D 1; + s.info.cap_insn_split =3D 8; #elif defined(_ARCH_PPC) s.info.disassembler_options =3D (char *)"any"; print_insn =3D print_insn_ppc; @@ -537,6 +607,8 @@ void monitor_disas(Monitor *mon, CPUState *cpu, s.info.buffer_vma =3D pc; s.info.cap_arch =3D -1; s.info.cap_mode =3D 0; + s.info.cap_insn_unit =3D 4; + s.info.cap_insn_split =3D 4; =20 #ifdef TARGET_WORDS_BIGENDIAN s.info.endian =3D BFD_ENDIAN_BIG; diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 47c8b2a85c..7f7a3d1e32 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -489,13 +489,19 @@ static void arm_disas_set_info(CPUState *cpu, disasse= mble_info *info) info->print_insn =3D print_insn_arm_a64; #endif info->cap_arch =3D CS_ARCH_ARM64; + info->cap_insn_unit =3D 4; + info->cap_insn_split =3D 4; } else { int cap_mode; if (env->thumb) { info->print_insn =3D print_insn_thumb1; + info->cap_insn_unit =3D 2; + info->cap_insn_split =3D 4; cap_mode =3D CS_MODE_THUMB; } else { info->print_insn =3D print_insn_arm; + info->cap_insn_unit =3D 4; + info->cap_insn_split =3D 4; cap_mode =3D CS_MODE_ARM; } if (arm_feature(env, ARM_FEATURE_V8)) { diff --git a/target/i386/cpu.c b/target/i386/cpu.c index 6f21a5e518..1edcf29e27 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -4109,6 +4109,8 @@ static void x86_disas_set_info(CPUState *cs, disassem= ble_info *info) info->cap_mode =3D (env->hflags & HF_CS64_MASK ? CS_MODE_64 : env->hflags & HF_CS32_MASK ? CS_MODE_32 : CS_MODE_16); + info->cap_insn_unit =3D 1; + info->cap_insn_split =3D 8; } =20 static Property x86_cpu_properties[] =3D { --=20 2.13.6