Remove unused file_string parameter in gdb_disassembly
[deliverable/binutils-gdb.git] / gdb / disasm.c
index 940592864387c83a71a977398556c18db178807a..9d36f151f30444a60086f491b055fbf97e82f6e5 100644 (file)
@@ -1,6 +1,6 @@
 /* Disassemble support for GDB.
 
-   Copyright (C) 2000-2016 Free Software Foundation, Inc.
+   Copyright (C) 2000-2017 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -25,6 +25,7 @@
 #include "gdbcore.h"
 #include "dis-asm.h"
 #include "source.h"
+#include <algorithm>
 
 /* Disassemble functions.
    FIXME: We should get rid of all the duplicate code in gdb that does
@@ -86,11 +87,10 @@ allocate_dis_line_table (void)
                            xfree, xcalloc, xfree);
 }
 
-/* Add DLE to TABLE.
-   Returns 1 if added, 0 if already present.  */
+/* Add a new dis_line_entry containing SYMTAB and LINE to TABLE.  */
 
 static void
-maybe_add_dis_line_entry (htab_t table, struct symtab *symtab, int line)
+add_dis_line_entry (htab_t table, struct symtab *symtab, int line)
 {
   void **slot;
   struct dis_line_entry dle, *dlep;
@@ -119,29 +119,38 @@ line_has_code_p (htab_t table, struct symtab *symtab, int line)
   return htab_find (table, &dle) != NULL;
 }
 
-/* Like target_read_memory, but slightly different parameters.  */
-static int
-dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len,
-                    struct disassemble_info *info)
+/* Wrapper of target_read_code.  */
+
+int
+gdb_disassembler::dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr,
+                                      unsigned int len,
+                                      struct disassemble_info *info)
 {
   return target_read_code (memaddr, myaddr, len);
 }
 
-/* Like memory_error with slightly different parameters.  */
-static void
-dis_asm_memory_error (int err, bfd_vma memaddr,
-                     struct disassemble_info *info)
+/* Wrapper of memory_error.  */
+
+void
+gdb_disassembler::dis_asm_memory_error (int err, bfd_vma memaddr,
+                                       struct disassemble_info *info)
 {
-  memory_error (TARGET_XFER_E_IO, memaddr);
+  gdb_disassembler *self
+    = static_cast<gdb_disassembler *>(info->application_data);
+
+  self->m_err_memaddr = memaddr;
 }
 
-/* Like print_address with slightly different parameters.  */
-static void
-dis_asm_print_address (bfd_vma addr, struct disassemble_info *info)
+/* Wrapper of print_address.  */
+
+void
+gdb_disassembler::dis_asm_print_address (bfd_vma addr,
+                                        struct disassemble_info *info)
 {
-  struct gdbarch *gdbarch = (struct gdbarch *) info->application_data;
+  gdb_disassembler *self
+    = static_cast<gdb_disassembler *>(info->application_data);
 
-  print_address (gdbarch, addr, (struct ui_file *) info->stream);
+  print_address (self->arch (), addr, self->stream ());
 }
 
 static int
@@ -173,10 +182,9 @@ compare_lines (const void *mle1p, const void *mle2p)
 /* See disasm.h.  */
 
 int
