/* Disassemble support for GDB.
   Copyright (C) 2002-2022 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/>.  */

#ifndef DISASM_H
#define DISASM_H

#include "dis-asm.h"
#include "disasm-flags.h"

struct gdbarch;
struct ui_out;
struct ui_file;

/* A wrapper around a disassemble_info and a gdbarch.  This is the core
   set of data that all disassembler sub-classes will need.  This class
   doesn't actually implement the disassembling process, that is something
   that sub-classes will do, with each sub-class doing things slightly
   differently.

   The constructor of this class is protected, you should not create
   instances of this class directly, instead create an instance of an
   appropriate sub-class.  */

struct gdb_disassemble_info
{
  DISABLE_COPY_AND_ASSIGN (gdb_disassemble_info);

  /* Return the gdbarch we are disassembling for.  */
  struct gdbarch *arch ()
  { return m_gdbarch; }

  /* Return a pointer to the disassemble_info, this will be needed for
     passing into the libopcodes disassembler.  */
  struct disassemble_info *disasm_info ()
  { return &m_di; }

protected:

  /* Types for the function callbacks within m_di.  */
  using read_memory_ftype = decltype (disassemble_info::read_memory_func);
  using memory_error_ftype = decltype (disassemble_info::memory_error_func);
  using print_address_ftype = decltype (disassemble_info::print_address_func);
  using fprintf_ftype = decltype (disassemble_info::fprintf_func);
  using fprintf_styled_ftype = decltype (disassemble_info::fprintf_styled_func);

  /* Constructor, many fields in m_di are initialized from GDBARCH.  The
     remaining arguments are function callbacks that are written into m_di.
     Of these function callbacks FPRINTF_FUNC and FPRINTF_STYLED_FUNC must
     not be nullptr.  If READ_MEMORY_FUNC, MEMORY_ERROR_FUNC, or
     PRINT_ADDRESS_FUNC are nullptr, then that field within m_di is left
     with its default value (see the libopcodes function
     init_disassemble_info for the defaults).  */
  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);

  /* Destructor.  */
  virtual ~gdb_disassemble_info ();

  /* Stores data required for disassembling instructions in
     opcodes.  */
  struct disassemble_info m_di;

private:
  /* The architecture we are disassembling for.  */
  struct gdbarch *m_gdbarch;

  /* If we own the string in `m_di.disassembler_options', we do so
     using this field.  */
  std::string m_disassembler_options_holder;
};

/* A wrapper around gdb_disassemble_info.  This class adds default
   print functions that are supplied to the disassemble_info within the
   parent class.  These default print functions write to the stream, which
   is also contained in the parent class.

   As with the parent class, the constructor for this class is protected,
   you should not create instances of this class, but create an
   appropriate sub-class instead.  */

struct gdb_printing_disassembler : public gdb_disassemble_info
{
  DISABLE_COPY_AND_ASSIGN (gdb_printing_disassembler);

protected:

  /* The stream that disassembler output is being written too.  */
  struct ui_file *stream ()
  { return m_stream; }

  /* Constructor.  All the arguments are just passed to the parent class.
     We also add the two print functions to the arguments passed to the
     parent.  See gdb_disassemble_info for a description of how the
     arguments are handled.  */
  gdb_printing_disassembler (struct gdbarch *gdbarch,
			     struct ui_file *stream,
			     read_memory_ftype read_memory_func,
			     memory_error_ftype memory_error_func,
			     print_address_ftype print_address_func)
    : gdb_disassemble_info (gdbarch, read_memory_func,
			    memory_error_func, print_address_func,
			    fprintf_func, fprintf_styled_func),
      m_stream (stream)
  {
    gdb_assert (stream != nullptr);
  }

  /* Callback used as the disassemble_info's fprintf_func callback.  The
     DIS_INFO pointer is a pointer to a gdb_printing_disassembler object.
     Content is written to the m_stream extracted from DIS_INFO.  */
  static int fprintf_func (void *dis_info, const char *format, ...)
    ATTRIBUTE_PRINTF(2,3);

