/* Disassemble support for GDB.

   Copyright (C) 2000-2024 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "arch-utils.h"
#include "target.h"
#include "value.h"
#include "ui-out.h"
#include "disasm.h"
#include "gdbcore.h"
#include "gdbcmd.h"
#include "dis-asm.h"
#include "source.h"
#include "gdbsupport/gdb-safe-ctype.h"
#include <algorithm>
#include <optional>
#include "valprint.h"
#include "cli/cli-style.h"
#include "objfiles.h"
#include "inferior.h"

/* Disassemble functions.
   FIXME: We should get rid of all the duplicate code in gdb that does
   the same thing: disassemble_command() and the gdbtk variation.  */

/* This variable is used to hold the prospective disassembler_options value
   which is set by the "set disassembler_options" command.  */
static std::string prospective_options;

/* When this is true we will try to use libopcodes to provide styling to
   the disassembler output.  */

static bool use_libopcodes_styling = true;

/* To support the set_use_libopcodes_styling function we have a second
   variable which is connected to the actual set/show option.  */

static bool use_libopcodes_styling_option = use_libopcodes_styling;

/* The "maint show libopcodes-styling enabled" command.  */

static void
show_use_libopcodes_styling  (struct ui_file *file, int from_tty,
			      struct cmd_list_element *c,
			      const char *value)
{
  gdbarch *arch = current_inferior ()->arch ();
  gdb_non_printing_memory_disassembler dis (arch);
  bool supported = dis.disasm_info ()->created_styled_output;

  if (supported || !use_libopcodes_styling)
    gdb_printf (file, _("Use of libopcodes styling support is \"%s\".\n"),
		value);
  else
    {
      /* Use of libopcodes styling is not supported, and the user has this
	 turned on!  */
      gdb_printf (file, _("Use of libopcodes styling support is \"off\""
			  " (not supported on architecture \"%s\")\n"),
		  gdbarch_bfd_arch_info (arch)->printable_name);
    }
}

/* The "maint set libopcodes-styling enabled" command.  */

static void
set_use_libopcodes_styling (const char *args, int from_tty,
			    struct cmd_list_element *c)
{
  gdbarch *arch = current_inferior ()->arch ();
  gdb_non_printing_memory_disassembler dis (arch);
  bool supported = dis.disasm_info ()->created_styled_output;

  /* If the current architecture doesn't support libopcodes styling then we
     give an error here, but leave the underlying setting enabled.  This
     means that if the user switches to an architecture that does support
     libopcodes styling the setting will be enabled.  */

  if (use_libopcodes_styling_option && !supported)
    {
      use_libopcodes_styling_option = use_libopcodes_styling;
      error (_("Use of libopcodes styling not supported on architecture \"%s\"."),
	     gdbarch_bfd_arch_info (arch)->printable_name);
    }
  else
    use_libopcodes_styling = use_libopcodes_styling_option;
}

/* This structure is used to store line number information for the
   deprecated /m option.
   We need a different sort of line table from the normal one cuz we can't
   depend upon implicit line-end pc's for lines to do the
   reordering in this function.  */

struct deprecated_dis_line_entry
{
  int line;
  CORE_ADDR start_pc;
  CORE_ADDR end_pc;
};

/* This Structure is used to store line number information.
   We need a different sort of line table from the normal one cuz we can't
   depend upon implicit line-end pc's for lines to do the
   reordering in this function.  */

struct dis_line_entry
{
  struct symtab *symtab;
  int line;
};

/* Hash function for dis_line_entry.  */

static hashval_t
hash_dis_line_entry (const void *item)
{
  const struct dis_line_entry *dle = (const struct dis_line_entry *) item;

  return htab_hash_pointer (dle->symtab) + dle->line;
}

/* Equal function for dis_line_entry.  */

static int
eq_dis_line_entry (const void *item_lhs, const void *item_rhs)
{
  const struct dis_line_entry *lhs = (const struct dis_line_entry *) item_lhs;
  const struct dis_line_entry *rhs = (const struct dis_line_entry *) item_rhs;

  return (lhs->symtab == rhs->symtab
	  && lhs->line == rhs->line);
}

/* Create the table to manage lines for mixed source/disassembly.  */

static htab_t
allocate_dis_line_table (void)
{
  return htab_create_alloc (41,
			    hash_dis_line_entry, eq_dis_line_entry,
			    xfree, xcalloc, xfree);
}

/* Add a new dis_line_entry containing SYMTAB and LINE to TABLE.  */

static void
add_dis_line_entry (htab_t table, struct symtab *symtab, int line)
{
  void **slot;
  struct dis_line_entry dle, *dlep;

  dle.symtab = symtab;
  dle.line = line;
  slot = htab_find_slot (table, &dle, INSERT);
  if (*slot == NULL)
    {
      dlep = XNEW (struct dis_line_entry);
      dlep->symtab = symtab;
      dlep->line = line;
      *slot = dlep;
    }
}

/* Return non-zero if SYMTAB, LINE are in TABLE.  */

static int
line_has_code_p (htab_t table, struct symtab *symtab, int line)
{
  struct dis_line_entry dle;

  dle.symtab = symtab;
  dle.line = line;
  return htab_find (table, &dle) != NULL;
}

/* Wrapper of target_read_code.  */

int
gdb_disassembler_memory_reader::dis_asm_read_memory
  (bfd_vma memaddr, gdb_byte *myaddr, unsigned int len,
   struct disassemble_info *info) noexcept
{
  return target_read_code (memaddr, myaddr, len);
}

/* Wrapper of memory_error.  */

void
gdb_disassembler::dis_asm_memory_error
  (int err, bfd_vma memaddr, struct disassemble_info *info) noexcept
{
  gdb_disassembler *self
    = static_cast<gdb_disassembler *>(info->application_data);

  self->m_err_memaddr.emplace (memaddr);
}

/* Wrapper of print_address.  */

