Use gdbpy_enter in py-param.c
[binutils-gdb.git] / gdb / disasm.c
index a07467ed2a5ba182fcc69681866f24d339b86fed..84a03e92881878fbd2777320725d150651d2c3dc 100644 (file)
@@ -1,6 +1,6 @@
 /* Disassemble support for GDB.
 
-   Copyright (C) 2000-2015 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;
@@ -170,12 +170,12 @@ 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.  */
+/* See disasm.h.  */
 
-static int
+int
 gdb_pretty_print_insn (struct gdbarch *gdbarch, struct ui_out *uiout,
-                      struct disassemble_info * di, CORE_ADDR pc, int flags,
+                      struct disassemble_info * di,
+                      const struct disasm_insn *insn, int flags,
                       struct ui_file *stb)
 {
   /* parts of the symbolic representation of the address */
@@ -186,27 +186,54 @@ gdb_pretty_print_insn (struct gdbarch *gdbarch, struct ui_out *uiout,
   struct cleanup *ui_out_chain;
   char *filename = NULL;
   char *name = NULL;
+  CORE_ADDR pc;
 
   ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
+  pc = insn->addr;
+
+  if (insn->number != 0)
+    {
+      uiout->field_fmt ("insn-number", "%u", insn->number);
+      uiout->text ("\t");
+    }
 
-  if ((flags & DISASSEMBLY_OMIT_PC) == 0)
-    ui_out_text (uiout, pc_prefix (pc));
-  ui_out_field_core_addr (uiout, "address", gdbarch, pc);
+  if ((flags & DISASSEMBLY_SPECULATIVE) != 0)
+    {
+      if (insn->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)
+           uiout->text (pc_prefix (pc) + 1);
+         else
+           uiout->text ("  ");
+       }
+      else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
+       uiout->text (pc_prefix (pc));
+      else
+       uiout->text ("   ");
+    }
+  else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
+    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);
@@ -240,18 +267,18 @@ gdb_pretty_print_insn (struct gdbarch *gdbarch, struct ui_out *uiout,
          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);
 
-  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;
 }
@@ -263,25 +290,29 @@ dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
            int how_many, int flags, struct ui_file *stb,
            CORE_ADDR *end_pc)
 {
+  struct disasm_insn insn;
   int num_displayed = 0;
 
-  while (low < high && (how_many < 0 || num_displayed < how_many))
+  memset (&insn, 0, sizeof (insn));
+  insn.addr = low;
+
+  while (insn.addr < high && (how_many < 0 || num_displayed < how_many))
     {
       int size;
 
-      size = gdb_pretty_print_insn (gdbarch, uiout, di, low, flags, stb);
+      size = gdb_pretty_print_insn (gdbarch, uiout, di, &insn, flags, stb);
       if (size <= 0)
        break;
 
       ++num_displayed;
-      low += size;
+      insn.addr += size;
 
       /* Allow user to bail out with ^C.  */
       QUIT;
     }
 
   if (end_pc != NULL)
-    *end_pc = low;
+    *end_pc = insn.addr;
 
   return num_displayed;
 }
@@ -309,7 +340,7 @@ do_mixed_source_and_assembly_deprecated
   int out_of_order = 0;
   int next_line = 0;
   int num_displayed = 0;
-  enum print_source_lines_flags psl_flags = 0;
+  print_source_lines_flags psl_flags = 0;
   struct cleanup *ui_out_chain;
   struct cleanup *ui_out_tuple_chain = make_cleanup (null_cleanup, 0);
   struct cleanup *ui_out_list_chain = make_cleanup (null_cleanup, 0);
@@ -443,7 +474,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;
@@ -463,14 +494,10 @@ do_mixed_source_and_assembly (struct gdbarch *gdbarch, struct ui_out *uiout,
                              CORE_ADDR low, CORE_ADDR high,
                              int how_many, int flags, struct ui_file *stb)
 {
-  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;
-  enum print_source_lines_flags psl_flags = 0;
+  print_source_lines_flags psl_flags = 0;
   struct cleanup *cleanups;
   struct cleanup *ui_out_chain;
   struct cleanup *ui_out_tuple_chain;
@@ -521,7 +548,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, sal.symtab, sal.line);
     }
 
   /* Second pass: print the disassembly.
@@ -562,7 +589,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;
@@ -622,7 +648,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);
@@ -637,12 +663,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)
            {
@@ -674,7 +699,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");
        }
@@ -688,7 +713,7 @@ 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,
@@ -712,13 +737,11 @@ do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
                  CORE_ADDR low, CORE_ADDR high,
                  int how_many, int flags, struct ui_file *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,
-                              flags, stb, NULL);
+  dump_insns (gdbarch, uiout, di, low, high, how_many, flags, stb, NULL);
 
   do_cleanups (ui_out_chain);
 }
@@ -774,7 +797,6 @@ gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
   struct cleanup *cleanups = make_cleanup_ui_file_delete (stb);
   struct disassemble_info di = gdb_disassemble_info (gdbarch, stb);
   struct symtab *symtab;
-  struct linetable_entry *le = NULL;
   int nlines = -1;
 
   /* Assume symtab is valid for whole PC range.  */