From patchwork Thu Oct 1 16:35:44 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 8905 Received: (qmail 8527 invoked by alias); 1 Oct 2015 16:36:02 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 8154 invoked by uid 89); 1 Oct 2015 16:35:58 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mail-pa0-f42.google.com Received: from mail-pa0-f42.google.com (HELO mail-pa0-f42.google.com) (209.85.220.42) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Thu, 01 Oct 2015 16:35:54 +0000 Received: by pacfv12 with SMTP id fv12so80791978pac.2; Thu, 01 Oct 2015 09:35:52 -0700 (PDT) X-Received: by 10.66.139.201 with SMTP id ra9mr13253544pab.153.1443717352432; Thu, 01 Oct 2015 09:35:52 -0700 (PDT) Received: from E107787-LIN.cambridge.arm.com (power-aix.osuosl.org. [140.211.15.154]) by smtp.gmail.com with ESMTPSA id bs3sm7555970pbd.89.2015.10.01.09.35.51 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 01 Oct 2015 09:35:51 -0700 (PDT) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org, binutils@sourceware.org Subject: [PATCH 2/2] [aarch64] Use opcodes to decode instructions in GDB Date: Thu, 1 Oct 2015 17:35:44 +0100 Message-Id: <1443717344-8632-3-git-send-email-yao.qi@linaro.org> In-Reply-To: <1443717344-8632-1-git-send-email-yao.qi@linaro.org> References: <1443717344-8632-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes I just noticed that opcodes, at least in aarch64, exposes some good interface to decode instructions. It is good for GDB to use them rather than reinventing the wheel. In this patch, I expose disas_aarch64_insn in opcodes, and use it in aarch64_software_single_step to decode instructions. If this is a good way to go, I'll continue using disas_aarch64_insn in other places such as prologue analysis and even fast tracepoint in GDBserver. Regression tested GDB for target aarch64-linux-gnu. Is opcodes change OK? opcodes: 2015-10-01 Yao Qi * aarch64-dis.c (disas_aarch64_insn): Make it external. Update comments. * aarch64-dis.h (disas_aarch64_insn): Declare it. gdb: 2015-10-01 Yao Qi * aarch64-tdep.c: Include opcodes/aarch64-dis.h. (submask): Move it above. (bit): Likewise. (bits): Likewise. (aarch64_software_single_step): Call disas_aarch64_insn. Decode instruction by aarch64_inst instead of using aarch64_decode_bcond. --- gdb/aarch64-tdep.c | 29 ++++++++++++++++++----------- opcodes/aarch64-dis.c | 4 ++-- opcodes/aarch64-dis.h | 5 +++++ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 5b5e1ad..25a8446 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -59,6 +59,12 @@ #include "arch/aarch64-insn.h" +#include "opcodes/aarch64-dis.h" + +#define submask(x) ((1L << ((x) + 1)) - 1) +#define bit(obj,st) (((obj) >> (st)) & 1) +#define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st))) + /* Pseudo register base numbers. */ #define AARCH64_Q0_REGNUM 0 #define AARCH64_D0_REGNUM (AARCH64_Q0_REGNUM + 32) @@ -2491,35 +2497,40 @@ aarch64_software_single_step (struct frame_info *frame) int insn_count; int bc_insn_count = 0; /* Conditional branch instruction count. */ int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */ + aarch64_inst inst; + + if (disas_aarch64_insn (insn, &inst) != 0) + return 0; /* Look for a Load Exclusive instruction which begins the sequence. */ - if (!decode_masked_match (insn, 0x3fc00000, 0x08400000)) + if (inst.opcode->iclass != ldstexcl || bit (insn, 22) == 0) return 0; for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count) { - int32_t offset; - unsigned cond; - loc += insn_size; insn = read_memory_unsigned_integer (loc, insn_size, byte_order_for_code); + if (disas_aarch64_insn (insn, &inst) != 0) + return 0; /* Check if the instruction is a conditional branch. */ - if (aarch64_decode_bcond (loc, insn, &cond, &offset)) + if (inst.opcode->iclass == condbranch) { + gdb_assert (inst.operands[0].type == AARCH64_OPND_ADDR_PCREL19); + if (bc_insn_count >= 1) return 0; /* It is, so we'll try to set a breakpoint at the destination. */ - breaks[1] = loc + offset; + breaks[1] = loc + inst.operands[0].imm.value; bc_insn_count++; last_breakpoint++; } /* Look for the Store Exclusive which closes the atomic sequence. */ - if (decode_masked_match (insn, 0x3fc00000, 0x08000000)) + if (inst.opcode->iclass == ldstexcl && bit (insn, 22) == 0) { closing_insn = loc; break; @@ -2771,10 +2782,6 @@ When on, AArch64 specific debugging is enabled."), /* AArch64 process record-replay related structures, defines etc. */ -#define submask(x) ((1L << ((x) + 1)) - 1) -#define bit(obj,st) (((obj) >> (st)) & 1) -#define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st))) - #define REG_ALLOC(REGS, LENGTH, RECORD_BUF) \ do \ { \ diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c index e0faeb5..1c9bc7c 100644 --- a/opcodes/aarch64-dis.c +++ b/opcodes/aarch64-dis.c @@ -2029,9 +2029,9 @@ user_friendly_fixup (aarch64_inst *inst) } } -/* Decode INSN and fill in *INST the instruction information. */ +/* See aarch64-dis.h. */ -static int +int disas_aarch64_insn (uint32_t insn, aarch64_inst *inst) { const aarch64_opcode *opcode = aarch64_opcode_lookup (insn); diff --git a/opcodes/aarch64-dis.h b/opcodes/aarch64-dis.h index 767191c..241100e 100644 --- a/opcodes/aarch64-dis.h +++ b/opcodes/aarch64-dis.h @@ -36,6 +36,11 @@ const aarch64_opcode* aarch64_opcode_lookup (uint32_t); const aarch64_opcode* aarch64_find_next_opcode (const aarch64_opcode *); +/* Decode INSN and fill in *INST the instruction information. Return zero + on success. */ + +int disas_aarch64_insn (uint32_t insn, aarch64_inst *inst); + /* Given OPCODE, return its alias, e.g. given UBFM, return LSL. In the case of multiple alias candidates, the one of the highest priority