void
gdb_disassembler::dis_asm_print_address
  (bfd_vma addr, struct disassemble_info *info) noexcept
{
  gdb_disassembler *self
    = static_cast<gdb_disassembler *>(info->application_data);

  if (self->in_comment_p ())
    {
      /* Calling 'print_address' might add styling to the output (based on
	 the properties of the stream we're writing too).  This is usually
	 fine, but if we are in an assembler comment then we'd prefer to
	 have the comment style, rather than the default address style.

	 Print the address into a temporary buffer which doesn't support
	 styling, then reprint this unstyled address with the default text
	 style.

	 As we are inside a comment right now, the standard print routine
	 will ensure that the comment is printed to the user with a
	 suitable comment style.  */
      string_file tmp;
      print_address (self->arch (), addr, &tmp);
      self->fprintf_styled_func (self, dis_style_text, "%s", tmp.c_str ());
    }
  else
    print_address (self->arch (), addr, self->stream ());
}

/* See disasm.h.  */

ui_file *
gdb_printing_disassembler::stream_from_gdb_disassemble_info (void *dis_info)
{
  gdb_disassemble_info *di = (gdb_disassemble_info *) dis_info;
  gdb_printing_disassembler *dis
    = gdb::checked_static_cast<gdb_printing_disassembler *> (di);
  ui_file *stream = dis->stream ();
  gdb_assert (stream != nullptr);
  return stream;
}

/* Format disassembler output to STREAM.  */

int
gdb_printing_disassembler::fprintf_func (void *dis_info,
					 const char *format, ...) noexcept
{
  ui_file *stream = stream_from_gdb_disassemble_info (dis_info);

  va_list args;
  va_start (args, format);
  gdb_vprintf (stream, format, args);
  va_end (args);

  /* Something non -ve.  */
  return 0;
}

/* See disasm.h.  */

int
gdb_printing_disassembler::fprintf_styled_func
  (void *dis_info, enum disassembler_style style,
   const char *format, ...) noexcept
{
  ui_file *stream = stream_from_gdb_disassemble_info (dis_info);
  gdb_printing_disassembler *dis = (gdb_printing_disassembler *) dis_info;

  va_list args;
  va_start (args, format);
  std::string content = string_vprintf (format, args);
  va_end (args);

  /* Once in a comment then everything should be styled as a comment.  */
  if (style == dis_style_comment_start)
    dis->set_in_comment (true);
  if (dis->in_comment_p ())
    style = dis_style_comment_start;

  /* Now print the content with the correct style.  */
  const char *txt = content.c_str ();
  switch (style)
    {
    case dis_style_mnemonic:
    case dis_style_sub_mnemonic:
    case dis_style_assembler_directive:
      fputs_styled (txt, disasm_mnemonic_style.style (), stream);
      break;

    case dis_style_register:
      fputs_styled (txt, disasm_register_style.style (), stream);
      break;

    case dis_style_immediate:
    case dis_style_address_offset:
      fputs_styled (txt, disasm_immediate_style.style (), stream);
      break;

    case dis_style_address:
      fputs_styled (txt, address_style.style (), stream);
      break;

    case dis_style_symbol:
      fputs_styled (txt, function_name_style.style (), stream);
      break;

    case dis_style_comment_start:
      fputs_styled (txt, disasm_comment_style.style (), stream);
      break;

    case dis_style_text:
      gdb_puts (txt, stream);
      break;
    }

  /* Something non -ve.  */
  return 0;
}

static bool
line_is_less_than (const deprecated_dis_line_entry &mle1,
		   const deprecated_dis_line_entry &mle2)
{
  bool val;

  /* End of sequence markers have a line number of 0 but don't want to
     be sorted to the head of the list, instead sort by PC.  */
  if (mle1.line == 0 || mle2.line == 0)
    {
      if (mle1.start_pc != mle2.start_pc)
	val = mle1.start_pc < mle2.start_pc;
      else
	val = mle1.line < mle2.line;
    }
  else
    {
      if (mle1.line != mle2.line)
	val = mle1.line < mle2.line;
      else
	val = mle1.start_pc < mle2.start_pc;
    }
  return val;
}

/* See disasm.h.  */

