public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Andrew Burgess <aburgess@redhat.com>
To: gdb-patches@sourceware.org
Cc: Andrew Burgess <aburgess@redhat.com>
Subject: [PATCH 9/9] gdb/mi: new options for -data-disassemble command
Date: Thu, 23 Jun 2022 17:05:16 +0100	[thread overview]
Message-ID: <7e451914de0fc57677e73bf48d66a70b23276f7f.1655999715.git.aburgess@redhat.com> (raw)
In-Reply-To: <cover.1655999715.git.aburgess@redhat.com>

Now that the disassembler has two different strategies for laying out
the opcode bytes of an instruction (see /r vs /b for the disassemble
command), I wanted to add support for this to the MI disassemble
command.

Currently the -data-disassemble command takes a single 'mode' value,
which currently has 6 different values (0 -> 5), 3 of these modes
relate to opcode display.

So, clearly I should just add an additional 3 modes to handle the new
opcode format, right?

No, I didn't think that was a great idea either.

So, I wonder, could I adjust the -data-disassemble command in a
backward compatible way, that would allow GDB to move away from using
the mode value altogether?

I think we can.

In this commit, I propose adding two new options to -data-disassemble,
these are:

  --opcodes none|bytes|display
  --source

Additionally, I will make the mode optional, and default to mode 0 if
no mode value is given.  Mode 0 is the simplest, no source code, no
opcodes disassembly mode.

The two new options are only valid for mode 0, if they are used with
any other mode then an error is thrown.

The --opcodes option can add opcodes to the result, with 'bytes' being
equivalent to 'disassemble /b' and 'display' being 'disassemble /r'.

The --source option will enable the /s style source code display, this
is equivalent to modes 4 and 5.  There is no way, using the new
command options to get the now deprecated /m style source code
display, that is mode 1 and 3.

My hope is that new users of the MI will not use the mode at all, and
instead will just use the new options to achieve the output they need.
Existing MI users can continue to use the mode, and will not need to
be updated to use the new options.
---
 gdb/doc/gdb.texinfo                     | 83 ++++++++++++++++++-------
 gdb/mi/mi-cmd-disas.c                   | 75 +++++++++++++++++++---
 gdb/testsuite/gdb.mi/mi-disassemble.exp | 66 +++++++++++++-------
 3 files changed, 174 insertions(+), 50 deletions(-)

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index ca9d29bd364..456d362a109 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -34387,7 +34387,9 @@
   ( -s @var{start-addr} -e @var{end-addr}
   | -a @var{addr}
   | -f @var{filename} -l @var{linenum} [ -n @var{lines} ] )
-  -- @var{mode}
+  [ --opcodes @var{opcodes-mode} ]
+  [ --source ]
+  [ -- @var{mode} ]
 @end smallexample
 
 @noindent
@@ -34416,31 +34418,56 @@
 displayed; if @var{lines} is higher than the number of lines between
 @var{start-addr} and @var{end-addr}, only the lines up to @var{end-addr}
 are displayed.
+@item @var{opcodes-mode}
+is one of @samp{none}, @samp{bytes}, or @samp{display}.  This setting
+can only be used with @var{mode} 0.  Passing @samp{none} here will
+prevent opcodes being included in the result; passing @samp{bytes} here
+will include opcodes in the result, the opcodes will be formatted as for
+@kbd{disassemble /b}; and passing @samp{display} here will include the
+opcodes in the result, the opcodes will be formatted as for
+@kbd{disassemble /r}.
 @item @var{mode}
-is one of:
+the use of @var{mode} is deprecated in favour of using the
+@code{--opcodes} and @code{--source} options.  When no @var{mode} is
+given, @var{mode} 0 will be assumed.  However, the @var{mode} is still
+available for backward compatibility.  The @var{mode} should be one of:
 @itemize @bullet
-@item 0 disassembly only
-@item 1 mixed source and disassembly (deprecated)
-@item 2 disassembly with raw opcodes
-@item 3 mixed source and disassembly with raw opcodes (deprecated)
-@item 4 mixed source and disassembly
-@item 5 mixed source and disassembly with raw opcodes
+@item 0 disassembly only:
+This is the default mode if no mode is specified.
+@item 1 mixed source and disassembly (deprecated):
+It is not possible to recreate this mode using @code{--opcodes} and
+@code{--source} options.
+@item 2 disassembly with raw opcodes:
+This mode is equivalent to using @var{mode} 0 and passing
+@code{--opcodes bytes} to the command.
+@item 3 mixed source and disassembly with raw opcodes (deprecated):
+It is not possible to recreate this mode using @code{--opcodes} and
+@code{--source} options.
+@item 4 mixed source and disassembly:
+This mode is equivalent to using @var{mode} 0 and passing
+@code{--source} to the command.
+@item 5 mixed source and disassembly with raw opcodes:
+This mode is equivalent to using @var{mode} 0 and passing
+@code{--opcodes bytes} and @code{--source} to the command.
 @end itemize