  /* Callback used as the disassemble_info's fprintf_styled_func callback.
     The DIS_INFO pointer is a pointer to a gdb_printing_disassembler
     object.  Content is written to the m_stream extracted from DIS_INFO.  */
  static int fprintf_styled_func (void *dis_info,
				  enum disassembler_style style,
				  const char *format, ...)
    ATTRIBUTE_PRINTF(3,4);

  /* Return true if the disassembler is considered inside a comment, false
     otherwise.  */
  bool in_comment_p () const
  { return m_in_comment; }

  /* Set whether the disassembler should be considered as within comment
     text or not.  */
  void set_in_comment (bool c)
  { m_in_comment = c; }

private:

  /* When libopcodes calls the fprintf_func and fprintf_styled_func
     callbacks, a 'void *' argument is passed.  We arrange, through our
     call to init_disassemble_info that this argument will be a pointer to
     a gdb_disassemble_info sub-class, specifically, a
     gdb_printing_disassembler pointer.  This helper function casts
     DIS_INFO to the correct type (with some asserts), and then returns the
     m_stream member variable.  */
  static ui_file *stream_from_gdb_disassemble_info (void *dis_info);

  /* The stream to which output should be sent.  */
  struct ui_file *m_stream;

  /* Are we inside a comment?  This will be set true if the disassembler
     uses styled output and emits a start of comment character.  It is up
     to the code that uses this disassembler class to reset this flag back
     to false at a suitable time (e.g. at the end of every line).  */
  bool m_in_comment = false;
};

/* A basic disassembler that doesn't actually print anything.  */

struct gdb_non_printing_disassembler : public gdb_disassemble_info
{
  gdb_non_printing_disassembler (struct gdbarch *gdbarch,
				 read_memory_ftype read_memory_func)
    : gdb_disassemble_info (gdbarch,
			    read_memory_func,
			    nullptr /* memory_error_func */,
			    nullptr /* print_address_func */,
			    null_fprintf_func,
			    null_fprintf_styled_func)
  { /* Nothing.  */ }

private:

  /* Callback used as the disassemble_info's fprintf_func callback, this
     doesn't write anything to STREAM, but just returns 0.  */
  static int null_fprintf_func (void *stream, const char *format, ...)
    ATTRIBUTE_PRINTF(2,3);

  /* Callback used as the disassemble_info's fprintf_styled_func callback,
     , this doesn't write anything to STREAM, but just returns 0.  */
  static int null_fprintf_styled_func (void *stream,
				       enum disassembler_style style,
				       const char *format, ...)
    ATTRIBUTE_PRINTF(3,4);
};

/* This is a helper class, for use as an additional base-class, by some of
   the disassembler classes below.  This class just defines a static method
   for reading from target memory, which can then be used by the various
   disassembler sub-classes.  */

struct gdb_disassembler_memory_reader
{
  /* Implements the read_memory_func disassemble_info callback.  */
  static int dis_asm_read_memory (bfd_vma memaddr, gdb_byte *myaddr,
				  unsigned int len,
				  struct disassemble_info *info);
};

/* 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 target memory.  */

struct gdb_non_printing_memory_disassembler
  : public gdb_non_printing_disassembler,
    private gdb_disassembler_memory_reader
{
  /* Constructor.  GDBARCH is the architecture to disassemble for.  */
  gdb_non_printing_memory_disassembler (struct gdbarch *gdbarch)
    :gdb_non_printing_disassembler (gdbarch, dis_asm_read_memory)
  { /* Nothing.  */ }
};

/* A dissassembler class that provides 'print_insn', a method for
   disassembling a single instruction to the output stream.  */

