From af70908dc41c8bf21680aeb2f849ce4043b2031a Mon Sep 17 00:00:00 2001 From: Markus Metzger Date: Mon, 12 Oct 2015 13:43:42 +0200 Subject: [PATCH] disasm: split dump_insns Split disasm.c's dump_insn into two parts: - print a single instruction - loop over the specified address range The first part will be refined in subsequent patches so it can be reused. gdb/ * disasm.c (dump_insns): Split into this and ... (gdb_pretty_print_insn): ... this. --- gdb/ChangeLog | 5 ++ gdb/disasm.c | 173 ++++++++++++++++++++++++++++---------------------- 2 files changed, 101 insertions(+), 77 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b098a63975..5bf629829d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2015-11-04 Markus Metzger + + * disasm.c (dump_insns): Split into this and ... + (gdb_pretty_print_insn): ... this. + 2015-11-03 Simon Marchi * xtensa-linux-nat.c (supply_gregset_reg): Make static. diff --git a/gdb/disasm.c b/gdb/disasm.c index c17574ebee..a07467ed2a 100644 --- a/gdb/disasm.c +++ b/gdb/disasm.c @@ -170,100 +170,119 @@ compare_lines (const void *mle1p, const void *mle2p) return val; } +/* Prints the instruction at PC into UIOUT and returns the length of the + printed instruction in bytes. */ + static int -dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout, - struct disassemble_info * di, - CORE_ADDR low, CORE_ADDR high, - int how_many, int flags, struct ui_file *stb, - CORE_ADDR *end_pc) +gdb_pretty_print_insn (struct gdbarch *gdbarch, struct ui_out *uiout, + struct disassemble_info * di, CORE_ADDR pc, int flags, + struct ui_file *stb) { - int num_displayed = 0; - CORE_ADDR pc; - /* parts of the symbolic representation of the address */ int unmapped; int offset; int line; + int size; struct cleanup *ui_out_chain; + char *filename = NULL; + char *name = NULL; + + ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); + + if ((flags & DISASSEMBLY_OMIT_PC) == 0) + ui_out_text (uiout, pc_prefix (pc)); + ui_out_field_core_addr (uiout, "address", gdbarch, pc); + + if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename, + &line, &unmapped)) + { + /* We don't care now about line, filename and unmapped. But we might in + the future. */ + ui_out_text (uiout, " <"); + if ((flags & DISASSEMBLY_OMIT_FNAME) == 0) + ui_out_field_string (uiout, "func-name", name); + ui_out_text (uiout, "+"); + ui_out_field_int (uiout, "offset", offset); + ui_out_text (uiout, ">:\t"); + } + else + ui_out_text (uiout, ":\t"); - for (pc = low; pc < high;) + if (filename != NULL) + xfree (filename); + if (name != NULL) + xfree (name); + + ui_file_rewind (stb); + if (flags & DISASSEMBLY_RAW_INSN) { - char *filename = NULL; - char *name = NULL; + CORE_ADDR end_pc; + bfd_byte data; + int err; + const char *spacer = ""; - QUIT; - if (how_many >= 0) - { - if (num_displayed >= how_many) - break; - else - num_displayed++; - } - ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL); + /* Build the opcodes using a temporary stream so we can + write them out in a single go for the MI. */ + struct ui_file *opcode_stream = mem_fileopen (); + struct cleanup *cleanups = + make_cleanup_ui_file_delete (opcode_stream); - if ((flags & DISASSEMBLY_OMIT_PC) == 0) - ui_out_text (uiout, pc_prefix (pc)); - ui_out_field_core_addr (uiout, "address", gdbarch, pc); + size = gdbarch_print_insn (gdbarch, pc, di); + end_pc = pc + size; - if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename, - &line, &unmapped)) + for (;pc < end_pc; ++pc) { - /* We don't care now about line, filename and - unmapped. But we might in the future. */ - ui_out_text (uiout, " <"); - if ((flags & DISASSEMBLY_OMIT_FNAME) == 0) - ui_out_field_string (uiout, "func-name", name); - ui_out_text (uiout, "+"); - ui_out_field_int (uiout, "offset", offset); - ui_out_text (uiout, ">:\t"); + err = (*di->read_memory_func) (pc, &data, 1, di); + if (err != 0) + (*di->memory_error_func) (err, pc, di); + fprintf_filtered (opcode_stream, "%s%02x", + spacer, (unsigned) data); + spacer = " "; } - else - ui_out_text (uiout, ":\t"); - - if (filename != NULL) - xfree (filename); - if (name != NULL) - xfree (name); - - ui_file_rewind (stb); - if (flags & DISASSEMBLY_RAW_INSN) - { - CORE_ADDR old_pc = pc; - bfd_byte data; - int err; - const char *spacer = ""; - - /* Build the opcodes using a temporary stream so we can - write them out in a single go for the MI. */ - struct ui_file *opcode_stream = mem_fileopen (); - struct cleanup *cleanups = - make_cleanup_ui_file_delete (opcode_stream); - - pc += gdbarch_print_insn (gdbarch, pc, di); - for (;old_pc < pc; old_pc++) - { - err = (*di->read_memory_func) (old_pc, &data, 1, di); - if (err != 0) - (*di->memory_error_func) (err, old_pc, di); - fprintf_filtered (opcode_stream, "%s%02x", - spacer, (unsigned) data); - spacer = " "; - } - ui_out_field_stream (uiout, "opcodes", opcode_stream); - ui_out_text (uiout, "\t"); - - do_cleanups (cleanups); - } - else - pc += gdbarch_print_insn (gdbarch, pc, di); - ui_out_field_stream (uiout, "inst", stb); - ui_file_rewind (stb); - do_cleanups (ui_out_chain); - ui_out_text (uiout, "\n"); + + ui_out_field_stream (uiout, "opcodes", opcode_stream); + ui_out_text (uiout, "\t"); + + do_cleanups (cleanups); + } + else + size = gdbarch_print_insn (gdbarch, pc, di); + + ui_out_field_stream (uiout, "inst", stb); + ui_file_rewind (stb); + do_cleanups (ui_out_chain); + ui_out_text (uiout, "\n"); + + return size; +} + +static int +dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout, + struct disassemble_info * di, + CORE_ADDR low, CORE_ADDR high, + int how_many, int flags, struct ui_file *stb, + CORE_ADDR *end_pc) +{ + int num_displayed = 0; + + while (low < high && (how_many < 0 || num_displayed < how_many)) + { + int size; + + size = gdb_pretty_print_insn (gdbarch, uiout, di, low, flags, stb); + if (size <= 0) + break; + + ++num_displayed; + low += size; + + /* Allow user to bail out with ^C. */ + QUIT; } if (end_pc != NULL) - *end_pc = pc; + *end_pc = low; + return num_displayed; } -- 2.34.1