int
gdb_pretty_print_disassembler::pretty_print_insn (const struct disasm_insn *insn,
						  gdb_disassembly_flags flags)
{
  /* parts of the symbolic representation of the address */
  int unmapped;
  int offset;
  int line;
  int size;
  CORE_ADDR pc;
  struct gdbarch *gdbarch = arch ();

  {
    ui_out_emit_tuple tuple_emitter (m_uiout, NULL);
    pc = insn->addr;

    if (insn->number != 0)
      {
	m_uiout->field_unsigned ("insn-number", insn->number);
	m_uiout->text ("\t");
      }

    if ((flags & DISASSEMBLY_SPECULATIVE) != 0)
      {
	if (insn->is_speculative)
	  {
	    m_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)
	      m_uiout->text (pc_prefix (pc) + 1);
	    else
	      m_uiout->text ("  ");
	  }
	else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
	  m_uiout->text (pc_prefix (pc));
	else
	  m_uiout->text ("   ");
      }
    else if ((flags & DISASSEMBLY_OMIT_PC) == 0)
      m_uiout->text (pc_prefix (pc));
    m_uiout->field_core_addr ("address", gdbarch, pc);

    std::string name, filename;
    bool omit_fname = ((flags & DISASSEMBLY_OMIT_FNAME) != 0);
    if (!build_address_symbolic (gdbarch, pc, false, omit_fname, &name,
				 &offset, &filename, &line, &unmapped))
      {
	/* We don't care now about line, filename and unmapped.  But we might in
	   the future.  */
	m_uiout->text (" <");
	if (!omit_fname)
	  m_uiout->field_string ("func-name", name,
				 function_name_style.style ());
	/* For negative offsets, avoid displaying them as +-N; the sign of
	   the offset takes the place of the "+" here.  */
	if (offset >= 0)
	  m_uiout->text ("+");
	m_uiout->field_signed ("offset", offset);
	m_uiout->text (">:\t");
      }
    else
      m_uiout->text (":\t");

    /* Clear the buffer into which we will disassemble the instruction.  */
    m_insn_stb.clear ();

    /* A helper function to write the M_INSN_STB buffer, followed by a
       newline.  This can be called in a couple of situations.  */
    auto write_out_insn_buffer = [&] ()
    {
      m_uiout->field_stream ("inst", m_insn_stb);
      m_uiout->text ("\n");
    };

    try
      {
	/* Now we can disassemble the instruction.  If the disassembler
	   returns a negative value this indicates an error and is handled
	   within the print_insn call, resulting in an exception being
	   thrown.  Returning zero makes no sense, as this indicates we
	   disassembled something successfully, but it was something of no
	   size?  */
	size = m_di.print_insn (pc);
	gdb_assert (size > 0);
      }
    catch (const gdb_exception &)
      {
	/* An exception was thrown while disassembling the instruction.
	   However, the disassembler might still have written something
	   out, so ensure that we flush the instruction buffer before
	   rethrowing the exception.  We can't perform this write from an
	   object destructor as the write itself might throw an exception
	   if the pager kicks in, and the user selects quit.  */
	write_out_insn_buffer ();
	throw;
      }

    if ((flags & (DISASSEMBLY_RAW_INSN | DISASSEMBLY_RAW_BYTES)) != 0)
      {
	/* Build the opcodes using a temporary stream so we can
	   write them out in a single go for the MI.  */
	m_opcode_stb.clear ();

	/* Read the instruction opcode data.  */
	m_opcode_data.resize (size);
	read_code (pc, m_opcode_data.data (), size);

	/* The disassembler provides information about the best way to
	   display the instruction bytes to the user.  We provide some sane
	   defaults in case the disassembler gets it wrong.  */
	const struct disassemble_info *di = m_di.disasm_info ();
	int bytes_per_line = std::max (di->bytes_per_line, size);
	int bytes_per_chunk = std::max (di->bytes_per_chunk, 1);

	/* If the user has requested the instruction bytes be displayed
	   byte at a time, then handle that here.  Also, if the instruction
	   is not a multiple of the chunk size (which probably indicates a
	   disassembler problem) then avoid that causing display problems
	   by switching to byte at a time mode.  */
	if ((flags & DISASSEMBLY_RAW_BYTES) != 0
	    || (size % bytes_per_chunk) != 0)
	  bytes_per_chunk = 1;

	/* Print the instruction opcodes bytes, grouped into chunks.  */
	for (int i = 0; i < size; i += bytes_per_chunk)
	  {
	    if (i > 0)
	      m_opcode_stb.puts (" ");

	    if (di->display_endian == BFD_ENDIAN_LITTLE)
	      {
		for (int k = bytes_per_chunk; k-- != 0; )
		  m_opcode_stb.printf ("%02x", (unsigned) m_opcode_data[i + k]);
	      }
	    else
	      {
		for (int k = 0; k < bytes_per_chunk; k++)
		  m_opcode_stb.printf ("%02x", (unsigned) m_opcode_data[i + k]);
	      }
	  }

	/* Calculate required padding.  */
	int nspaces = 0;
	for (int i = size; i < bytes_per_line; i += bytes_per_chunk)
	  {
	    if (i > size)
	      nspaces++;
	    nspaces += bytes_per_chunk * 2;
	  }

	m_uiout->field_stream ("opcodes", m_opcode_stb);
	m_uiout->spaces (nspaces);
	m_uiout->text ("\t");
      }

    /* Disassembly was a success, write out the instruction buffer.  */
    write_out_insn_buffer ();
  }

  return size;
}

static int
dump_insns (struct gdbarch *gdbarch,
	    struct ui_out *uiout, CORE_ADDR low, CORE_ADDR high,
	    int how_many, gdb_disassembly_flags flags, CORE_ADDR *end_pc)
{
  struct disasm_insn insn;
  int num_displayed = 0;

  memset (&insn, 0, sizeof (insn));
  insn.addr = low;

  gdb_pretty_print_disassembler disasm (gdbarch, uiout);

  while (insn.addr < high && (how_many < 0 || num_displayed < how_many))
    {
      int size;

      size = disasm.pretty_print_insn (&insn, flags);
      if (size <= 0)
	break;

      ++num_displayed;
      insn.addr += size;

      /* Allow user to bail out with ^C.  */
      QUIT;
    }

  if (end_pc != NULL)
    *end_pc = insn.addr;

  return num_displayed;
}

/* The idea here is to present a source-O-centric view of a
   function to the user.  This means that things are presented
   in source order, with (possibly) out of order assembly
   immediately following.

   N.B. This view is deprecated.  */

