This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Add a new modifier /c to "disassemble" command to make it output binary code


How about test suites?
At a minimum, gdb.base/help.exp probably needs an update.

Hui Zhu wrote:
Hi,

The objdump will output the binary code when it works but gdb not.
I make a patch to add a new modifier /c to "disassemble" command to
make it output binary code.
Please help me review it.

Thanks,
Hui

2009-07-09 Hui Zhu <teawater@gmail.com>

	* cli/cli-cmds.c (disassemble_command): Add a new modifier /c
	to "disassemble" command to make it output binary code.
	(init_cli_cmds): Ditto.
	(print_disassembly): Add a new argument "code" to make sure
	output binary code or not.
	(disassemble_current_function): Ditto.
	* mi/mi-cmd-disas.c (mi_cmd_disassemble): Ditto.
	* stack.c (gdb_disassembly_stub): Ditto.
	* disasm.h (gdb_disassembly): Ditto.
	* disasm.c (do_mixed_source_and_assembly): Ditto.
	(do_mixed_source_and_assembly): Ditto.
	(do_assembly_only): Ditto.
	(gdb_disassembly): Ditto.
	(dump_insns): Output the binary code if "code" is true.

---
 cli/cli-cmds.c    |   27 +++++++++++++++++----------
 disasm.c          |   35 ++++++++++++++++++++++++++---------
 disasm.h          |    3 ++-
 mi/mi-cmd-disas.c |    2 +-
 stack.c           |    2 +-
 5 files changed, 47 insertions(+), 22 deletions(-)

