/* 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.
#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
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;
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 */
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);
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;
}
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;
}
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);
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;
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;
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.
while (pc < high)
{
- struct linetable_entry *le = NULL;
struct symtab_and_line sal;
CORE_ADDR end_pc;
int start_preceding_line_to_display = 0;
{
/* 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);
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)
{
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");
}
}
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,
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);
}
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. */