From patchwork Mon Aug 20 22:41:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Buettner X-Patchwork-Id: 28990 Received: (qmail 25548 invoked by alias); 20 Aug 2018 22:41:57 -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 25539 invoked by uid 89); 20 Aug 2018 22:41:55 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mx1.redhat.com Received: from mx3-rdu2.redhat.com (HELO mx1.redhat.com) (66.187.233.73) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 20 Aug 2018 22:41:54 +0000 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BD8AE87A76 for ; Mon, 20 Aug 2018 22:41:52 +0000 (UTC) Received: from pinnacle.lan (ovpn-117-83.phx2.redhat.com [10.3.117.83]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 7A81B6353E for ; Mon, 20 Aug 2018 22:41:52 +0000 (UTC) Date: Mon, 20 Aug 2018 15:41:50 -0700 From: Kevin Buettner To: gdb-patches@sourceware.org Subject: [PATCH v3 4/8] Disassemble blocks with non-contiguous ranges Message-ID: <20180820154150.4b76969e@pinnacle.lan> In-Reply-To: <20180820152512.671a7dc7@pinnacle.lan> References: <20180820152512.671a7dc7@pinnacle.lan> MIME-Version: 1.0 X-IsSubscribed: yes This patch adds support for disassembly of blocks with non-contiguous ranges. These blocks are printed as follows: (gdb) disassemble foo Dump of assembler code for function foo: Address range 0x401136 to 0x401151: 0x0000000000401136 <+0>: push %rbp 0x0000000000401137 <+1>: mov %rsp,%rbp 0x000000000040113a <+4>: callq 0x401134 0x000000000040113f <+9>: mov 0x2eef(%rip),%eax # 0x404034 0x0000000000401145 <+15>: test %eax,%eax 0x0000000000401147 <+17>: je 0x40114e 0x0000000000401149 <+19>: callq 0x401128 0x000000000040114e <+24>: nop 0x000000000040114f <+25>: pop %rbp 0x0000000000401150 <+26>: retq Address range 0x401128 to 0x401134: 0x0000000000401128 <+-14>: push %rbp 0x0000000000401129 <+-13>: mov %rsp,%rbp 0x000000000040112c <+-10>: callq 0x401126 0x0000000000401131 <+-5>: nop 0x0000000000401132 <+-4>: pop %rbp 0x0000000000401133 <+-3>: retq End of assembler dump. This is an actual dump from the test case that I constructed for this work. The ranges are printed in the order encountered in the debug info. For the above example, note that the second range occupies lower addresses than the first range. Functions with contiguous ranges are still printed as follows: (gdb) disassemble main Dump of assembler code for function main: 0x0000000000401151 <+0>: push %rbp 0x0000000000401152 <+1>: mov %rsp,%rbp 0x0000000000401155 <+4>: callq 0x401136 0x000000000040115a <+9>: mov $0x0,%eax 0x000000000040115f <+14>: pop %rbp 0x0000000000401160 <+15>: retq End of assembler dump. gdb/ChangeLog: * cli/cli-cmds.c (block.h): Include. (print_disassembly): Handle printing of non-contiguous blocks. (disassemble_current_function): Likewise. (disassemble_command): Likewise. --- gdb/cli/cli-cmds.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/gdb/cli/cli-cmds.c b/gdb/cli/cli-cmds.c index 5c5d6dc..4694553 100644 --- a/gdb/cli/cli-cmds.c +++ b/gdb/cli/cli-cmds.c @@ -38,6 +38,7 @@ #include "tracepoint.h" #include "filestuff.h" #include "location.h" +#include "block.h" #include "ui-out.h" @@ -1091,11 +1092,15 @@ list_command (const char *arg, int from_tty) Perform the disassembly. NAME is the name of the function if known, or NULL. [LOW,HIGH) are the range of addresses to disassemble. + BLOCK is the block to disassemble; it needs to be provided + when non-contiguous blocks are disassembled; otherwise + it can be NULL. MIXED is non-zero to print source with the assembler. */ static void print_disassembly (struct gdbarch *gdbarch, const char *name, CORE_ADDR low, CORE_ADDR high, + const struct block *block, gdb_disassembly_flags flags) { #if defined(TUI) @@ -1104,14 +1109,28 @@ print_disassembly (struct gdbarch *gdbarch, const char *name, { printf_filtered ("Dump of assembler code "); if (name != NULL) - printf_filtered ("for function %s:\n", name); - else - printf_filtered ("from %s to %s:\n", - paddress (gdbarch, low), paddress (gdbarch, high)); - - /* Dump the specified range. */ - gdb_disassembly (gdbarch, current_uiout, flags, -1, low, high); + printf_filtered ("for function %s:\n", name); + if (block == nullptr || BLOCK_CONTIGUOUS_P (block)) + { + if (name == NULL) + printf_filtered ("from %s to %s:\n", + paddress (gdbarch, low), paddress (gdbarch, high)); + /* Dump the specified range. */ + gdb_disassembly (gdbarch, current_uiout, flags, -1, low, high); + } + else + { + for (int i = 0; i < BLOCK_NRANGES (block); i++) + { + CORE_ADDR low = BLOCK_RANGE_START (block, i); + CORE_ADDR high = BLOCK_RANGE_END (block, i); + printf_filtered (_("Address range %s to %s:\n"), + paddress (gdbarch, low), + paddress (gdbarch, high)); + gdb_disassembly (gdbarch, current_uiout, flags, -1, low, high); + } + } printf_filtered ("End of assembler dump.\n"); gdb_flush (gdb_stdout); } @@ -1133,11 +1152,12 @@ disassemble_current_function (gdb_disassembly_flags flags) struct gdbarch *gdbarch; CORE_ADDR low, high, pc; const char *name; + const struct block *block; frame = get_selected_frame (_("No frame selected.")); gdbarch = get_frame_arch (frame); pc = get_frame_address_in_block (frame); - if (find_pc_partial_function (pc, &name, &low, &high) == 0) + if (find_pc_partial_function (pc, &name, &low, &high, &block) == 0) error (_("No function contains program counter for selected frame.")); #if defined(TUI) /* NOTE: cagney/2003-02-13 The `tui_active' was previously @@ -1148,7 +1168,7 @@ disassemble_current_function (gdb_disassembly_flags flags) #endif low += gdbarch_deprecated_function_start_offset (gdbarch); - print_disassembly (gdbarch, name, low, high, flags); + print_disassembly (gdbarch, name, low, high, block, flags); } /* Dump a specified section of assembly code. @@ -1184,6 +1204,7 @@ disassemble_command (const char *arg, int from_tty) CORE_ADDR pc; gdb_disassembly_flags flags; const char *p; + const struct block *block = nullptr; p = arg; name = NULL; @@ -1234,7 +1255,7 @@ disassemble_command (const char *arg, int from_tty) if (p[0] == '\0') { /* One argument. */ - if (find_pc_partial_function (pc, &name, &low, &high) == 0) + if (find_pc_partial_function (pc, &name, &low, &high, &block) == 0) error (_("No function contains specified address.")); #if defined(TUI) /* NOTE: cagney/2003-02-13 The `tui_active' was previously @@ -1262,7 +1283,7 @@ disassemble_command (const char *arg, int from_tty) high += low; } - print_disassembly (gdbarch, name, low, high, flags); + print_disassembly (gdbarch, name, low, high, block, flags); } static void