-
 Modes 1 and 3 are deprecated.  The output is ``source centric''
 which hasn't proved useful in practice.
 @xref{Machine Code}, for a discussion of the difference between
 @code{/m} and @code{/s} output of the @code{disassemble} command.
 @end table
 
+The @code{--source} can only be used with @var{mode} 0.  Passing this
+option will include the source code in the disassembly result as if
+@var{mode} 4 or 5 had been used.
+
 @subsubheading Result
 
 The result of the @code{-data-disassemble} command will be a list named
-@samp{asm_insns}, the contents of this list depend on the @var{mode}
-used with the @code{-data-disassemble} command.
+@samp{asm_insns}, the contents of this list depend on the options used
+with the @code{-data-disassemble} command.
 
-For modes 0 and 2 the @samp{asm_insns} list contains tuples with the
-following fields:
+For modes 0 and 2, and when the @code{--source} option is not used the
+@samp{asm_insns} list contains tuples with the following fields:
 
 @table @code
 @item address
@@ -34456,15 +34483,27 @@
 The text disassembly for this @samp{address}.
 
 @item opcodes
-This field is only present for modes 2, 3 and 5.  This contains the
-raw opcode bytes for the @samp{inst} field.  The bytes are formatted
-as single bytes, in hex, in ascending address order, with a single
-space between each byte.
-
-@end table
-
-For modes 1, 3, 4 and 5 the @samp{asm_insns} list contains tuples named
-@samp{src_and_asm_line}, each of which has the following fields:
+This field is only present for modes 2, 3 and 5, or when the
+@code{--opcodes} option @samp{bytes} or @samp{display} is used.  This
+contains the raw opcode bytes for the @samp{inst} field.
+
+When the @samp{--opcodes} option is not passed to
+@code{-data-disassemble}, or the @samp{bytes} value is passed to
+@samp{--opcodes}, then the bytes are formatted as a series of single
+bytes, in hex, in ascending address order, with a single space between
+each byte.  This format is equivalent to the @samp{/b} option being used
+with the @kbd{disassemble} command.
+
+When @samp{--opcodes} is passed the value @samp{display} then the bytes
+are formatted in the natural instruction display order.  This means
+multiple bytes can be grouped together, and the bytes might be
+byte-swapped.  This format is equivalent to the @samp{/r} option being
+used with the @kbd{disassemble} command.
+@end table
+
+For modes 1, 3, 4 and 5, or when the @code{--source} option is used, the
+@samp{asm_insns} list contains tuples named @samp{src_and_asm_line},
+each of which has the following fields:
 
 @table @code
 @item line
diff --git a/gdb/mi/mi-cmd-disas.c b/gdb/mi/mi-cmd-disas.c
index 4f6e5613b9d..db5a78827fc 100644
--- a/gdb/mi/mi-cmd-disas.c
+++ b/gdb/mi/mi-cmd-disas.c
@@ -68,6 +68,8 @@ mi_cmd_disassemble (const char *command, char **argv, int argc)
   bool start_seen = false;
   bool end_seen = false;
   bool addr_seen = false;
+  bool opcodes_seen = false;
+  bool source_seen = false;
 
   /* ... and their corresponding value. */
   char *file_string = NULL;
@@ -77,12 +79,23 @@ mi_cmd_disassemble (const char *command, char **argv, int argc)
   CORE_ADDR high = 0;
   CORE_ADDR addr = 0;
 
+  /* Flags to handle the --opcodes option.  */
+  enum opcodes_mode
+  {
+    OPCODES_DEFAULT, OPCODES_NONE, OPCODES_DISPLAY, OPCODES_BYTES
+  };
+  enum opcodes_mode opcodes_mode = OPCODES_DEFAULT;
+
+  /* Handle the -source option.  */
+  bool show_source = false;
+
   /* Options processing stuff.  */
   int oind = 0;
   char *oarg;
   enum opt
   {
-    FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_OPT, ADDR_OPT
+    FILE_OPT, LINE_OPT, NUM_OPT, START_OPT, END_OPT, ADDR_OPT, OPCODES_OPT,
+    SHOW_SRC_OPT
   };
   static const struct mi_opt opts[] =
     {
@@ -92,6 +105,8 @@ mi_cmd_disassemble (const char *command, char **argv, int argc)
       {"s", START_OPT, 1},
       {"e", END_OPT, 1},
       {"a", ADDR_OPT, 1},
+      {"-opcodes", OPCODES_OPT, 1},
+      {"-source", SHOW_SRC_OPT, 0},
       { 0, 0, 0 }
     };
 
