disasm: split dump_insns
authorMarkus Metzger <markus.t.metzger@intel.com>
Mon, 12 Oct 2015 11:43:42 +0000 (13:43 +0200)
committerMarkus Metzger <markus.t.metzger@intel.com>
Wed, 4 Nov 2015 08:11:01 +0000 (09:11 +0100)
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
gdb/disasm.c

index b098a63975b6f2705a6caa40ac9ead651a7ea3d8..5bf629829d7aa479eec9ac280e50ef40b44c1297 100644 (file)
@@ -1,3 +1,8 @@
+2015-11-04  Markus Metzger  <markus.t.metzger@intel.com>
+
+       * disasm.c (dump_insns): Split into this and ...
+       (gdb_pretty_print_insn): ... this.
+
 2015-11-03  Simon Marchi  <simon.marchi@polymtl.ca>
 
        * xtensa-linux-nat.c (supply_gregset_reg): Make static.
index c17574ebeea20a176c3280f27722d5b6c8351eef..a07467ed2a5ba182fcc69681866f24d339b86fed 100644 (file)
@@ -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;
 }