From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 81268 invoked by alias); 21 Sep 2015 14:54:51 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 81194 invoked by uid 89); 21 Sep 2015 14:54:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL,BAYES_00,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mga11.intel.com Received: from mga11.intel.com (HELO mga11.intel.com) (192.55.52.93) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 21 Sep 2015 14:54:49 +0000 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga102.fm.intel.com with ESMTP; 21 Sep 2015 07:54:47 -0700 X-ExtLoop1: 1 Received: from irvmail001.ir.intel.com ([163.33.26.43]) by FMSMGA003.fm.intel.com with ESMTP; 21 Sep 2015 07:54:45 -0700 Received: from ulvlx001.iul.intel.com (ulvlx001.iul.intel.com [172.28.207.17]) by irvmail001.ir.intel.com (8.14.3/8.13.6/MailSET/Hub) with ESMTP id t8LEsi9c014472; Mon, 21 Sep 2015 15:54:45 +0100 Received: from ulvlx001.iul.intel.com (localhost [127.0.0.1]) by ulvlx001.iul.intel.com with ESMTP id t8LEsiGs010485; Mon, 21 Sep 2015 16:54:44 +0200 Received: (from mmetzger@localhost) by ulvlx001.iul.intel.com with œ id t8LEsi5M010481; Mon, 21 Sep 2015 16:54:44 +0200 From: Markus Metzger To: palves@redhat.com, dje@google.com Cc: gdb-patches@sourceware.org Subject: [PATCH 2/6] disasm: add struct disas_insn to describe to-be-disassembled instruction Date: Mon, 21 Sep 2015 14:54:00 -0000 Message-Id: <1442847283-10200-3-git-send-email-markus.t.metzger@intel.com> In-Reply-To: <1442847283-10200-1-git-send-email-markus.t.metzger@intel.com> References: <1442847283-10200-1-git-send-email-markus.t.metzger@intel.com> X-IsSubscribed: yes X-SW-Source: 2015-09/txt/msg00508.txt.bz2 Add a new struct disas_insn to add additional fields describing the to-be-disassembled instruction. The additional fields are: number an optional instruction number, zero if omitted. is_speculative a predicate saying whether the instruction was executed speculatively. Replace the PC parameter of dump_insn with a pointer to the above struct. If non-zero, the instruction number is printed first. It will also appear as a new optional field "insn-number" in MI. The field will be present if insn_num is non-zero. If is_speculative is set, speculative execution will be indicated by a "?" following the new instruction number field. Unless the PC is omitted, it will overwrite the first byte of the PC prefix. It will appear as a new optional field "is-speculative" in MI. The field will contain "?" and will be present if is_speculative is set. The speculative execution indication is guarded by a new flag DISASSEMBLY_SPECULATION. 2015-09-21 Markus Metzger gdb/ * disasm.h (DISASSEMBLY_SPECULATION): New. (struct disas_insn): New. * disasm.c (dump_insn): Replace parameter PC with INSN. Update users. Print instruction number and indicate speculative execution. --- gdb/disasm.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++------------- gdb/disasm.h | 14 ++++++++++++ 2 files changed, 69 insertions(+), 15 deletions(-) diff --git a/gdb/disasm.c b/gdb/disasm.c index 981ab7e..044dcac 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -170,13 +170,13 @@ compare_lines (const void *mle1p, const void *mle2p) return val; } -/* Prints the instruction at PC into UIOUT and returns the length of the +/* Prints the instruction INSN into UIOUT and returns the length of the printed instruction in bytes. */ static int dump_insn (struct gdbarch *gdbarch, struct ui_out *uiout, - struct disassemble_info * di, CORE_ADDR pc, int flags, - struct ui_file *stb) + struct disassemble_info * di, const struct disas_insn *insn, + int flags, struct ui_file *stb) { /* parts of the symbolic representation of the address */ int unmapped; @@ -186,10 +186,37 @@ dump_insn (struct gdbarch *gdbarch, struct ui_out *uiout, struct cleanup *ui_out_chain; char *filename = NULL; char *name = NULL; + CORE_ADDR pc; ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); + pc = insn->addr; + + if (insn->number != 0) + { + ui_out_field_fmt (uiout, "insn-number", "%u", insn->number); + ui_out_text (uiout, "\t"); + } + + if ((flags & DISASSEMBLY_SPECULATIVE) != 0) + { + if (insn->is_speculative) + { + ui_out_field_string (uiout, "is-speculative", "?"); - if ((flags & DISASSEMBLY_OMIT_PC) == 0) + /* The speculative execution indication overwrites the first + character of the PC prefix. + We assume a PC prefix length of 3 characters. */ + if ((flags & DISASSEMBLY_OMIT_PC) == 0) + ui_out_text (uiout, pc_prefix (pc) + 1); + else + ui_out_text (uiout, " "); + } + else if ((flags & DISASSEMBLY_OMIT_PC) == 0) + ui_out_text (uiout, pc_prefix (pc)); + else + ui_out_text (uiout, " "); + } + else if ((flags & DISASSEMBLY_OMIT_PC) == 0) ui_out_text (uiout, pc_prefix (pc)); ui_out_field_core_addr (uiout, "address", gdbarch, pc); @@ -347,7 +374,7 @@ do_mixed_source_and_assembly_deprecated for (i = 0; i < newlines; i++) { - CORE_ADDR pc; + struct disas_insn insn; /* Print out everything from next_line to the current line. */ if (mle[i].line >= next_line) @@ -402,17 +429,20 @@ do_mixed_source_and_assembly_deprecated = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn"); } - pc = mle[i].start_pc; - while (pc < mle[i].end_pc && (how_many < 0 || num_displayed < how_many)) + memset (&insn, 0, sizeof (insn)); + insn.addr = mle[i].start_pc; + + while (insn.addr < mle[i].end_pc + && (how_many < 0 || num_displayed < how_many)) { int size; - size = dump_insn (gdbarch, uiout, di, pc, flags, stb); + size = dump_insn (gdbarch, uiout, di, &insn, flags, stb); if (size <= 0) break; num_displayed += 1; - pc += size; + insn.addr += size; /* Allow user to bail out with ^C. */ QUIT; @@ -551,6 +581,7 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout, int start_preceding_line_to_display = 0; int end_preceding_line_to_display = 0; int new_source_line = 0; + struct disas_insn insn; sal = find_pc_line (pc, 0); @@ -675,21 +706,26 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout, else end_pc = pc + 1; - while (pc < end_pc && (how_many < 0 || num_displayed < how_many)) + memset (&insn, 0, sizeof (insn)); + insn.addr = pc; + + while (insn.addr < end_pc && (how_many < 0 || num_displayed < how_many)) { int size; - size = dump_insn (gdbarch, uiout, di, pc, flags, stb); + size = dump_insn (gdbarch, uiout, di, &insn, flags, stb); if (size <= 0) break; num_displayed += 1; - pc += size; + insn.addr += size; /* Allow user to bail out with ^C. */ QUIT; } + pc = insn.addr; + if (how_many >= 0 && num_displayed >= how_many) break; @@ -708,20 +744,24 @@ do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout, int how_many, int flags, struct ui_file *stb) { struct cleanup *ui_out_chain; + struct disas_insn insn; int num_displayed = 0; ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns"); - while (low < high && (how_many < 0 || num_displayed < how_many)) + memset (&insn, 0, sizeof (insn)); + insn.addr = low; + + while (insn.addr < high && (how_many < 0 || num_displayed < how_many)) { int size; - size = dump_insn (gdbarch, uiout, di, low, flags, stb); + size = dump_insn (gdbarch, uiout, di, &insn, flags, stb); if (size <= 0) break; num_displayed += 1; - low += size; + insn.addr += size; /* Allow user to bail out with ^C. */ QUIT; diff --git a/gdb/disasm.h b/gdb/disasm.h index 7e6f1a2..3d6f5bb 100644 --- a/gdb/disasm.h +++ b/gdb/disasm.h @@ -27,11 +27,25 @@ #define DISASSEMBLY_FILENAME (0x1 << 3) #define DISASSEMBLY_OMIT_PC (0x1 << 4) #define DISASSEMBLY_SOURCE (0x1 << 5) +#define DISASSEMBLY_SPECULATIVE (0x1 << 6) struct gdbarch; struct ui_out; struct ui_file; +/* An instruction to be disassembled. */ + +struct disas_insn { + /* The address of the memory containing the instruction. */ + CORE_ADDR addr; + + /* An optional instruction number. If non-zero, it is printed first. */ + unsigned int number; + + /* A bit-field saying whether the instruction was executed speculatively. */ + unsigned int is_speculative:1; +}; + /* Return a filled in disassemble_info object for use by gdb. */ extern struct disassemble_info gdb_disassemble_info (struct gdbarch *gdbarch, -- 1.8.3.1