From patchwork Sat Feb 8 15:57:59 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 24373 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-pa0-f70.google.com (mail-pa0-f70.google.com [209.85.220.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id A599B20967 for ; Sat, 8 Feb 2014 16:14:41 +0000 (UTC) Received: by mail-pa0-f70.google.com with SMTP id kq14sf9384153pab.9 for ; Sat, 08 Feb 2014 08:14:40 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:date :message-id:in-reply-to:references:cc:subject:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:list-subscribe :errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=jY9E14kF72Dh1Gi2046UCdGTsLbOXK1ERU0+IidIbRA=; b=PgKpaRPwdno7yWiXLBgdZUy3NjeQ0QNI3u+becSAEDEXoQb27AZZVvoD57dFWU0P6K vUP+wP1j0vmDZaoaRwQ1ENvvUFno+YatsetKG+hHJT11Li1ocDO0o6sC7/RGLO7FuS6C /ZeLb8x2uDYSdelD9KptLL4a5I45r64KQaMLloiRvLkagUsM8WiQ/upv9QGymWsSafvt JMYqFD7pDcehPMtuSdC4p7XXTBD+BS3IwRU63U4FUt5GOiXsuDuUC40JJPSn0QtBIZgC jBEr88oR1EPAXhMuNf0gnzK6RWErSYYjFGZgKNA/KSPQYgYrwzK1ZukM82QdYpGxlDzo gBog== X-Gm-Message-State: ALoCoQnDsXHn5eC5TF3K8+6P3gVrjY5DHlI3sJodyY6O4Nz47VAhVpzsK4bcLo8zWbce2fY2TTKb X-Received: by 10.69.16.98 with SMTP id fv2mr8414927pbd.7.1391876080518; Sat, 08 Feb 2014 08:14:40 -0800 (PST) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.30.8 with SMTP id c8ls1524943qgc.56.gmail; Sat, 08 Feb 2014 08:14:40 -0800 (PST) X-Received: by 10.220.10.2 with SMTP id n2mr1140822vcn.26.1391876080429; Sat, 08 Feb 2014 08:14:40 -0800 (PST) Received: from mail-ve0-f180.google.com (mail-ve0-f180.google.com [209.85.128.180]) by mx.google.com with ESMTPS id tt2si2632098vdc.61.2014.02.08.08.14.40 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sat, 08 Feb 2014 08:14:40 -0800 (PST) Received-SPF: neutral (google.com: 209.85.128.180 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.128.180; Received: by mail-ve0-f180.google.com with SMTP id db12so3795945veb.11 for ; Sat, 08 Feb 2014 08:14:40 -0800 (PST) X-Received: by 10.52.30.167 with SMTP id t7mr406420vdh.36.1391876080329; Sat, 08 Feb 2014 08:14:40 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.174.196 with SMTP id u4csp41145vcz; Sat, 8 Feb 2014 08:14:39 -0800 (PST) X-Received: by 10.140.27.179 with SMTP id 48mr30187995qgx.18.1391876079563; Sat, 08 Feb 2014 08:14:39 -0800 (PST) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id ew5si6188649qab.7.2014.02.08.08.14.39 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Sat, 08 Feb 2014 08:14:39 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Received: from localhost ([::1]:47164 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WCAYB-0007He-3Q for patch@linaro.org; Sat, 08 Feb 2014 11:14:39 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47343) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WCAIf-0007vI-TO for qemu-devel@nongnu.org; Sat, 08 Feb 2014 10:58:39 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WCAIe-00030z-E0 for qemu-devel@nongnu.org; Sat, 08 Feb 2014 10:58:37 -0500 Received: from mnementh.archaic.org.uk ([2001:8b0:1d0::1]:45685) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WCAIe-00030p-3l for qemu-devel@nongnu.org; Sat, 08 Feb 2014 10:58:36 -0500 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1WCAI9-0003M0-Q7; Sat, 08 Feb 2014 15:58:05 +0000 From: Peter Maydell To: Anthony Liguori Date: Sat, 8 Feb 2014 15:57:59 +0000 Message-Id: <1391875084-12772-25-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1391875084-12772-1-git-send-email-peter.maydell@linaro.org> References: <1391875084-12772-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:8b0:1d0::1 Cc: Blue Swirl , qemu-devel@nongnu.org, Aurelien Jarno Subject: [Qemu-devel] [PULL 24/29] disas: Implement disassembly output for A64 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.128.180 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 From: Claudio Fontana Use libvixl to implement disassembly output in debug logs for A64, for use with both AArch64 hosts and targets. Signed-off-by: Claudio Fontana [PMM: * added support for target disassembly * switched to custom QEMUDisassembler so the output format matches what QEMU expects * make sure we correctly fall back to "just print hex" if we didn't build the AArch64 disassembler because of lack of a C++ compiler * rename from 'aarch64' to 'arm-a64' because this is a disassembler for the A64 instruction set * merge aarch64.c and aarch64-cxx.cc into one C++ file * simplify the aarch64.c<->aarch64-cxx.cc interface] Signed-off-by: Peter Maydell --- configure | 4 +++ disas.c | 14 ++++++-- disas/Makefile.objs | 5 +++ disas/arm-a64.cc | 87 +++++++++++++++++++++++++++++++++++++++++++++ disas/libvixl/Makefile.objs | 8 +++++ include/disas/bfd.h | 1 + target-arm/translate-a64.c | 2 +- 7 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 disas/arm-a64.cc create mode 100644 disas/libvixl/Makefile.objs diff --git a/configure b/configure index 236764a..8f3cc20 100755 --- a/configure +++ b/configure @@ -4641,6 +4641,10 @@ for i in $ARCH $TARGET_BASE_ARCH ; do arm) echo "CONFIG_ARM_DIS=y" >> $config_target_mak echo "CONFIG_ARM_DIS=y" >> config-all-disas.mak + if test -n "${cxx}"; then + echo "CONFIG_ARM_A64_DIS=y" >> $config_target_mak + echo "CONFIG_ARM_A64_DIS=y" >> config-all-disas.mak + fi ;; cris) echo "CONFIG_CRIS_DIS=y" >> $config_target_mak diff --git a/disas.c b/disas.c index 0203ef2..79e6944 100644 --- a/disas.c +++ b/disas.c @@ -190,7 +190,7 @@ static int print_insn_od_target(bfd_vma pc, disassemble_info *info) /* Disassemble this for me please... (debugging). 'flags' has the following values: i386 - 1 means 16 bit code, 2 means 64 bit code - arm - bit 0 = thumb, bit 1 = reverse endian + arm - bit 0 = thumb, bit 1 = reverse endian, bit 2 = A64 ppc - nonzero means little endian other targets - unused */ @@ -225,7 +225,15 @@ void target_disas(FILE *out, CPUArchState *env, target_ulong code, } print_insn = print_insn_i386; #elif defined(TARGET_ARM) - if (flags & 1) { + if (flags & 4) { + /* We might not be compiled with the A64 disassembler + * because it needs a C++ compiler; in that case we will + * fall through to the default print_insn_od case. + */ +#if defined(CONFIG_ARM_A64_DIS) + print_insn = print_insn_arm_a64; +#endif + } else if (flags & 1) { print_insn = print_insn_thumb1; } else { print_insn = print_insn_arm; @@ -356,6 +364,8 @@ void disas(FILE *out, void *code, unsigned long size) #elif defined(_ARCH_PPC) s.info.disassembler_options = (char *)"any"; print_insn = print_insn_ppc; +#elif defined(__aarch64__) && defined(CONFIG_ARM_A64_DIS) + print_insn = print_insn_arm_a64; #elif defined(__alpha__) print_insn = print_insn_alpha; #elif defined(__sparc__) diff --git a/disas/Makefile.objs b/disas/Makefile.objs index 3b1e77a..41c2374 100644 --- a/disas/Makefile.objs +++ b/disas/Makefile.objs @@ -1,5 +1,10 @@ + common-obj-$(CONFIG_ALPHA_DIS) += alpha.o common-obj-$(CONFIG_ARM_DIS) += arm.o +common-obj-$(CONFIG_ARM_A64_DIS) += arm-a64.o +common-obj-$(CONFIG_ARM_A64_DIS) += libvixl/ +libvixldir = $(SRC_PATH)/disas/libvixl +$(obj)/arm-a64.o: QEMU_CFLAGS += -I$(libvixldir) common-obj-$(CONFIG_CRIS_DIS) += cris.o common-obj-$(CONFIG_HPPA_DIS) += hppa.o common-obj-$(CONFIG_I386_DIS) += i386.o diff --git a/disas/arm-a64.cc b/disas/arm-a64.cc new file mode 100644 index 0000000..162be0c --- /dev/null +++ b/disas/arm-a64.cc @@ -0,0 +1,87 @@ +/* + * ARM A64 disassembly output wrapper to libvixl + * Copyright (c) 2013 Linaro Limited + * Written by Claudio Fontana + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "a64/disasm-a64.h" + +extern "C" { +#include "disas/bfd.h" +} + +using namespace vixl; + +static Decoder *vixl_decoder = NULL; +static Disassembler *vixl_disasm = NULL; + +/* We don't use libvixl's PrintDisassembler because its output + * is a little unhelpful (trailing newlines, for example). + * Instead we use our own very similar variant so we have + * control over the format. + */ +class QEMUDisassembler : public Disassembler { +public: + explicit QEMUDisassembler(FILE *stream) : stream_(stream) { } + ~QEMUDisassembler() { } + +protected: + void ProcessOutput(Instruction *instr) { + fprintf(stream_, "%08" PRIx32 " %s", + instr->InstructionBits(), GetOutput()); + } + +private: + FILE *stream_; +}; + +static int vixl_is_initialized(void) +{ + return vixl_decoder != NULL; +} + +static void vixl_init(FILE *f) { + vixl_decoder = new Decoder(); + vixl_disasm = new QEMUDisassembler(f); + vixl_decoder->AppendVisitor(vixl_disasm); +} + +#define INSN_SIZE 4 + +/* Disassemble ARM A64 instruction. This is our only entry + * point from QEMU's C code. + */ +int print_insn_arm_a64(uint64_t addr, disassemble_info *info) +{ + uint8_t bytes[INSN_SIZE]; + uint32_t instr; + int status; + + status = info->read_memory_func(addr, bytes, INSN_SIZE, info); + if (status != 0) { + info->memory_error_func(status, addr, info); + return -1; + } + + if (!vixl_is_initialized()) { + vixl_init(info->stream); + } + + instr = bytes[0] | bytes[1] << 8 | bytes[2] << 16 | bytes[3] << 24; + vixl_decoder->Decode(reinterpret_cast(&instr)); + + return INSN_SIZE; +} diff --git a/disas/libvixl/Makefile.objs b/disas/libvixl/Makefile.objs new file mode 100644 index 0000000..0adb3ce --- /dev/null +++ b/disas/libvixl/Makefile.objs @@ -0,0 +1,8 @@ +libvixl_OBJS = utils.o \ + a64/instructions-a64.o \ + a64/decoder-a64.o \ + a64/disasm-a64.o + +$(addprefix $(obj)/,$(libvixl_OBJS)): QEMU_CFLAGS += -I$(SRC_PATH)/disas/libvixl + +common-obj-$(CONFIG_ARM_A64_DIS) += $(libvixl_OBJS) diff --git a/include/disas/bfd.h b/include/disas/bfd.h index 803b6ef..8bd703c 100644 --- a/include/disas/bfd.h +++ b/include/disas/bfd.h @@ -379,6 +379,7 @@ int print_insn_h8300 (bfd_vma, disassemble_info*); int print_insn_h8300h (bfd_vma, disassemble_info*); int print_insn_h8300s (bfd_vma, disassemble_info*); int print_insn_h8500 (bfd_vma, disassemble_info*); +int print_insn_arm_a64 (bfd_vma, disassemble_info*); int print_insn_alpha (bfd_vma, disassemble_info*); disassembler_ftype arc_get_disassembler (int, int); int print_insn_arm (bfd_vma, disassemble_info*); diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 5698b3e..d60223a 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -8105,7 +8105,7 @@ done_generating: qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); log_target_disas(env, pc_start, dc->pc - pc_start, - dc->thumb | (dc->bswap_code << 1)); + 4 | (dc->bswap_code << 1)); qemu_log("\n"); } #endif