-gdb_pretty_print_insn (struct gdbarch *gdbarch, struct ui_out *uiout,
-                      struct disassemble_info * di,
-                      const struct disasm_insn *insn, int flags,
-                      struct ui_file *stb)
+gdb_disassembler::pretty_print_insn (struct ui_out *uiout,
+                                    const struct disasm_insn *insn,
+                                    int flags)
 {
   /* parts of the symbolic representation of the address */
   int unmapped;
@@ -187,53 +195,55 @@ gdb_pretty_print_insn (struct gdbarch *gdbarch, struct ui_out *uiout,
   char *filename = NULL;
   char *name = NULL;
   CORE_ADDR pc;
+  struct ui_file *stb = stream ();
+  struct gdbarch *gdbarch = arch ();
 
   ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
   pc = insn->addr;
 
   if (insn->number != 0)
     {
-      ui_out_field_fmt (uiout, "insn-number", "%u", insn->number);
-      ui_out_text (uiout, "\t");
+      uiout->field_fmt ("insn-number", "%u", insn->number);
+      uiout->text ("\t");
     }
 
   if ((flags & DISASSEMBLY_SPECULATIVE) != 0)
     {
       if (insn->is_speculative)
        {
-         ui_out_field_string (uiout, "is-speculative", "?");
+         uiout->field_string ("is-speculative", "?");
 
          /* The speculative execution indication overwrites the first
             character of the PC prefix.
             We assume a PC prefix length of 3 characters.  */
          if ((flags & DISASSEMBLY_OMIT_PC) == 0)
-           ui_out_text (uiout, pc_prefix (pc) + 1);
+           uiout->text (pc_prefix (pc) + 1);
          else
-           ui_out_text (uiout, "  ");
+           uiout->text ("  ");
        }
       else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
-       ui_out_text (uiout, pc_prefix (pc));
+       uiout->text (pc_prefix (pc));
       else
-       ui_out_text (uiout, "   ");
+       uiout->text ("   ");
     }
   else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
-    ui_out_text (uiout, pc_prefix (pc));
-  ui_out_field_core_addr (uiout, "address", gdbarch, pc);
+    uiout->text (pc_prefix (pc));
+  uiout->field_core_addr ("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, " <");
+      uiout->text (" <");
       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");
+       uiout->field_string ("func-name", name);
+      uiout->text ("+");
+      uiout->field_int ("offset", offset);
+      uiout->text (">:\t");
     }
   else
-    ui_out_text (uiout, ":\t");
+    uiout->text (":\t");
 
   if (filename != NULL)
     xfree (filename);
@@ -254,40 +264,39 @@ gdb_pretty_print_insn (struct gdbarch *gdbarch, struct ui_out *uiout,
       struct cleanup *cleanups =
        make_cleanup_ui_file_delete (opcode_stream);
 
-      size = gdbarch_print_insn (gdbarch, pc, di);
+      size = print_insn (pc);
       end_pc = pc + size;
 
       for (;pc < end_pc; ++pc)
        {
-         err = (*di->read_memory_func) (pc, &data, 1, di);
+         err = m_di.read_memory_func (pc, &data, 1, &m_di);
          if (err != 0)
-           (*di->memory_error_func) (err, pc, di);
+           m_di.memory_error_func (err, pc, &m_di);
          fprintf_filtered (opcode_stream, "%s%02x",
                            spacer, (unsigned) data);
          spacer = " ";
        }
 
-      ui_out_field_stream (uiout, "opcodes", opcode_stream);
-      ui_out_text (uiout, "\t");
+      uiout->field_stream ("opcodes", opcode_stream);
+      uiout->text ("\t");
 
       do_cleanups (cleanups);
     }
   else
-    size = gdbarch_print_insn (gdbarch, pc, di);
+    size = print_insn (pc);
 
-  ui_out_field_stream (uiout, "inst", stb);
+  uiout->field_stream ("inst", stb);
   ui_file_rewind (stb);
   do_cleanups (ui_out_chain);
-  ui_out_text (uiout, "\n");
+  uiout->text ("\n");
 
   return size;
 }
 
 static int
-dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
-           struct disassemble_info * di,
+dump_insns (struct ui_out *uiout, gdb_disassembler *di,
            CORE_ADDR low, CORE_ADDR high,
-           int how_many, int flags, struct ui_file *stb,
+           int how_many, int flags,
            CORE_ADDR *end_pc)
 {
   struct disasm_insn insn;
@@ -300,7 +309,7 @@ dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
     {
       int size;
 
-      size = gdb_pretty_print_insn (gdbarch, uiout, di, &insn, flags, stb);
+      size = di->pretty_print_insn (uiout, &insn, flags);
       if (size <= 0)
        break;
 
@@ -326,10 +335,10 @@ dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
 
 static void
 do_mixed_source_and_assembly_deprecated
-  (struct gdbarch *gdbarch, struct ui_out *uiout,
-   struct disassemble_info *di, struct symtab *symtab,
+  (struct ui_out *uiout,
+   gdb_disassembler *di, struct symtab *symtab,
    CORE_ADDR low, CORE_ADDR high,
-   int how_many, int flags, struct ui_file *stb)
+   int how_many, int flags)
 {
   int newlines = 0;
   int nlines;
@@ -462,9 +471,9 @@ do_mixed_source_and_assembly_deprecated
            = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
        }
 
-      num_displayed += dump_insns (gdbarch, uiout, di,
+      num_displayed += dump_insns (uiout, di,
                                   mle[i].start_pc, mle[i].end_pc,
-                                  how_many, flags, stb, NULL);
+                                  how_many, flags, NULL);
 
       /* 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.  */
@@ -474,7 +483,7 @@ do_mixed_source_and_assembly_deprecated
          do_cleanups (ui_out_tuple_chain);
          ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
          ui_out_list_chain = make_cleanup (null_cleanup, 0);
-         ui_out_text (uiout, "\n");
+         uiout->text ("\n");
        }
       if (how_many >= 0 && num_displayed >= how_many)
        break;
@@ -488,28 +497,23 @@ do_mixed_source_and_assembly_deprecated
    immediately following.  */
 
 static void
-do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
-                             struct disassemble_info *di,
+do_mixed_source_and_assembly (struct gdbarch *gdbarch,
+                             struct ui_out *uiout,
+                             gdb_disassembler *di,
                              struct symtab *main_symtab,
                              CORE_ADDR low, CORE_ADDR high,
-                             int how_many, int flags, struct ui_file *stb)
+                             int how_many, int flags)
 {
-  int newlines = 0;
   const struct linetable_entry *le, *first_le;
-  struct symtab_and_line sal;
   int i, nlines;
-  int out_of_order = 0;
-  int next_line = 0;
   int num_displayed = 0;
   print_source_lines_flags psl_flags = 0;
-  struct cleanup *cleanups;
   struct cleanup *ui_out_chain;
   struct cleanup *ui_out_tuple_chain;
   struct cleanup *ui_out_list_chain;
   CORE_ADDR pc;
   struct symtab *last_symtab;
   int last_line;
-  htab_t dis_line_table;
 
   gdb_assert (main_symtab != NULL && SYMTAB_LINETABLE (main_symtab) != NULL);
 
@@ -519,8 +523,7 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
      but if that text is for code that will be disassembled later, then
      we'll want to defer printing it until later with its associated code.  */
 
-  dis_line_table = allocate_dis_line_table ();
-  cleanups = make_cleanup_htab_delete (dis_line_table);
+  htab_up dis_line_table (allocate_dis_line_table ());
 
   pc = low;
 
@@ -552,7 +555,7 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
       pc += length;
 
       if (sal.symtab != NULL)
-       maybe_add_dis_line_entry (dis_line_table, sal.symtab, sal.line);
+       add_dis_line_entry (dis_line_table.get (), sal.symtab, sal.line);
     }
 
   /* Second pass: print the disassembly.
@@ -569,9 +572,6 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
      which is where we put file name and source line contents output.
 
      Cleanup usage:
-     cleanups:
-       For things created at the beginning of this function and need to be
-       kept until the end of this function.
      ui_out_chain
        Handles the outer "asm_insns" list.
      ui_out_tuple_chain
@@ -593,7 +593,6 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
 
   while (pc < high)
     {
-      struct linetable_entry *le = NULL;
       struct symtab_and_line sal;
       CORE_ADDR end_pc;
       int start_preceding_line_to_display = 0;
@@ -630,7 +629,8 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
                     not associated with code that we'll print later.  */
                  for (l = sal.line - 1; l > last_line; --l)
                    {
-                     if (line_has_code_p (dis_line_table, sal.symtab, l))
+                     if (line_has_code_p (dis_line_table.get (),
+                                          sal.symtab, l))
                        break;
                    }
                  if (l < sal.line - 1)
@@ -653,7 +653,7 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
        {
          /* Skip the newline if this is the first instruction.  */
          if (pc > low)
-           ui_out_text (uiout, "\n");
+           uiout->text ("\n");
          if (ui_out_tuple_chain != NULL)
            {
              gdb_assert (ui_out_list_chain != NULL);
@@ -668,12 +668,11 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
                 output includes the source specs for each line.  */
              if (sal.symtab != NULL)
                {
-                 ui_out_text (uiout,
-                              symtab_to_filename_for_display (sal.symtab));
+                 uiout->text (symtab_to_filename_for_display (sal.symtab));
                }
              else
-               ui_out_text (uiout, "unknown");
-             ui_out_text (uiout, ":\n");
+               uiout->text ("unknown");
+             uiout->text (":\n");
            }
          if (start_preceding_line_to_display > 0)
            {
@@ -705,7 +704,7 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
          if (sal.symtab != NULL)
            print_source_lines (sal.symtab, sal.line, sal.line + 1, psl_flags);
          else
-           ui_out_text (uiout, _("--- no source info for this pc ---\n"));
+           uiout->text (_("--- no source info for this pc ---\n"));
          ui_out_list_chain
            = make_cleanup_ui_out_list_begin_end (uiout, "line_asm_insn");
        }
@@ -719,11 +718,11 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
        }
 
       if (sal.end != 0)
-       end_pc = min (sal.end, high);
+       end_pc = std::min (sal.end, high);
       else
        end_pc = pc + 1;
-      num_displayed += dump_insns (gdbarch, uiout, di, pc, end_pc,
-                                  how_many, flags, stb, &end_pc);
+      num_displayed += dump_insns (uiout, di, pc, end_pc,
+                                  how_many, flags, &end_pc);
       pc = end_pc;
 
       if (how_many >= 0 && num_displayed >= how_many)
@@ -734,22 +733,19 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
     }
 
   do_cleanups (ui_out_chain);