struct gdb_disassembler : public gdb_printing_disassembler,
			  private gdb_disassembler_memory_reader
{
  gdb_disassembler (struct gdbarch *gdbarch, struct ui_file *file)
    : gdb_disassembler (gdbarch, file, dis_asm_read_memory)
  { /* Nothing.  */ }

  DISABLE_COPY_AND_ASSIGN (gdb_disassembler);

  /* Disassemble a single instruction at MEMADDR to the ui_file* that was
     passed to the constructor.  If a memory error occurs while
     disassembling this instruction then an error will be thrown.  */
  int print_insn (CORE_ADDR memaddr, int *branch_delay_insns = NULL);

protected:
  gdb_disassembler (struct gdbarch *gdbarch, struct ui_file *file,
		    read_memory_ftype func);

private:
  /* This member variable is given a value by calling dis_asm_memory_error.
     If after calling into the libopcodes disassembler we get back a
     negative value (which indicates an error), then, if this variable has
     a value, we report a memory error to the user, otherwise, we report a
     non-memory error.  */
  gdb::optional<CORE_ADDR> m_err_memaddr;

  /* Disassembler output is built up into this buffer.  Whether this
     string_file is created with styling support or not depends on the
     value of use_ext_lang_colorization_p, as well as whether disassembler
     styling in general is turned on, and also, whether *m_dest supports
     styling or not.  */
  string_file m_buffer;

  /* The stream to which disassembler output will be written.  */
  ui_file *m_dest;

  /* When true, m_buffer will be created without styling support,
     otherwise, m_buffer will be created with styling support.

     This field will initially be true, but will be set to false if
     ext_lang_colorize_disasm fails to add styling at any time.

     If the extension language is going to add the styling then m_buffer
     should be created without styling support, the extension language will
     then add styling at the end of the disassembly process.

     If the extension language is not going to add the styling, then we
     create m_buffer with styling support, and GDB will add minimal styling
     (currently just to addresses and symbols) as it goes.  */
  static bool use_ext_lang_colorization_p;

  static void dis_asm_memory_error (int err, bfd_vma memaddr,
				    struct disassemble_info *info);
  static void dis_asm_print_address (bfd_vma addr,
				     struct disassemble_info *info);
};

/* An instruction to be disassembled.  */

struct disasm_insn
{
  /* The address of the memory containing the instruction.  */
  CORE_ADDR addr;

  /* An optional instruction number.  If non-zero, it is printed first.  */
  unsigned int number;

  /* True if the instruction was executed speculatively.  */
  unsigned int is_speculative:1;
};

extern void gdb_disassembly (struct gdbarch *gdbarch, struct ui_out *uiout,
			     gdb_disassembly_flags flags, int how_many,
			     CORE_ADDR low, CORE_ADDR high);

/* 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.  */

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

/* Class used to pretty-print instructions.  */

class gdb_pretty_print_disassembler
{
public:
  explicit gdb_pretty_print_disassembler (struct gdbarch *gdbarch,
					  struct ui_out *uiout)
    : m_uiout (uiout),
      m_insn_stb (uiout->can_emit_style_escape ()),
      m_di (gdbarch, &m_insn_stb)
  {}

  /* Prints the instruction INSN into the saved ui_out and returns the
     length of the printed instruction in bytes.  */
  int pretty_print_insn (const struct disasm_insn *insn,
			 gdb_disassembly_flags flags);

private:
  /* Returns the architecture used for disassembling.  */
  struct gdbarch *arch () { return m_di.arch (); }

  /* The ui_out that is used by pretty_print_insn.  */
  struct ui_out *m_uiout;

  /* The buffer used to build the instruction string.  The
     disassembler is initialized with this stream.  */
  string_file m_insn_stb;

  /* The disassembler used for instruction printing.  */
  gdb_disassembler m_di;

  /* The buffer used to build the raw opcodes string.  */
  string_file m_opcode_stb;
};

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

extern int gdb_insn_length (struct gdbarch *gdbarch, CORE_ADDR memaddr);

/* Return the length in bytes of INSN, originally at MEMADDR.  MAX_LEN
   is the size of the buffer containing INSN.  */

extern int gdb_buffered_insn_length (struct gdbarch *gdbarch,
				     const gdb_byte *insn, int max_len,
				     CORE_ADDR memaddr);

/* Returns GDBARCH's disassembler options.  */

extern char *get_disassembler_options (struct gdbarch *gdbarch);

/* Sets the active gdbarch's disassembler options to OPTIONS.  */

extern void set_disassembler_options (const char *options);

#endif