--- a/cli/cli-cmds.c
+++ b/cli/cli-cmds.c
@@ -908,7 +908,7 @@ list_command (char *arg, int from_tty)

 static void
 print_disassembly (struct gdbarch *gdbarch, const char *name,
-		   CORE_ADDR low, CORE_ADDR high, int mixed)
+		   CORE_ADDR low, CORE_ADDR high, int mixed, int code)
 {
 #if defined(TUI)
   if (!tui_is_window_visible (DISASSEM_WIN))
@@ -922,7 +922,7 @@ print_disassembly (struct gdbarch *gdbar
 			 paddress (gdbarch, low), paddress (gdbarch, high));

       /* Dump the specified range.  */
-      gdb_disassembly (gdbarch, uiout, 0, mixed, -1, low, high);
+      gdb_disassembly (gdbarch, uiout, 0, mixed, -1, code, low, high);

       printf_filtered ("End of assembler dump.\n");
       gdb_flush (gdb_stdout);
@@ -940,7 +940,7 @@ print_disassembly (struct gdbarch *gdbar
    MIXED is non-zero to print source with the assembler.  */

 static void
-disassemble_current_function (int mixed)
+disassemble_current_function (int mixed, int code)
 {
   struct frame_info *frame;
   struct gdbarch *gdbarch;
@@ -961,20 +961,21 @@ disassemble_current_function (int mixed)
 #endif
   low += gdbarch_deprecated_function_start_offset (gdbarch);

-  print_disassembly (gdbarch, name, low, high, mixed);
+  print_disassembly (gdbarch, name, low, high, mixed, code);
 }

/* Dump a specified section of assembly code.

    Usage:
-     disassemble [/m]
+     disassemble [/mc]
        - dump the assembly code for the function of the current pc
-     disassemble [/m] addr
+     disassemble [/mc] addr
        - dump the assembly code for the function at ADDR
-     disassemble [/m] low high
+     disassemble [/mc] low high
        - dump the assembly code in the range [LOW,HIGH)

-   A /m modifier will include source code with the assembly.  */
+   A /m modifier will include source code with the assembly.
+   A /c modifier will include binary code with the assembly.  */

 static void
 disassemble_command (char *arg, int from_tty)
@@ -985,9 +986,11 @@ disassemble_command (char *arg, int from
   CORE_ADDR pc, pc_masked;
   char *space_index;
   int mixed_source_and_assembly;
+  int code;

   name = NULL;
   mixed_source_and_assembly = 0;
+  code = 0;

   if (arg && *arg == '/')
     {
@@ -1003,6 +1006,9 @@ disassemble_command (char *arg, int from
 	    case 'm':
 	      mixed_source_and_assembly = 1;
 	      break;
+	    case 'c':
+	      code = 1;
+	      break;
 	    default:
 	      error (_("Invalid disassembly modifier."));
 	    }
@@ -1014,7 +1020,7 @@ disassemble_command (char *arg, int from

   if (! arg || ! *arg)
     {
-      disassemble_current_function (mixed_source_and_assembly);
+      disassemble_current_function (mixed_source_and_assembly, code);
       return;
     }

@@ -1044,7 +1050,7 @@ disassemble_command (char *arg, int from
       high = parse_and_eval_address (space_index + 1);
     }

-  print_disassembly (gdbarch, name, low, high, mixed_source_and_assembly);
+  print_disassembly (gdbarch, name, low, high,
mixed_source_and_assembly, code);
 }

 static void
@@ -1453,6 +1459,7 @@ With two args if one is empty it stands
 Disassemble a specified section of memory.\n\
 Default is the function surrounding the pc of the selected frame.\n\
 With a /m modifier, source lines are included (if available).\n\
+With a /c modifier, binary code are included.\n\
 With a single argument, the function surrounding that address is dumped.\n\
 Two arguments are taken as a range of memory to dump."));
   set_cmd_completer (c, location_completer);
--- a/disasm.c
+++ b/disasm.c
@@ -88,7 +88,7 @@ static int
 dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
 	    struct disassemble_info * di,
 	    CORE_ADDR low, CORE_ADDR high,
-	    int how_many, struct ui_stream *stb)
+	    int how_many, int code, struct ui_stream *stb)
 {
   int num_displayed = 0;
   CORE_ADDR pc;
@@ -135,7 +135,23 @@ dump_insns (struct gdbarch *gdbarch, str
 	xfree (name);

       ui_file_rewind (stb->stream);
-      pc += gdbarch_print_insn (gdbarch, pc, di);
+      if (code)
+        {
+          CORE_ADDR old_pc = pc;
+          bfd_byte data;
+          int status;
+          pc += gdbarch_print_insn (gdbarch, pc, di);
+          for (;old_pc < pc; old_pc++)
+            {
+              status = (*di->read_memory_func) (old_pc, &data, 1, di);
+              if (status != 0)
+                (*di->memory_error_func) (status, old_pc, di);
+              ui_out_message (uiout, 0, " %02x", (unsigned)data);
+            }
+          ui_out_text (uiout, "\t");
+        }
+      else
+        pc += gdbarch_print_insn (gdbarch, pc, di);
       ui_out_field_stream (uiout, "inst", stb);
       ui_file_rewind (stb->stream);
       do_cleanups (ui_out_chain);
@@ -154,7 +170,7 @@ do_mixed_source_and_assembly (struct gdb
 			      struct linetable_entry *le,
 			      CORE_ADDR low, CORE_ADDR high,
 			      struct symtab *symtab,
-			      int how_many, struct ui_stream *stb)
+			      int how_many, int code, struct ui_stream *stb)
 {
   int newlines = 0;
   struct dis_line_entry *mle;
@@ -278,7 +294,7 @@ do_mixed_source_and_assembly (struct gdb

       num_displayed += dump_insns (gdbarch, uiout, di,
 				   mle[i].start_pc, mle[i].end_pc,
-				   how_many, stb);
+				   how_many, code, stb);

       /* When we've reached the end of the mle array, or we've seen the last
          assembly range for this source line, close out the list/tuple.  */
@@ -301,14 +317,15 @@ static void
 do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
 		  struct disassemble_info * di,
 		  CORE_ADDR low, CORE_ADDR high,
-		  int how_many, struct ui_stream *stb)
+		  int how_many, int code, struct ui_stream *stb)
 {
   int num_displayed = 0;
   struct cleanup *ui_out_chain;

ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");

-  num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many, stb);
+  num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many,
+                              code, stb);

   do_cleanups (ui_out_chain);
 }
@@ -357,7 +374,7 @@ void
 gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
 		char *file_string,
 		int mixed_source_and_assembly,
