From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26968 invoked by alias); 15 May 2007 18:13:57 -0000 Received: (qmail 26952 invoked by uid 22791); 15 May 2007 18:13:55 -0000 X-Spam-Check-By: sourceware.org Received: from dmz.mips-uk.com (HELO dmz.mips-uk.com) (194.74.144.194) by sourceware.org (qpsmtpd/0.31) with ESMTP; Tue, 15 May 2007 18:13:51 +0000 Received: from internal-mx1 ([192.168.192.240] helo=ukservices1.mips.com) by dmz.mips-uk.com with esmtp (Exim 3.35 #1 (Debian)) id 1Ho1Wv-0000WU-00; Tue, 15 May 2007 19:13:49 +0100 Received: from perivale.mips.com ([192.168.192.200]) by ukservices1.mips.com with esmtp (Exim 3.36 #1 (Debian)) id 1Ho1Wn-0004wV-00; Tue, 15 May 2007 19:13:41 +0100 Received: from macro (helo=localhost) by perivale.mips.com with local-esmtp (Exim 4.63) (envelope-from ) id 1Ho1Wn-0004ST-QW; Tue, 15 May 2007 19:13:41 +0100 Date: Tue, 15 May 2007 18:13:00 -0000 From: "Maciej W. Rozycki" To: gdb-patches@sourceware.org cc: Nigel Stephens , "Maciej W. Rozycki" Subject: Disassemble branch delay slot instructions automatically Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-MIPS-Technologies-UK-MailScanner: Found to be clean X-MIPS-Technologies-UK-MailScanner-From: macro@mips.com 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 X-SW-Source: 2007-05/txt/msg00266.txt.bz2 Hello, This is a change that implements automatic disassembly of instructions in a branch delay slot if a branch is the last instruction to be output. It is especially useful with the "display /i" command when single-stepping, where you may want to see a single instruction normally not to get distracted, but with a branch an intruction that follows would be executed without having been printed. Here is an example for MIPS machine code -- this is with our current implementation: (gdb) x /i 0x801018a4 0x801018a4 : beqz v0,0x80101a10 and here -- the same command with the patch applied: (gdb) x /i 0x801018a4 0x801018a4 : beqz v0,0x80101a10 0x801018a8 : li v1,11 This change has been tested natively for mips-unknown-linux-gnu and remotely for mipsisa32-sde-elf, using mips-sim-sde32/-EB and mips-sim-sde32/-EL as the targets, with no regressions. 2007-05-15 Nigel Stephens Maciej W. Rozycki * disasm.c (gdb_set_disassemble_info): New public function to set up a disassemble_info structure, ready for a call to TARGET_PRINT_INSN. * disasm.h (gdb_set_disassemble_info): Add prototype. * printcmd.c (branch_delay_insns): New variable to record number of delay slots after disassembling a branch. (print_formatted): When disassembling don't call gdb_print_insn, but call TARGET_PRINT_INSN directly. Then pick up the resulting branch_delay_insns from the disassemble_info structure and store in local variable of same name. (do_examine): When disassembling, if the last instruction disassembled has any branch delay slots, then bump the count so that they get disassembled too. OK to apply? Maciej 12235.diff Index: binutils-quilt/src/gdb/printcmd.c =================================================================== --- binutils-quilt.orig/src/gdb/printcmd.c 2007-05-15 18:59:05.000000000 +0100 +++ binutils-quilt/src/gdb/printcmd.c 2007-05-15 18:59:46.000000000 +0100 @@ -43,6 +43,7 @@ #include "gdb_assert.h" #include "block.h" #include "disasm.h" +#include "dis-asm.h" #ifdef TUI #include "tui/tui.h" /* For tui_active et.al. */ @@ -70,6 +71,10 @@ static CORE_ADDR next_address; +/* Number of delay instructions following current disassembled insn. */ + +static int branch_delay_insns; + /* Last address examined. */ static CORE_ADDR last_examine_address; @@ -277,8 +282,17 @@ /* We often wrap here if there are long symbolic names. */ wrap_here (" "); - next_address = VALUE_ADDRESS (val) - + gdb_print_insn (VALUE_ADDRESS (val), stream); + { + static struct disassemble_info di; + + gdb_set_disassemble_info (current_gdbarch, stream, &di); + next_address = (VALUE_ADDRESS (val) + + TARGET_PRINT_INSN (VALUE_ADDRESS (val), &di)); + if (di.insn_info_valid) + branch_delay_insns = di.branch_delay_insns; + else + branch_delay_insns = 0; + } break; default: @@ -800,6 +814,10 @@ release_value (last_examine_value); print_formatted (last_examine_value, format, size, gdb_stdout); + + /* Display any branch delay slots following the final insn. */ + if (format == 'i' && count == 1) + count += branch_delay_insns; } printf_filtered ("\n"); gdb_flush (gdb_stdout); Index: binutils-quilt/src/gdb/disasm.c =================================================================== --- binutils-quilt.orig/src/gdb/disasm.c 2007-05-15 18:59:05.000000000 +0100 +++ binutils-quilt/src/gdb/disasm.c 2007-05-15 18:59:46.000000000 +0100 @@ -349,6 +349,15 @@ return di; } +/* Publicly callable version of gdb_disassemble_info which doesn't + return a structure, but stores the result via a pointer. */ +void +gdb_set_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file, + struct disassemble_info *di) +{ + *di = gdb_disassemble_info (gdbarch, file); +} + void gdb_disassembly (struct ui_out *uiout, char *file_string, Index: binutils-quilt/src/gdb/disasm.h =================================================================== --- binutils-quilt.orig/src/gdb/disasm.h 2007-05-15 18:59:05.000000000 +0100 +++ binutils-quilt/src/gdb/disasm.h 2007-05-15 18:59:46.000000000 +0100 @@ -35,4 +35,13 @@ extern int gdb_print_insn (CORE_ADDR memaddr, struct ui_file *stream); +/* Fill in a disassemble_info structure, ready for a call to + TARGET_PRINT_INSN. */ + +struct disassemble_info; + +extern void gdb_set_disassemble_info (struct gdbarch *, + struct ui_file *, + struct disassemble_info *); + #endif