+2009-07-11 Hui Zhu <teawater@gmail.com>
+
+ * cli/cli-cmds.c (disassemble_command): Add a new modifier /r
+ to "disassemble" command to print the raw instructions in hex as
+ well as in symbolic form.
+ (init_cli_cmds): Ditto.
+ (print_disassembly): Change "mixed" to "flags" to translate
+ the behavior of disassemble.
+ (disassemble_current_function): Ditto.
+ * mi/mi-cmd-disas.c (mi_cmd_disassemble): Ditto.
+ * stack.c (gdb_disassembly_stub): Ditto.
+ * disasm.c (do_mixed_source_and_assembly): Ditto.
+ (do_mixed_source_and_assembly): Ditto.
+ (do_assembly_only): Ditto.
+ (gdb_disassembly): Ditto.
+ (dump_insns): print the raw instructions in hex as well as in
+ symbolic form if DISASSEMBLY_RAW_INSN and flags is true.
+ * disasm.h (DISASSEMBLY_SOURCE): Include source code with the
+ assembly if it and flags is true.
+ (DISASSEMBLY_RAW_INSN): Include the raw instructions in hex with
+ the assembly if it and flags is true.
+ (gdb_disassembly): Update extern.
+ * NEWS: Document disassemble/r support.
+
2009-07-10 Tom Tromey <tromey@redhat.com>
* dwarf2-frame.c: Include dwarf2.h, not elf/dwarf2.h.
*** Changes since GDB 6.8
+* "disassemble" command with a /r modifier, print the raw instructions
+in hex as well as in symbolic form."
+
* Process record and replay
In a architecture environment that supports ``process record and
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 flags)
{
#if defined(TUI)
if (!tui_is_window_visible (DISASSEM_WIN))
paddress (gdbarch, low), paddress (gdbarch, high));
/* Dump the specified range. */
- gdb_disassembly (gdbarch, uiout, 0, mixed, -1, low, high);
+ gdb_disassembly (gdbarch, uiout, 0, flags, -1, low, high);
printf_filtered ("End of assembler dump.\n");
gdb_flush (gdb_stdout);
MIXED is non-zero to print source with the assembler. */
static void
-disassemble_current_function (int mixed)
+disassemble_current_function (int flags)
{
struct frame_info *frame;
struct gdbarch *gdbarch;
#endif
low += gdbarch_deprecated_function_start_offset (gdbarch);
- print_disassembly (gdbarch, name, low, high, mixed);
+ print_disassembly (gdbarch, name, low, high, flags);
}
/* Dump a specified section of assembly code.
Usage:
- disassemble [/m]
+ disassemble [/mr]
- dump the assembly code for the function of the current pc
- disassemble [/m] addr
+ disassemble [/mr] addr
- dump the assembly code for the function at ADDR
- disassemble [/m] low high
+ disassemble [/mr] 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 /r modifier will include raw instructions in hex with the assembly. */
static void
disassemble_command (char *arg, int from_tty)
char *name;
CORE_ADDR pc, pc_masked;
char *space_index;
- int mixed_source_and_assembly;
+ int flags;
name = NULL;
- mixed_source_and_assembly = 0;
+ flags = 0;
if (arg && *arg == '/')
{
switch (*arg++)
{
case 'm':
- mixed_source_and_assembly = 1;
+ flags |= DISASSEMBLY_SOURCE;
+ break;
+ case 'r':
+ flags |= DISASSEMBLY_RAW_INSN;
break;
default:
error (_("Invalid disassembly modifier."));
if (! arg || ! *arg)
{
- disassemble_current_function (mixed_source_and_assembly);
+ disassemble_current_function (flags);
return;
}
high = parse_and_eval_address (space_index + 1);
}
- print_disassembly (gdbarch, name, low, high, mixed_source_and_assembly);
+ print_disassembly (gdbarch, name, low, high, flags);
}
static void
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 /r modifier, raw instructions in hex 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);
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 flags, struct ui_stream *stb)
{
int num_displayed = 0;
CORE_ADDR pc;
xfree (name);
ui_file_rewind (stb->stream);
- pc += gdbarch_print_insn (gdbarch, pc, di);
+ if (flags & DISASSEMBLY_RAW_INSN)
+ {
+ 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);
struct linetable_entry *le,
CORE_ADDR low, CORE_ADDR high,
struct symtab *symtab,
- int how_many, struct ui_stream *stb)
+ int how_many, int flags, struct ui_stream *stb)
{
int newlines = 0;
struct dis_line_entry *mle;
num_displayed += dump_insns (gdbarch, uiout, di,
mle[i].start_pc, mle[i].end_pc,
- how_many, stb);
+ how_many, flags, 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. */
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 flags, 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,
+ flags, stb);
do_cleanups (ui_out_chain);
}
void
gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
char *file_string,
- int mixed_source_and_assembly,
+ int flags,
int how_many, CORE_ADDR low, CORE_ADDR high)
{
struct ui_stream *stb = ui_out_stream_new (uiout);
nlines = symtab->linetable->nitems;
}
- if (!mixed_source_and_assembly || nlines <= 0
+ if (!(flags & DISASSEMBLY_SOURCE) || 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, flags, stb);
- else if (mixed_source_and_assembly)
+ else if (flags & DISASSEMBLY_SOURCE)
do_mixed_source_and_assembly (gdbarch, uiout, &di, nlines, le, low,
- high, symtab, how_many, stb);
+ high, symtab, how_many, flags, stb);
do_cleanups (cleanups);
gdb_flush (gdb_stdout);
#ifndef DISASM_H
#define DISASM_H
+#define DISASSEMBLY_SOURCE (0x1 << 0)
+#define DISASSEMBLY_RAW_INSN (0x1 << 1)
+
struct ui_out;
struct ui_file;
gdb_disassembly (gdbarch, uiout,
file_string,
- mixed_source_and_assembly, how_many, low, high);
+ DISASSEMBLY_SOURCE, how_many, low, high);
}
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,
+ DISASSEMBLY_SOURCE | DISASSEMBLY_RAW_INSN, p->how_many,
+ p->low, p->high);
}
/* Use TRY_CATCH to catch the exception from the gdb_disassembly