static void
do_mixed_source_and_assembly_deprecated
  (struct gdbarch *gdbarch, struct ui_out *uiout,
   struct symtab *symtab,
   CORE_ADDR low, CORE_ADDR high,
   int how_many, gdb_disassembly_flags flags)
{
  int newlines = 0;
  int nlines;
  const struct linetable_entry *le;
  struct deprecated_dis_line_entry *mle;
  struct symtab_and_line sal;
  int i;
  int out_of_order = 0;
  int next_line = 0;
  int num_displayed = 0;
  print_source_lines_flags psl_flags = 0;

  gdb_assert (symtab != nullptr && symtab->linetable () != nullptr);

  nlines = symtab->linetable ()->nitems;
  le = symtab->linetable ()->item;

  if (flags & DISASSEMBLY_FILENAME)
    psl_flags |= PRINT_SOURCE_LINES_FILENAME;

  mle = (struct deprecated_dis_line_entry *)
    alloca (nlines * sizeof (struct deprecated_dis_line_entry));

  struct objfile *objfile = symtab->compunit ()->objfile ();

  unrelocated_addr unrel_low
    = unrelocated_addr (low - objfile->text_section_offset ());
  unrelocated_addr unrel_high
    = unrelocated_addr (high - objfile->text_section_offset ());

  /* Copy linetable entries for this function into our data
     structure, creating end_pc's and setting out_of_order as
     appropriate.  */

  /* First, skip all the preceding functions.  */

  for (i = 0; i < nlines - 1 && le[i].unrelocated_pc () < unrel_low; i++);

  /* Now, copy all entries before the end of this function.  */

  for (; i < nlines - 1 && le[i].unrelocated_pc () < unrel_high; i++)
    {
      if (le[i] == le[i + 1])
	continue;		/* Ignore duplicates.  */

      /* Skip any end-of-function markers.  */
      if (le[i].line == 0)
	continue;

      mle[newlines].line = le[i].line;
      if (le[i].line > le[i + 1].line)
	out_of_order = 1;
      mle[newlines].start_pc = le[i].pc (objfile);
      mle[newlines].end_pc = le[i + 1].pc (objfile);
      newlines++;
    }

  /* If we're on the last line, and it's part of the function,
     then we need to get the end pc in a special way.  */

  if (i == nlines - 1 && le[i].unrelocated_pc () < unrel_high)
    {
      mle[newlines].line = le[i].line;
      mle[newlines].start_pc = le[i].pc (objfile);
      sal = find_pc_line (le[i].pc (objfile), 0);
      mle[newlines].end_pc = sal.end;
      newlines++;
    }

  /* Now, sort mle by line #s (and, then by addresses within lines).  */

  if (out_of_order)
    std::sort (mle, mle + newlines, line_is_less_than);

  /* Now, for each line entry, emit the specified lines (unless
     they have been emitted before), followed by the assembly code
     for that line.  */

  ui_out_emit_list asm_insns_list (uiout, "asm_insns");

  std::optional<ui_out_emit_tuple> outer_tuple_emitter;
  std::optional<ui_out_emit_list> inner_list_emitter;

  for (i = 0; i < newlines; i++)
    {
      /* Print out everything from next_line to the current line.  */
      if (mle[i].line >= next_line)
	{
	  if (next_line != 0)
	    {
	      /* Just one line to print.  */
	      if (next_line == mle[i].line)
		{
		  outer_tuple_emitter.emplace (uiout, "src_and_asm_line");
		  print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
		}
	      else
		{
		  /* Several source lines w/o asm instructions associated.  */
		  for (; next_line < mle[i].line; next_line++)
		    {
		      ui_out_emit_tuple tuple_emitter (uiout,
						       "src_and_asm_line");
		      print_source_lines (symtab, next_line, next_line + 1,
					  psl_flags);
		      ui_out_emit_list temp_list_emitter (uiout,
							  "line_asm_insn");
		    }
		  /* Print the last line and leave list open for
		     asm instructions to be added.  */
		  outer_tuple_emitter.emplace (uiout, "src_and_asm_line");
		  print_source_lines (symtab, next_line, mle[i].line + 1, psl_flags);
		}
	    }
	  else
	    {
	      outer_tuple_emitter.emplace (uiout, "src_and_asm_line");
	      print_source_lines (symtab, mle[i].line, mle[i].line + 1, psl_flags);
	    }

	  next_line = mle[i].line + 1;
	  inner_list_emitter.emplace (uiout, "line_asm_insn");
	}

      num_displayed += dump_insns (gdbarch, uiout,
				   mle[i].start_pc, mle[i].end_pc,
				   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.  */
      if (i == (newlines - 1) || mle[i + 1].line > mle[i].line)
	{
	  inner_list_emitter.reset ();
	  outer_tuple_emitter.reset ();
	  uiout->text ("\n");
	}
      if (how_many >= 0 && num_displayed >= how_many)
	break;
    }
}

/* The idea here is to present a source-O-centric view of a
   function to the user.  This means that things are presented
   in source order, with (possibly) out of order assembly
   immediately following.  */

static void
do_mixed_source_and_assembly (struct gdbarch *gdbarch,
			      struct ui_out *uiout,
			      struct symtab *main_symtab,
			      CORE_ADDR low, CORE_ADDR high,
			      int how_many, gdb_disassembly_flags flags)
{
  const struct linetable_entry *le, *first_le;
  int i, nlines;
  int num_displayed = 0;
  print_source_lines_flags psl_flags = 0;
  CORE_ADDR pc;
  struct symtab *last_symtab;
  int last_line;

  gdb_assert (main_symtab != NULL && main_symtab->linetable () != NULL);

  /* First pass: collect the list of all source files and lines.
     We do this so that we can only print lines containing code once.
     We try to print the source text leading up to the next instruction,
     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.  */

  htab_up dis_line_table (allocate_dis_line_table ());

  struct objfile *objfile = main_symtab->compunit ()->objfile ();

  unrelocated_addr unrel_low
    = unrelocated_addr (low - objfile->text_section_offset ());
  unrelocated_addr unrel_high
    = unrelocated_addr (high - objfile->text_section_offset ());

  pc = low;

  /* The prologue may be empty, but there may still be a line number entry
     for the opening brace which is distinct from the first line of code.
     If the prologue has been eliminated find_pc_line may return the source
     line after the opening brace.  We still want to print this opening brace.
     first_le is used to implement this.  */

  nlines = main_symtab->linetable ()->nitems;
  le = main_symtab->linetable ()->item;
  first_le = NULL;

  /* Skip all the preceding functions.  */
  for (i = 0; i < nlines && le[i].unrelocated_pc () < unrel_low; i++)
    continue;

  if (i < nlines && le[i].unrelocated_pc () < unrel_high)
    first_le = &le[i];

  /* Add lines for every pc value.  */
  while (pc < high)
    {
      struct symtab_and_line sal;
      int length;

      sal = find_pc_line (pc, 0);
      length = gdb_insn_length (gdbarch, pc);
      pc += length;

      if (sal.symtab != NULL)
	add_dis_line_entry (dis_line_table.get (), sal.symtab, sal.line);
    }

  /* Second pass: print the disassembly.

     Output format, from an MI perspective:
       The result is a ui_out list, field name "asm_insns", where elements have
       name "src_and_asm_line".
       Each element is a tuple of source line specs (field names line, file,
       fullname), and field "line_asm_insn" which contains the disassembly.
       Field "line_asm_insn" is a list of tuples: address, func-name, offset,
       opcodes, inst.

     CLI output works on top of this because MI ignores ui_out_text output,
     which is where we put file name and source line contents output.

     Emitter usage:
     asm_insns_emitter
       Handles the outer "asm_insns" list.
     tuple_emitter
       The tuples for each group of consecutive disassemblies.
     list_emitter
       List of consecutive source lines or disassembled insns.  */

  if (flags & DISASSEMBLY_FILENAME)
    psl_flags |= PRINT_SOURCE_LINES_FILENAME;

  ui_out_emit_list asm_insns_emitter (uiout, "asm_insns");

  std::optional<ui_out_emit_tuple> tuple_emitter;
  std::optional<ui_out_emit_list> list_emitter;

  last_symtab = NULL;
  last_line = 0;
  pc = low;

  while (pc < high)
    {
      struct symtab_and_line sal;
      CORE_ADDR end_pc;
      int start_preceding_line_to_display = 0;
      int end_preceding_line_to_display = 0;
      int new_source_line = 0;

      sal = find_pc_line (pc, 0);

      if (sal.symtab != last_symtab)
	{
	  /* New source file.  */
	  new_source_line = 1;

	  /* If this is the first line of output, check for any preceding
	     lines.  */
	  if (last_line == 0
	      && first_le != NULL
	      && first_le->line < sal.line)
	    {
	      start_preceding_line_to_display = first_le->line;
	      end_preceding_line_to_display = sal.line;
	    }
	}
      else
	{
	  /* Same source file as last time.  */
	  if (sal.symtab != NULL)
	    {
	      if (sal.line > last_line + 1 && last_line != 0)
		{
		  int l;

		  /* Several preceding source lines.  Print the trailing ones
		     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.get (),
					   sal.symtab, l))
			break;
		    }
		  if (l < sal.line - 1)
		    {
		      start_preceding_line_to_display = l + 1;
		      end_preceding_line_to_display = sal.line;
		    }
		}
	      if (sal.line != last_line)
		new_source_line = 1;
	      else
		{
		  /* Same source line as last time.  This can happen, depending
		     on the debug info.  */
		}
	    }
	}

      if (new_source_line)
	{
	  /* Skip the newline if this is the first instruction.  */
	  if (pc > low)
	    uiout->text ("\n");
	  if (tuple_emitter.has_value ())
	    {
	      gdb_assert (list_emitter.has_value ());
	      list_emitter.reset ();
	      tuple_emitter.reset ();
	    }
	  if (sal.symtab != last_symtab
	      && !(flags & DISASSEMBLY_FILENAME))
	    {
	      /* Remember MI ignores ui_out_text.
		 We don't have to do anything here for MI because MI
		 output includes the source specs for each line.  */
	      if (sal.symtab != NULL)
		{
		  uiout->text (symtab_to_filename_for_display (sal.symtab));
		}
	      else
		uiout->text ("unknown");
	      uiout->text (":\n");
	    }
	  if (start_preceding_line_to_display > 0)
	    {
	      /* Several source lines w/o asm instructions associated.
		 We need to preserve the structure of the output, so output
		 a bunch of line tuples with no asm entries.  */
	      int l;

	      gdb_assert (sal.symtab != NULL);
	      for (l = start_preceding_line_to_display;
		   l < end_preceding_line_to_display;
		   ++l)
		{
		  ui_out_emit_tuple line_tuple_emitter (uiout,
							"src_and_asm_line");
		  print_source_lines (sal.symtab, l, l + 1, psl_flags);
		  ui_out_emit_list chain_line_emitter (uiout, "line_asm_insn");
		}
	    }
	  tuple_emitter.emplace (uiout, "src_and_asm_line");
	  if (sal.symtab != NULL)
	    print_source_lines (sal.symtab, sal.line, sal.line + 1, psl_flags);
	  else
	    uiout->text (_("--- no source info for this pc ---\n"));
	  list_emitter.emplace (uiout, "line_asm_insn");
	}
      else
	{
	  /* Here we're appending instructions to an existing line.
	     By construction the very first insn will have a symtab
	     and follow the new_source_line path above.  */
	  gdb_assert (tuple_emitter.has_value ());
	  gdb_assert (list_emitter.has_value ());
	}

      if (sal.end != 0)
	end_pc = std::min (sal.end, high);
      else
	end_pc = pc + 1;
      num_displayed += dump_insns (gdbarch, uiout, pc, end_pc,
				   how_many, flags, &end_pc);
      pc = end_pc;

      if (how_many >= 0 && num_displayed >= how_many)
	break;

      last_symtab = sal.symtab;
      last_line = sal.line;
    }
}

static void
do_assembly_only (struct gdbarch *gdbarch, struct ui_out *uiout,
		  CORE_ADDR low, CORE_ADDR high,
		  int how_many, gdb_disassembly_flags flags)
{
  ui_out_emit_list list_emitter (uiout, "asm_insns");

  dump_insns (gdbarch, uiout, low, high, how_many, flags, NULL);
}

/* Combine implicit and user disassembler options and return them
   in a newly-created string.  */

static std::string
get_all_disassembler_options (struct gdbarch *gdbarch)
{
  const char *implicit = gdbarch_disassembler_options_implicit (gdbarch);
  const char *options = get_disassembler_options (gdbarch);
  const char *comma = ",";

  if (implicit == nullptr)
    {
      implicit = "";
      comma = "";
    }

  if (options == nullptr)
    {
      options = "";
      comma = "";
    }

  return string_printf ("%s%s%s", implicit, comma, options);
}

gdb_disassembler::gdb_disassembler (struct gdbarch *gdbarch,
				    struct ui_file *file,
				    read_memory_ftype func)
  : gdb_printing_disassembler (gdbarch, &m_buffer, func,
			       dis_asm_memory_error, dis_asm_print_address),
    m_dest (file),
    m_buffer (!use_ext_lang_for_styling () && use_libopcodes_for_styling ())
{ /* Nothing.  */ }

/* See disasm.h.  */

bool
gdb_disassembler::use_ext_lang_for_styling () const
{
  /* The use of m_di.created_styled_output here is a bit of a cheat, but
     it works fine for now.

     This function is called in situations after m_di has been initialized,
     but before the instruction has been disassembled.

     Currently, every target that supports libopcodes styling sets the
     created_styled_output field in disassemble_init_for_target, which was
     called as part of the initialization of gdb_printing_disassembler.

     This means that we are OK to check the created_styled_output field
     here.

     If, in the future, there's ever a target that only sets the
     created_styled_output field during the actual instruction disassembly
     phase, then we will need to update this code.  */
  return (disassembler_styling
	  && (!m_di.created_styled_output || !use_libopcodes_styling)
	  && use_ext_lang_colorization_p
	  && m_dest->can_emit_style_escape ());
}

/* See disasm.h.  */

bool
gdb_disassembler::use_libopcodes_for_styling () const
{
  /* See the comment on the use of m_di.created_styled_output in the
     gdb_disassembler::use_ext_lang_for_styling function.  */
  return (disassembler_styling
	  && m_di.created_styled_output
	  && use_libopcodes_styling
	  && m_dest->can_emit_style_escape ());
}

/* See disasm.h.  */

gdb_disassemble_info::gdb_disassemble_info
  (struct gdbarch *gdbarch,
   read_memory_ftype read_memory_func, memory_error_ftype memory_error_func,
   print_address_ftype print_address_func, fprintf_ftype fprintf_func,
   fprintf_styled_ftype fprintf_styled_func)
    : m_gdbarch (gdbarch)
{
  gdb_assert (fprintf_func != nullptr);
  gdb_assert (fprintf_styled_func != nullptr);
  init_disassemble_info (&m_di, (void *) this, fprintf_func,
			 fprintf_styled_func);
  m_di.flavour = bfd_target_unknown_flavour;

  /* The memory_error_func, print_address_func, and read_memory_func are
     all initialized to a default (non-nullptr) value by the call to
     init_disassemble_info above.  If the user is overriding these fields
     (by passing non-nullptr values) then do that now, otherwise, leave
     these fields as the defaults.  */
  if (memory_error_func != nullptr)
    m_di.memory_error_func = memory_error_func;
  if (print_address_func != nullptr)
    m_di.print_address_func = print_address_func;
  if (read_memory_func != nullptr)
    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;
  m_disassembler_options_holder = get_all_disassembler_options (gdbarch);
  if (!m_disassembler_options_holder.empty ())
    m_di.disassembler_options = m_disassembler_options_holder.c_str ();
  disassemble_init_for_target (&m_di);
}

/* See disasm.h.  */

gdb_disassemble_info::~gdb_disassemble_info ()
{
  disassemble_free_target (&m_di);
}

/* Wrapper around calling gdbarch_print_insn.  This function takes care of
   first calling the extension language hooks for print_insn, and, if none
   of the extension languages can print this instruction, calls
   gdbarch_print_insn to do the work.

   GDBARCH is the architecture to disassemble in, VMA is the address of the
   instruction being disassembled, and INFO is the libopcodes disassembler
   related information.  */

static int
gdb_print_insn_1 (struct gdbarch *gdbarch, CORE_ADDR vma,
		  struct disassemble_info *info)
{
  /* Call into the extension languages to do the disassembly.  */
  std::optional<int> length = ext_lang_print_insn (gdbarch, vma, info);
  if (length.has_value ())
    return *length;

  /* No extension language wanted to do the disassembly, so do it
     manually.  */
  return gdbarch_print_insn (gdbarch, vma, info);
}

/* See disasm.h.  */

bool gdb_disassembler::use_ext_lang_colorization_p = true;

/* See disasm.h.  */

int
gdb_disassembler::print_insn (CORE_ADDR memaddr,
			      int *branch_delay_insns)
{
  m_err_memaddr.reset ();
  m_buffer.clear ();
  this->set_in_comment (false);

  int length = gdb_print_insn_1 (arch (), memaddr, &m_di);

  /* If we have successfully disassembled an instruction, disassembler
     styling using the extension language is on, and libopcodes hasn't
     already styled the output for us, and, if the destination can support
     styling, then lets call into the extension languages in order to style
     this output.  */
  if (length > 0 && use_ext_lang_for_styling ())
    {
      std::optional<std::string> ext_contents;
      ext_contents = ext_lang_colorize_disasm (m_buffer.string (), arch ());
      if (ext_contents.has_value ())
	m_buffer = std::move (*ext_contents);
      else
	{
	  /* The extension language failed to add styling to the
	     disassembly output.  Set the static flag so that next time we
	     disassemble we don't even bother attempting to use the
	     extension language for styling.  */
	  use_ext_lang_colorization_p = false;

	  /* We're about to disassemble this instruction again, reset the
	     in-comment state.  */
	  this->set_in_comment (false);

	  /* The instruction we just disassembled, and the extension
	     languages failed to style, might have otherwise had some
	     minimal styling applied by GDB.  To regain that styling we
	     need to recreate m_buffer, but this time with styling support.

	     To do this we perform an in-place new, but this time turn on
	     the styling support, then we can re-disassembly the
	     instruction, and gain any minimal styling GDB might add.  */
	  static_assert ((std::is_same<decltype (m_buffer),
			      string_file>::value));
	  gdb_assert (!m_buffer.term_out ());
	  m_buffer.~string_file ();
	  new (&m_buffer) string_file (use_libopcodes_for_styling ());
	  length = gdb_print_insn_1 (arch (), memaddr, &m_di);
	  gdb_assert (length > 0);
	}
    }

  /* Push any disassemble output to the real destination stream.  We do
     this even if the disassembler reported failure (-1) as the
     disassembler may have printed something to its output stream.  */
  gdb_printf (m_dest, "%s", m_buffer.c_str ());

  /* If the disassembler failed then report an appropriate error.  */
  if (length < 0)
    {
      if (m_err_memaddr.has_value ())
	memory_error (TARGET_XFER_E_IO, *m_err_memaddr);
      else
	error (_("unknown disassembler error (error = %d)"), length);
    }

  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,
		 gdb_disassembly_flags flags, int how_many,
		 CORE_ADDR low, CORE_ADDR high)
{
  struct symtab *symtab;
  int nlines = -1;

  /* Assume symtab is valid for whole PC range.  */
  symtab = find_pc_line_symtab (low);

  if (symtab != NULL && symtab->linetable () != NULL)
    nlines = symtab->linetable ()->nitems;

  if (!(flags & (DISASSEMBLY_SOURCE_DEPRECATED | DISASSEMBLY_SOURCE))
      || nlines <= 0)
    do_assembly_only (gdbarch, uiout, low, high, how_many, flags);

  else if (flags & DISASSEMBLY_SOURCE)
    do_mixed_source_and_assembly (gdbarch, uiout, symtab, low, high,
				  how_many, flags);

  else if (flags & DISASSEMBLY_SOURCE_DEPRECATED)
    do_mixed_source_and_assembly_deprecated (gdbarch, uiout, symtab,
					     low, high, how_many, flags);

  gdb_flush (gdb_stdout);
}

/* Print the instruction at address MEMADDR in debugged memory,
   on STREAM.  Returns the length of the instruction, in bytes,
   and, if requested, the number of branch delay slot instructions.  */

int
gdb_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
		struct ui_file *stream, int *branch_delay_insns)
{