@@ -129,6 +144,21 @@ mi_cmd_disassemble (const char *command, char **argv, int argc)
 	  addr = parse_and_eval_address (oarg);
 	  addr_seen = true;
 	  break;
+	case OPCODES_OPT:
+	  opcodes_seen = true;
+	  if (strcmp (oarg, "none") == 0)
+	    opcodes_mode = OPCODES_NONE;
+	  else if (strcmp (oarg, "display") == 0)
+	    opcodes_mode = OPCODES_DISPLAY;
+	  else if (strcmp (oarg, "bytes") == 0)
+	    opcodes_mode = OPCODES_BYTES;
+	  else
+	    error (_("-data-disassemble: unknown value for -opcodes argument"));
+	  break;
+	case SHOW_SRC_OPT:
+	  source_seen = true;
+	  show_source = true;
+	  break;
 	}
     }
   argv += oind;
@@ -146,13 +176,23 @@ mi_cmd_disassemble (const char *command, char **argv, int argc)
 
        || (!line_seen && !file_seen && !num_seen && !start_seen && !end_seen
 								&&  addr_seen))
-      || argc != 1)
-    error (_("-data-disassemble: Usage: ( [-f filename -l linenum "
-	     "[-n howmany]] | [-s startaddr -e endaddr] | [-a addr] ) [--] mode."));
+      || argc > 1)
+    error (_("-data-disassemble: Usage: "
+	     "( -f filename -l linenum [-n howmany] |"
+	     " -s startaddr -e endaddr | -a addr ) "
+	     "[ --opcodes mode ] [ --source ] [ [--] mode ]."));
+
+  if (argc == 1)
+    {
+      mode = atoi (argv[0]);
+      if (mode < 0 || mode > 5)
+	error (_("-data-disassemble: Mode argument must be in the range 0-5."));
+    }
+  else
+    mode = 0;
 
-  mode = atoi (argv[0]);
-  if (mode < 0 || mode > 5)
-    error (_("-data-disassemble: Mode argument must be in the range 0-5."));
+  if (mode != 0 && (source_seen || opcodes_seen))
+    error (_("-data-disassemble: --opcodes and --source can only be used with mode 0"));
 
   /* Convert the mode into a set of disassembly flags.  */
 
@@ -180,6 +220,27 @@ mi_cmd_disassemble (const char *command, char **argv, int argc)
       gdb_assert_not_reached ("bad disassembly mode");
     }
 
+  /* Now handle the (optional) --opcodes argument.  This partially
+     overrides the mode value.  */
+  if (opcodes_mode != OPCODES_DEFAULT)
+    {
+      /* Remove any existing flags related to opcodes display.  */
+      disasm_flags &= ~(DISASSEMBLY_RAW_BYTES | DISASSEMBLY_RAW_INSN);
+
+      /* Add back any required flags.  */
+      if (opcodes_mode == OPCODES_DISPLAY)
+	disasm_flags |= DISASSEMBLY_RAW_INSN;
+      else if (opcodes_mode == OPCODES_BYTES)
+	disasm_flags |= DISASSEMBLY_RAW_BYTES;
+    }
+
+  /* Handle the optional --source argument.  */
+  if (show_source)
+    {
+      disasm_flags &= ~DISASSEMBLY_SOURCE_DEPRECATED;
+      disasm_flags |= DISASSEMBLY_SOURCE;
+    }
+
   /* We must get the function beginning and end where line_num is
      contained.  */
 