-		int how_many, CORE_ADDR low, CORE_ADDR high)
+		int how_many, int code, CORE_ADDR low, CORE_ADDR high)
 {
   struct ui_stream *stb = ui_out_stream_new (uiout);
   struct cleanup *cleanups = make_cleanup_ui_out_stream_delete (stb);
@@ -379,11 +396,11 @@ gdb_disassembly (struct gdbarch *gdbarch

   if (!mixed_source_and_assembly || nlines <= 0
       || symtab == NULL || symtab->linetable == NULL)
-    do_assembly_only (gdbarch, uiout, &di, low, high, how_many, stb);
+    do_assembly_only (gdbarch, uiout, &di, low, high, how_many, code, stb);

   else if (mixed_source_and_assembly)
     do_mixed_source_and_assembly (gdbarch, uiout, &di, nlines, le, low,
-				  high, symtab, how_many, stb);
+				  high, symtab, how_many, code, stb);

   do_cleanups (cleanups);
   gdb_flush (gdb_stdout);
--- a/disasm.h
+++ b/disasm.h
@@ -25,7 +25,8 @@ struct ui_file;
 extern void gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
 			     char *file_string,
 			     int mixed_source_and_assembly,
-			     int how_many, CORE_ADDR low, CORE_ADDR high);
+			     int how_many, int code, CORE_ADDR low,
+	                     CORE_ADDR high);

 /* Print the instruction at address MEMADDR in debugged memory,
    on STREAM.  Returns the length of the instruction, in bytes,
--- a/mi/mi-cmd-disas.c
+++ b/mi/mi-cmd-disas.c
@@ -156,6 +156,6 @@ mi_cmd_disassemble (char *command, char

   gdb_disassembly (gdbarch, uiout,
   		   file_string,
-		   mixed_source_and_assembly, how_many, low, high);
+		   mixed_source_and_assembly, 0, how_many, low, high);

 }
--- a/stack.c
+++ b/stack.c
@@ -481,7 +481,7 @@ static void
 gdb_disassembly_stub (void *args)
 {
   struct gdb_disassembly_stub_args *p = args;
-  gdb_disassembly (p->gdbarch, uiout, 0, 0, p->how_many, p->low, p->high);
+  gdb_disassembly (p->gdbarch, uiout, 0, 0, 1, p->how_many, p->low, p->high);
 }

/* Use TRY_CATCH to catch the exception from the gdb_disassembly


2009-07-09 Hui Zhu <teawater@gmail.com>


	* gdb.texinfo (disassemble): Add a new modifier /c
	to "disassemble" command to make it output binary code.

---
 doc/gdb.texinfo |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

--- a/doc/gdb.texinfo
+++ b/doc/gdb.texinfo
@@ -6177,10 +6177,11 @@ Variables}).
 @cindex machine instructions
 @cindex listing machine instructions
 @item disassemble
-@itemx disassemble /m
+@itemx disassemble /mc
 This specialized command dumps a range of memory as machine
 instructions.  It can also print mixed source+disassembly by specifying
-the @code{/m} modifier.
+the @code{/m} modifier and print binary code by specifying
+the @code{/c}.
 The default memory range is the function surrounding the
 program counter of the selected frame.  A single argument to this
 command is a program counter value; @value{GDBN} dumps the function


------------------------------------------------------------------------


---
 cli/cli-cmds.c    |   27 +++++++++++++++++----------
 disasm.c          |   35 ++++++++++++++++++++++++++---------
 disasm.h          |    3 ++-
 mi/mi-cmd-disas.c |    2 +-
 stack.c           |    2 +-
 5 files changed, 47 insertions(+), 22 deletions(-)

--- a/cli/cli-cmds.c
+++ b/cli/cli-cmds.c
@@ -908,7 +908,7 @@ list_command (char *arg, int from_tty)
static void
print_disassembly (struct gdbarch *gdbarch, const char *name,
- CORE_ADDR low, CORE_ADDR high, int mixed)
+ CORE_ADDR low, CORE_ADDR high, int mixed, int code)
{
#if defined(TUI)
if (!tui_is_window_visible (DISASSEM_WIN))
@@ -922,7 +922,7 @@ print_disassembly (struct gdbarch *gdbar
paddress (gdbarch, low), paddress (gdbarch, high));
/* Dump the specified range. */
- gdb_disassembly (gdbarch, uiout, 0, mixed, -1, low, high);
+ gdb_disassembly (gdbarch, uiout, 0, mixed, -1, code, low, high);
printf_filtered ("End of assembler dump.\n");
gdb_flush (gdb_stdout);
@@ -940,7 +940,7 @@ print_disassembly (struct gdbarch *gdbar
MIXED is non-zero to print source with the assembler. */
static void
-disassemble_current_function (int mixed)
+disassemble_current_function (int mixed, int code)
{
struct frame_info *frame;
struct gdbarch *gdbarch;
@@ -961,20 +961,21 @@ disassemble_current_function (int mixed)
#endif
low += gdbarch_deprecated_function_start_offset (gdbarch);
- print_disassembly (gdbarch, name, low, high, mixed);
+ print_disassembly (gdbarch, name, low, high, mixed, code);
}
/* Dump a specified section of assembly code.
Usage:
- disassemble [/m]
+ disassemble [/mc]
- dump the assembly code for the function of the current pc
- disassemble [/m] addr
+ disassemble [/mc] addr
- dump the assembly code for the function at ADDR
- disassemble [/m] low high
+ disassemble [/mc] low high
- dump the assembly code in the range [LOW,HIGH)
- A /m modifier will include source code with the assembly. */
+ A /m modifier will include source code with the assembly.
+ A /c modifier will include binary code with the assembly. */
static void
disassemble_command (char *arg, int from_tty)
@@ -985,9 +986,11 @@ disassemble_command (char *arg, int from
CORE_ADDR pc, pc_masked;
char *space_index;
int mixed_source_and_assembly;
+ int code;
name = NULL;
mixed_source_and_assembly = 0;
+ code = 0;
if (arg && *arg == '/')
{
@@ -1003,6 +1006,9 @@ disassemble_command (char *arg, int from
case 'm':
mixed_source_and_assembly = 1;
break;
+ case 'c':
+ code = 1;
+ break;
default:
error (_("Invalid disassembly modifier."));
}
@@ -1014,7 +1020,7 @@ disassemble_command (char *arg, int from
if (! arg || ! *arg)
{
- disassemble_current_function (mixed_source_and_assembly);
+ disassemble_current_function (mixed_source_and_assembly, code);
return;
}
@@ -1044,7 +1050,7 @@ disassemble_command (char *arg, int from
high = parse_and_eval_address (space_index + 1);
}
- print_disassembly (gdbarch, name, low, high, mixed_source_and_assembly);
+ print_disassembly (gdbarch, name, low, high, mixed_source_and_assembly, code);
}
static void
@@ -1453,6 +1459,7 @@ With two args if one is empty it stands Disassemble a specified section of memory.\n\
Default is the function surrounding the pc of the selected frame.\n\
With a /m modifier, source lines are included (if available).\n\
+With a /c modifier, binary code are included.\n\
With a single argument, the function surrounding that address is dumped.\n\
Two arguments are taken as a range of memory to dump."));
set_cmd_completer (c, location_completer);
--- a/disasm.c
+++ b/disasm.c
@@ -88,7 +88,7 @@ static int
dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
struct disassemble_info * di,
CORE_ADDR low, CORE_ADDR high,
- int how_many, struct ui_stream *stb)
+ int how_many, int code, struct ui_stream *stb)
{
int num_displayed = 0;
CORE_ADDR pc;
@@ -135,7 +135,23 @@ dump_insns (struct gdbarch *gdbarch, str
xfree (name);
ui_file_rewind (stb->stream);
- pc += gdbarch_print_insn (gdbarch, pc, di);
+ if (code)
+ {
+ CORE_ADDR old_pc = pc;
+ bfd_byte data;
+ int status;
+ pc += gdbarch_print_insn (gdbarch, pc, di);
+ for (;old_pc < pc; old_pc++)
+ {
+ status = (*di->read_memory_func) (old_pc, &data, 1, di);
+ if (status != 0)
+ (*di->memory_error_func) (status, old_pc, di);
+ ui_out_message (uiout, 0, " %02x", (unsigned)data);
+ }
+ ui_out_text (uiout, "\t");
+ }
+ else
+ pc += gdbarch_print_insn (gdbarch, pc, di);
ui_out_field_stream (uiout, "inst", stb);
ui_file_rewind (stb->stream);
do_cleanups (ui_out_chain);
@@ -154,7 +170,7 @@ do_mixed_source_and_assembly (struct gdb
struct linetable_entry *le,
CORE_ADDR low, CORE_ADDR high,
struct symtab *symtab,
- int how_many, struct ui_stream *stb)
+ int how_many, int code, struct ui_stream *stb)
{
int newlines = 0;
struct dis_line_entry *mle;
@@ -278,7 +294,7 @@ do_mixed_source_and_assembly (struct gdb
num_displayed += dump_insns (gdbarch, uiout, di,
mle[i].start_pc, mle[i].end_pc,
- how_many, stb);
+ how_many, code, stb);
/* When we've reached the end of the mle array, or we've seen the last
assembly range for this source line, close out the list/tuple. */
@@ -301,14 +317,15 @@ static void
do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
struct disassemble_info * di,
CORE_ADDR low, CORE_ADDR high,
- int how_many, struct ui_stream *stb)
+ int how_many, int code, struct ui_stream *stb)
{
int num_displayed = 0;
struct cleanup *ui_out_chain;
ui_out_chain = make_cleanup_ui_out_list_begin_end (uiout, "asm_insns");
- num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many, stb);
+ num_displayed = dump_insns (gdbarch, uiout, di, low, high, how_many,
+ code, stb);
do_cleanups (ui_out_chain);
}
@@ -357,7 +374,7 @@ void
gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
char *file_string,
int mixed_source_and_assembly,
- int how_many, CORE_ADDR low, CORE_ADDR high)
+ int how_many, int code, CORE_ADDR low, CORE_ADDR high)
{
struct ui_stream *stb = ui_out_stream_new (uiout);
struct cleanup *cleanups = make_cleanup_ui_out_stream_delete (stb);
@@ -379,11 +396,11 @@ gdb_disassembly (struct gdbarch *gdbarch
if (!mixed_source_and_assembly || nlines <= 0
|| symtab == NULL || symtab->linetable == NULL)
- do_assembly_only (gdbarch, uiout, &di, low, high, how_many, stb);
+ do_assembly_only (gdbarch, uiout, &di, low, high, how_many, code, stb);
else if (mixed_source_and_assembly)
do_mixed_source_and_assembly (gdbarch, uiout, &di, nlines, le, low,
- high, symtab, how_many, stb);
+ high, symtab, how_many, code, stb);
do_cleanups (cleanups);
gdb_flush (gdb_stdout);
--- a/disasm.h
+++ b/disasm.h
@@ -25,7 +25,8 @@ struct ui_file;
extern void gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
char *file_string,
int mixed_source_and_assembly,
- int how_many, CORE_ADDR low, CORE_ADDR high);
+ int how_many, int code, CORE_ADDR low,
+ CORE_ADDR high);
/* Print the instruction at address MEMADDR in debugged memory,
on STREAM. Returns the length of the instruction, in bytes,
--- a/mi/mi-cmd-disas.c
+++ b/mi/mi-cmd-disas.c
@@ -156,6 +156,6 @@ mi_cmd_disassemble (char *command, char gdb_disassembly (gdbarch, uiout,
file_string,
- mixed_source_and_assembly, how_many, low, high);
+ mixed_source_and_assembly, 0, how_many, low, high);
}
--- a/stack.c
+++ b/stack.c
@@ -481,7 +481,7 @@ static void
gdb_disassembly_stub (void *args)
{
struct gdb_disassembly_stub_args *p = args;
- gdb_disassembly (p->gdbarch, uiout, 0, 0, p->how_many, p->low, p->high);
+ gdb_disassembly (p->gdbarch, uiout, 0, 0, 1, p->how_many, p->low, p->high);
}
/* Use TRY_CATCH to catch the exception from the gdb_disassembly



------------------------------------------------------------------------


---
 doc/gdb.texinfo |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

--- a/doc/gdb.texinfo
+++ b/doc/gdb.texinfo
@@ -6177,10 +6177,11 @@ Variables}).
 @cindex machine instructions
 @cindex listing machine instructions
 @item disassemble
-@itemx disassemble /m
+@itemx disassemble /mc
 This specialized command dumps a range of memory as machine
 instructions.  It can also print mixed source+disassembly by specifying
-the @code{/m} modifier.
+the @code{/m} modifier and print binary code by specifying
+the @code{/c}.
 The default memory range is the function surrounding the
 program counter of the selected frame.  A single argument to this
 command is a program counter value; @value{GDBN} dumps the function


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]