  gdb_disassembler di (gdbarch, stream);

  return di.print_insn (memaddr, branch_delay_insns);
}

/* Return the length in bytes of the instruction at address MEMADDR in
   debugged memory.  */

int
gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  return gdb_print_insn (gdbarch, addr, &null_stream, NULL);
}

/* See disasm.h.  */

int
gdb_non_printing_disassembler::null_fprintf_func
  (void *stream, const char *format, ...) noexcept
{
  return 0;
}

/* See disasm.h.  */

int
gdb_non_printing_disassembler::null_fprintf_styled_func
  (void *stream, enum disassembler_style style,
   const char *format, ...) noexcept
{
  return 0;
}

/* A non-printing disassemble_info management class.  The disassemble_info
   setup by this class will not print anything to the output stream (there
   is no output stream), and the instruction to be disassembled will be
   read from a buffer passed to the constructor.  */

struct gdb_non_printing_buffer_disassembler
  : public gdb_non_printing_disassembler
{
  /* Constructor.  GDBARCH is the architecture to disassemble for, BUFFER
     contains the instruction to disassemble, and INSN_ADDRESS is the
     address (in target memory) of the instruction to disassemble.  */
  gdb_non_printing_buffer_disassembler (struct gdbarch *gdbarch,
					gdb::array_view<const gdb_byte> buffer,
					CORE_ADDR insn_address)
    : gdb_non_printing_disassembler (gdbarch, nullptr)
  {
    /* The cast is necessary until disassemble_info is const-ified.  */
    m_di.buffer = (gdb_byte *) buffer.data ();
    m_di.buffer_length = buffer.size ();
    m_di.buffer_vma = insn_address;
  }
};