-  do_cleanups (cleanups);
 }
 
 static void
-do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
-                 struct disassemble_info * di,
+do_assembly_only (struct ui_out *uiout,
+                 gdb_disassembler *di,
                  CORE_ADDR low, CORE_ADDR high,
-                 int how_many, int flags, struct ui_file *stb)
+                 int how_many, int flags)
 {
-  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,
-                              flags, stb, NULL);
+  dump_insns (uiout, di, low, high, how_many, flags, NULL);
 
   do_cleanups (ui_out_chain);
 }
@@ -769,15 +765,16 @@ fprintf_disasm (void *stream, const char *format, ...)
   return 0;
 }
 
-struct disassemble_info
-gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file)
+gdb_disassembler::gdb_disassembler (struct gdbarch *gdbarch,
+                                   struct ui_file *file,
+                                   di_read_memory_ftype read_memory_func)
+  : m_gdbarch (gdbarch),
+    m_err_memaddr (0)
 {
-  struct disassemble_info di;
-
-  init_disassemble_info (&di, file, fprintf_disasm);
-  di.flavour = bfd_target_unknown_flavour;
-  di.memory_error_func = dis_asm_memory_error;
-  di.print_address_func = dis_asm_print_address;
+  init_disassemble_info (&m_di, file, fprintf_disasm);
+  m_di.flavour = bfd_target_unknown_flavour;
+  m_di.memory_error_func = dis_asm_memory_error;
+  m_di.print_address_func = dis_asm_print_address;
   /* NOTE: cagney/2003-04-28: The original code, from the old Insight
      disassembler had a local optomization here.  By default it would
      access the executable file, instead of the target memory (there
@@ -786,26 +783,45 @@ gdb_disassemble_info (struct gdbarch *gdbarch, struct ui_file *file)
      didn't work as they relied on the access going to the target.
      Further, it has been supperseeded by trust-read-only-sections
      (although that should be superseeded by target_trust..._p()).  */
-  di.read_memory_func = dis_asm_read_memory;
-  di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
-  di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
-  di.endian = gdbarch_byte_order (gdbarch);
-  di.endian_code = gdbarch_byte_order_for_code (gdbarch);
-  di.application_data = gdbarch;
-  disassemble_init_for_target (&di);
-  return di;
+  m_di.read_memory_func = read_memory_func;
+  m_di.arch = gdbarch_bfd_arch_info (gdbarch)->arch;
+  m_di.mach = gdbarch_bfd_arch_info (gdbarch)->mach;
+  m_di.endian = gdbarch_byte_order (gdbarch);
+  m_di.endian_code = gdbarch_byte_order_for_code (gdbarch);
+  m_di.application_data = this;
+  disassemble_init_for_target (&m_di);
+}
+
+int
+gdb_disassembler::print_insn (CORE_ADDR memaddr,
+                             int *branch_delay_insns)
+{
+  m_err_memaddr = 0;
+
+  int length = gdbarch_print_insn (arch (), memaddr, &m_di);
+
+  if (length < 0)
+    memory_error (TARGET_XFER_E_IO, m_err_memaddr);
+
+  if (branch_delay_insns != NULL)
+    {
+      if (m_di.insn_info_valid)
+       *branch_delay_insns = m_di.branch_delay_insns;
+      else
+       *branch_delay_insns = 0;
+    }
+  return length;
 }
 
 void
 gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