diff --git a/gdb/testsuite/gdb.mi/mi-disassemble.exp b/gdb/testsuite/gdb.mi/mi-disassemble.exp
index ef3337d4062..4d7c2f2e6e7 100644
--- a/gdb/testsuite/gdb.mi/mi-disassemble.exp
+++ b/gdb/testsuite/gdb.mi/mi-disassemble.exp
@@ -47,21 +47,27 @@ proc test_disassembly_only {} {
 
 
     mi_gdb_test "print/x \$pc" "" ""
-    mi_gdb_test "111-data-disassemble -s \$pc -e \"\$pc + 12\" -- 0" \
-	    "111\\^done,asm_insns=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\},\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}.*\]" \
-             "data-disassemble from pc to pc+12 assembly only"
 
-    mi_gdb_test "112-data-disassemble -a \$pc -- 0" \
-	    "112\\^done,asm_insns=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\},\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}.*\]" \
-             "data-disassemble function around pc assembly only"
+    foreach { test_name option_string } [list "mode 0" "-- 0" \
+					     "default mode" "" ] {
+	with_test_prefix $test_name {
+	    mi_gdb_test "111-data-disassemble -s \$pc -e \"\$pc + 12\" ${option_string}" \
+		"111\\^done,asm_insns=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\},\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}.*\]" \
+		"data-disassemble from pc to pc+12 assembly only"
 
-    mi_gdb_test "113-data-disassemble -a callee4 -- 0" \
-	    "113\\^done,asm_insns=\\\[\{address=\"$hex\",func-name=\"callee4\",offset=\"$decimal\",inst=\".*\"\},\{address=\"$hex\",func-name=\"callee4\",offset=\"$decimal\",inst=\".*\"\}.*\]" \
-             "data-disassemble function callee4 assembly only"
+	    mi_gdb_test "112-data-disassemble -a \$pc ${option_string}" \
+		"112\\^done,asm_insns=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\},\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}.*\]" \
+		"data-disassemble function around pc assembly only"
 
-    mi_gdb_test "222-data-disassemble  -f basics.c -l $line_main_body -- 0" \
-	    "222\\^done,asm_insns=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"0\",inst=\".*\"\},.*,\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}\\\]" \
-              "data-disassemble file & line, assembly only"
+	    mi_gdb_test "113-data-disassemble -a callee4 ${option_string}" \
+		"113\\^done,asm_insns=\\\[\{address=\"$hex\",func-name=\"callee4\",offset=\"$decimal\",inst=\".*\"\},\{address=\"$hex\",func-name=\"callee4\",offset=\"$decimal\",inst=\".*\"\}.*\]" \
+		"data-disassemble function callee4 assembly only"
+
+	    mi_gdb_test "222-data-disassemble  -f basics.c -l $line_main_body ${option_string}" \
+		"222\\^done,asm_insns=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"0\",inst=\".*\"\},.*,\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",inst=\".*\"\}\\\]" \
+		"data-disassemble file & line, assembly only"
+	}
+    }
 }
 
 proc test_disassembly_with_opcodes {} {
@@ -78,13 +84,20 @@ proc test_disassembly_with_opcodes {} {
     # -data-disassembly -f basics.c -l $line_main_body -- 2
 
     mi_gdb_test "print/x \$pc" "" ""
-    mi_gdb_test "111-data-disassemble -s \$pc -e \"\$pc + 12\" -- 2" \
-           "111\\^done,asm_insns=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",opcodes=\".*\",inst=\".*\"\},\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",opcodes=\".*\",inst=\".*\"\}.*\]" \
-             "data-disassemble from pc to pc+12 assembly with opcodes"
 
-    mi_gdb_test "222-data-disassemble  -f basics.c -l $line_main_body -- 2" \
-           "222\\^done,asm_insns=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"0\",opcodes=\".*\",inst=\".*\"\},.*,\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",opcodes=\".*\",inst=\".*\"\}\\\]" \
-              "data-disassemble file & line, assembly with opcodes"
+    foreach { test_name option_string} [list "mode 2" "-- 2" \
+					    "mode 0 and --opcodes bytes" "--opcodes bytes -- 0" \
+					    "default mode and --opcodes bytes" "--opcodes bytes"] {
+	with_test_prefix $test_name {
+	    mi_gdb_test "111-data-disassemble -s \$pc -e \"\$pc + 12\" ${option_string}" \
+		"111\\^done,asm_insns=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",opcodes=\".*\",inst=\".*\"\},\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",opcodes=\".*\",inst=\".*\"\}.*\]" \
+		"data-disassemble from pc to pc+12 assembly"
+
+	    mi_gdb_test "222-data-disassemble  -f basics.c -l $line_main_body ${option_string}" \
+		"222\\^done,asm_insns=\\\[\{address=\"$hex\",func-name=\"main\",offset=\"0\",opcodes=\".*\",inst=\".*\"\},.*,\{address=\"$hex\",func-name=\"main\",offset=\"$decimal\",opcodes=\".*\",inst=\".*\"\}\\\]" \
+		"data-disassemble file & line, assembly"
+	}
+    }
 }
 
 proc test_disassembly_lines_limit {} {
@@ -230,13 +243,24 @@ proc test_disassembly_bogus_args {} {
              "data-disassemble bogus address, -a"
 
     mi_gdb_test "456-data-disassemble -s \$pc -f basics.c -- 0" \
-             "456\\^error,msg=\"-data-disassemble: Usage: \\( .-f filename -l linenum .-n howmany.. \\| .-s startaddr -e endaddr. \\| .-a addr. \\) .--. mode.\"" \
-             "data-disassemble mix different args"
+	"456\\^error,msg=\"-data-disassemble: Usage: \\( -f filename -l linenum .-n howmany. \\| -s startaddr -e endaddr \\| -a addr \\) . --opcodes mode . . --source . . .--. mode .\\.\"" \
+	"data-disassemble mix different args"
 
     mi_gdb_test "789-data-disassemble -f basics.c -l $line_main_body -- 9" \
              "789\\^error,msg=\"-data-disassemble: Mode argument must be in the range 0-5.\"" \
-             "data-disassemble wrong mode arg"
+	"data-disassemble wrong mode arg"
+
+    foreach mode { 1 2 3 4 5 } {
+	foreach opcode_arg { none bytes display } {
+	    mi_gdb_test "801-data-disassemble -s \$pc -e \"\$pc + 12\" --opcodes ${opcode_arg} -- ${mode}" \
+		"801\\^error,msg=\"-data-disassemble: --opcodes and --source can only be used with mode 0\"" \
+		"data-disassemble use --opcode ${opcode_arg} with mode ${mode}"
+	}
 
+	mi_gdb_test "802-data-disassemble -s \$pc -e \"\$pc + 12\" --source -- ${mode}" \
+	    "802\\^error,msg=\"-data-disassemble: --opcodes and --source can only be used with mode 0\"" \
+	    "data-disassemble use --source with mode ${mode}"
+    }
 }
 
 # Check the format of the opcode bytes.
-- 
2.25.4


  parent reply	other threads:[~2022-06-23 16:05 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-23 16:05 [PATCH 0/9] Disassembler opcode display and text alignment Andrew Burgess
2022-06-23 16:05 ` [PATCH 1/9] gdb/doc: improve description of --data-disassemble opcodes output Andrew Burgess
2022-06-23 16:09   ` Eli Zaretskii
2022-06-29 12:54     ` Andrew Burgess
2022-06-23 16:05 ` [PATCH 2/9] gdb/testsuite: new test for -data-disassemble opcodes format Andrew Burgess
2022-06-23 16:05 ` [PATCH 3/9] gdb/disasm: read opcodes bytes with a single read_code call Andrew Burgess
2022-06-23 16:05 ` [PATCH 4/9] gdb: disassembler opcode display formatting Andrew Burgess
2022-06-23 16:14   ` Eli Zaretskii
2022-06-23 16:05 ` [PATCH 5/9] gdb: make gdb_disassembly_flag unsigned Andrew Burgess
2022-06-23 16:05 ` [PATCH 6/9] gdb/doc: fix column widths in MI compatibility table Andrew Burgess
2022-06-23 16:22   ` Eli Zaretskii
2022-06-30  9:39     ` Andrew Burgess
2022-06-23 16:05 ` [PATCH 7/9] gdb/doc: update syntax of -data-disassemble command arguments Andrew Burgess
2022-06-23 16:21   ` Eli Zaretskii
2022-06-30 10:18     ` Andrew Burgess
2022-06-30 10:46       ` Eli Zaretskii
2022-06-23 16:05 ` [PATCH 8/9] gdb/mi: some int to bool conversion Andrew Burgess
2022-06-23 16:05 ` Andrew Burgess [this message]
2022-06-23 16:34   ` [PATCH 9/9] gdb/mi: new options for -data-disassemble command Eli Zaretskii
2022-06-30 11:22     ` Andrew Burgess
2022-06-30 13:36       ` Eli Zaretskii
2022-07-25 18:28 ` [PATCH 0/9] Disassembler opcode display and text alignment Andrew Burgess
2022-09-05 14:11   ` Andrew Burgess
2022-09-21 16:41 ` Tom Tromey
2022-10-02 13:15   ` Andrew Burgess

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7e451914de0fc57677e73bf48d66a70b23276f7f.1655999715.git.aburgess@redhat.com \
    --to=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).