/* Return the length in bytes of INSN.  MAX_LEN is the size of the
   buffer containing INSN.  */

int
gdb_buffered_insn_length (struct gdbarch *gdbarch,
			  const gdb_byte *insn, int max_len, CORE_ADDR addr)
{
  gdb::array_view<const gdb_byte> buffer
    = gdb::make_array_view (insn, max_len);
  gdb_non_printing_buffer_disassembler dis (gdbarch, buffer, addr);
  int result = gdb_print_insn_1 (gdbarch, addr, dis.disasm_info ());
  return result;
}

const char *
get_disassembler_options (struct gdbarch *gdbarch)
{
  std::string *disassembler_options = gdbarch_disassembler_options (gdbarch);
  if (disassembler_options == nullptr || disassembler_options->empty ())
    return nullptr;
  return disassembler_options->c_str ();
}

void
set_disassembler_options (const char *prospective_options)
{
  struct gdbarch *gdbarch = get_current_arch ();
  std::string *disassembler_options = gdbarch_disassembler_options (gdbarch);
  const disasm_options_and_args_t *valid_options_and_args;
  const disasm_options_t *valid_options;
  gdb::unique_xmalloc_ptr<char> prospective_options_local
    = make_unique_xstrdup (prospective_options);
  char *options = remove_whitespace_and_extra_commas
    (prospective_options_local.get ());
  const char *opt;

  /* Allow all architectures, even ones that do not support 'set disassembler',
     to reset their disassembler options to NULL.  */
  if (options == NULL)
    {
      if (disassembler_options != nullptr)
	disassembler_options->clear ();
      return;
    }

  valid_options_and_args = gdbarch_valid_disassembler_options (gdbarch);
  if (valid_options_and_args == NULL)
    {
      gdb_printf (gdb_stderr, _("\
'set disassembler-options ...' is not supported on this architecture.\n"));
      return;
    }

  valid_options = &valid_options_and_args->options;

  /* Verify we have valid disassembler options.  */
  FOR_EACH_DISASSEMBLER_OPTION (opt, options)
    {
      size_t i;
      for (i = 0; valid_options->name[i] != NULL; i++)
	if (valid_options->arg != NULL && valid_options->arg[i] != NULL)
	  {
	    size_t len = strlen (valid_options->name[i]);
	    bool found = false;
	    const char *arg;
	    size_t j;

	    if (memcmp (opt, valid_options->name[i], len) != 0)
	      continue;
	    arg = opt + len;
	    if (valid_options->arg[i]->values == NULL)
	      break;
	    for (j = 0; valid_options->arg[i]->values[j] != NULL; j++)
	      if (disassembler_options_cmp
		    (arg, valid_options->arg[i]->values[j]) == 0)
		{
		  found = true;
		  break;
		}
	    if (found)
	      break;
	  }
	else if (disassembler_options_cmp (opt, valid_options->name[i]) == 0)
	  break;
      if (valid_options->name[i] == NULL)
	{
	  gdb_printf (gdb_stderr,
		      _("Invalid disassembler option value: '%s'.\n"),
		      opt);
	  return;
	}
    }

  *disassembler_options = options;
}