-                char *file_string, int flags, int how_many,
+                int flags, int how_many,
                 CORE_ADDR low, CORE_ADDR high)
 {
   struct ui_file *stb = mem_fileopen ();
   struct cleanup *cleanups = make_cleanup_ui_file_delete (stb);
-  struct disassemble_info di = gdb_disassemble_info (gdbarch, stb);
+  gdb_disassembler di (gdbarch, stb);
   struct symtab *symtab;
-  struct linetable_entry *le = NULL;
   int nlines = -1;
 
   /* Assume symtab is valid for whole PC range.  */
@@ -816,15 +832,15 @@ gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
 
   if (!(flags & (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
       || nlines <= 0)
-    do_assembly_only (gdbarch, uiout, &di, low, high, how_many, flags, stb);
+    do_assembly_only (uiout, &di, low, high, how_many, flags);
 
   else if (flags & DISASSEMBLY_SOURCE)
     do_mixed_source_and_assembly (gdbarch, uiout, &di, symtab, low, high,
-                                 how_many, flags, stb);
+                                 how_many, flags);
 
   else if (flags & DISASSEMBLY_SOURCE_DEPRECATED)
-    do_mixed_source_and_assembly_deprecated (gdbarch, uiout, &di, symtab,
-                                            low, high, how_many, flags, stb);
+    do_mixed_source_and_assembly_deprecated (uiout, &di, symtab,
+                                            low, high, how_many, flags);
 
   do_cleanups (cleanups);
   gdb_flush (gdb_stdout);
@@ -838,25 +854,10 @@ int
 gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
                struct ui_file *stream, int *branch_delay_insns)
 {
-  struct disassemble_info di;
-  int length;
 
-  di = gdb_disassemble_info (gdbarch, stream);
-  length = gdbarch_print_insn (gdbarch, memaddr, &di);
-  if (branch_delay_insns)
-    {
-      if (di.insn_info_valid)
-       *branch_delay_insns = di.branch_delay_insns;
-      else
-       *branch_delay_insns = 0;
-    }
-  return length;
-}
+  gdb_disassembler di (gdbarch, stream);
 
-static void
-do_ui_file_delete (void *arg)
-{
-  ui_file_delete ((struct ui_file *) arg);
+  return di.print_insn (memaddr, branch_delay_insns);
 }
 
 /* Return the length in bytes of the instruction at address MEMADDR in
@@ -865,16 +866,7 @@ do_ui_file_delete (void *arg)
 int
 gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
 {
-  static struct ui_file *null_stream = NULL;
-
-  /* Dummy file descriptor for the disassembler.  */
-  if (!null_stream)
-    {
-      null_stream = ui_file_new ();
-      make_final_cleanup (do_ui_file_delete, null_stream);
-    }
-
-  return gdb_print_insn (gdbarch, addr, null_stream, NULL);
+  return gdb_print_insn (gdbarch, addr, null_stream (), NULL);
 }
 
 /* fprintf-function for gdb_buffered_insn_length.  This function is a
This page took 0.032086 seconds and 4 git commands to generate.