static void
set_disassembler_options_sfunc (const char *args, int from_tty,
				struct cmd_list_element *c)
{
  set_disassembler_options (prospective_options.c_str ());
}

static void
show_disassembler_options_sfunc (struct ui_file *file, int from_tty,
				 struct cmd_list_element *c, const char *value)
{
  struct gdbarch *gdbarch = get_current_arch ();
  const disasm_options_and_args_t *valid_options_and_args;
  const disasm_option_arg_t *valid_args;
  const disasm_options_t *valid_options;

  const char *options = get_disassembler_options (gdbarch);
  if (options == NULL)
    options = "";

  gdb_printf (file, _("The current disassembler options are '%s'\n\n"),
	      options);

  valid_options_and_args = gdbarch_valid_disassembler_options (gdbarch);

  if (valid_options_and_args == NULL)
    {
      gdb_puts (_("There are no disassembler options available "
		  "for this architecture.\n"),
		file);
      return;
    }

  valid_options = &valid_options_and_args->options;

  gdb_printf (file, _("\
The following disassembler options are supported for use with the\n\
'set disassembler-options OPTION [,OPTION]...' command:\n"));

  if (valid_options->description != NULL)
    {
      size_t i, max_len = 0;

      gdb_printf (file, "\n");

      /* Compute the length of the longest option name.  */
      for (i = 0; valid_options->name[i] != NULL; i++)
	{
	  size_t len = strlen (valid_options->name[i]);

	  if (valid_options->arg != NULL && valid_options->arg[i] != NULL)
	    len += strlen (valid_options->arg[i]->name);
	  if (max_len < len)
	    max_len = len;
	}

      for (i = 0, max_len++; valid_options->name[i] != NULL; i++)
	{
	  gdb_printf (file, "  %s", valid_options->name[i]);
	  if (valid_options->arg != NULL && valid_options->arg[i] != NULL)
	    gdb_printf (file, "%s", valid_options->arg[i]->name);
	  if (valid_options->description[i] != NULL)
	    {
	      size_t len = strlen (valid_options->name[i]);

	      if (valid_options->arg != NULL && valid_options->arg[i] != NULL)
		len += strlen (valid_options->arg[i]->name);
	      gdb_printf (file, "%*c %s", (int) (max_len - len), ' ',
			  valid_options->description[i]);
	    }
	  gdb_printf (file, "\n");
	}
    }
  else
    {
      size_t i;
      gdb_printf (file, "  ");
      for (i = 0; valid_options->name[i] != NULL; i++)
	{
	  gdb_printf (file, "%s", valid_options->name[i]);
	  if (valid_options->arg != NULL && valid_options->arg[i] != NULL)
	    gdb_printf (file, "%s", valid_options->arg[i]->name);
	  if (valid_options->name[i + 1] != NULL)
	    gdb_printf (file, ", ");
	  file->wrap_here (2);
	}
      gdb_printf (file, "\n");
    }

  valid_args = valid_options_and_args->args;
  if (valid_args != NULL)
    {
      size_t i, j;

      for (i = 0; valid_args[i].name != NULL; i++)
	{
	  if (valid_args[i].values == NULL)
	    continue;
	  gdb_printf (file, _("\n\
  For the options above, the following values are supported for \"%s\":\n   "),
		      valid_args[i].name);
	  for (j = 0; valid_args[i].values[j] != NULL; j++)
	    {
	      gdb_printf (file, " %s", valid_args[i].values[j]);
	      file->wrap_here (3);
	    }
	  gdb_printf (file, "\n");
	}
    }
}

/* A completion function for "set disassembler".  */

static void
disassembler_options_completer (struct cmd_list_element *ignore,
				completion_tracker &tracker,
				const char *text, const char *word)
{
  struct gdbarch *gdbarch = get_current_arch ();
  const disasm_options_and_args_t *opts_and_args
    = gdbarch_valid_disassembler_options (gdbarch);

  if (opts_and_args != NULL)
    {
      const disasm_options_t *opts = &opts_and_args->options;

      /* Only attempt to complete on the last option text.  */
      const char *separator = strrchr (text, ',');
      if (separator != NULL)
	text = separator + 1;
      text = skip_spaces (text);
      complete_on_enum (tracker, opts->name, text, word);
    }
}


/* Initialization code.  */

void _initialize_disasm ();
void
_initialize_disasm ()
{
  /* Add the command that controls the disassembler options.  */
  set_show_commands set_show_disas_opts
    = add_setshow_string_noescape_cmd ("disassembler-options", no_class,
				       &prospective_options, _("\
Set the disassembler options.\n\
Usage: set disassembler-options OPTION [,OPTION]...\n\n\
See: 'show disassembler-options' for valid option values."), _("\
Show the disassembler options."), NULL,
					 set_disassembler_options_sfunc,
					 show_disassembler_options_sfunc,
					 &setlist, &showlist);
  set_cmd_completer (set_show_disas_opts.set, disassembler_options_completer);


  /* All the 'maint set|show libopcodes-styling' sub-commands.  */
  static struct cmd_list_element *maint_set_libopcodes_styling_cmdlist;
  static struct cmd_list_element *maint_show_libopcodes_styling_cmdlist;

  /* Adds 'maint set|show libopcodes-styling'.  */
  add_setshow_prefix_cmd ("libopcodes-styling", class_maintenance,
			  _("Set libopcodes-styling specific variables."),
			  _("Show libopcodes-styling specific variables."),
			  &maint_set_libopcodes_styling_cmdlist,
			  &maint_show_libopcodes_styling_cmdlist,
			  &maintenance_set_cmdlist,
			  &maintenance_show_cmdlist);

  /* Adds 'maint set|show gnu-source-highlight enabled'.  */
  add_setshow_boolean_cmd ("enabled", class_maintenance,
			   &use_libopcodes_styling_option, _("\
Set whether the libopcodes styling support should be used."), _("\
Show whether the libopcodes styling support should be used."),_("\
When enabled, GDB will try to make use of the builtin libopcodes styling\n\
support, to style the disassembler output.  Not every architecture has\n\
styling support within libopcodes, so enabling this is not a guarantee\n\
that libopcodes styling will be available.\n\
\n\
When this option is disabled, GDB will make use of the Python Pygments\n\
package (if available) to style the disassembler output.\n\
\n\
All disassembler styling can be disabled with:\n\
\n\
  set style disassembler enabled off"),
			   set_use_libopcodes_styling,
			   show_use_libopcodes_styling,
			   &maint_set_libopcodes_styling_cmdlist,
			   &maint_show_libopcodes_styling_cmdlist);
}
