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

#include "dis-asm.h"
#include "disasm-flags.h"
#include "ui-out.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.  The actual function
     signatures here are taken from include/dis-asm.h.  */
  using read_memory_ftype
    = int (*) (bfd_vma, bfd_byte *, unsigned int, struct disassemble_info *)
	noexcept;
  using memory_error_ftype
    = void (*) (int, bfd_vma, struct disassemble_info *) noexcept;
  using print_address_ftype
    = void (*) (bfd_vma, struct disassemble_info *) noexcept;
  using fprintf_ftype
    = int (*) (void *, const char *, ...) noexcept;
  using fprintf_styled_ftype
    = int (*) (void *, enum disassembler_style, const char *, ...) noexcept;

  /* 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);

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

protected:

  /* 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, ...) noexcept
    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, ...) noexcept
    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, ...) noexcept
    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, ...) noexcept
    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) noexcept;
};

/* 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 disassembler 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.  */
  std::optional<CORE_ADDR> m_err_memaddr;

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

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

  /* 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) noexcept;
  static void dis_asm_print_address (bfd_vma addr,
				     struct disassemble_info *info) noexcept;

  /* Return true if we should use the extension language to apply
     disassembler styling.  This requires disassembler styling to be on
     (i.e. 'set style disassembler enabled on'), the output stream needs to
     support styling, and libopcode styling needs to be either off, or not
     supported for the current architecture (libopcodes is used in
     preference to the extension language method).  */
  bool use_ext_lang_for_styling () const;

  /* Return true if we should use libopcodes to apply disassembler styling.
     This requires disassembler styling to be on (i.e. 'set style
     disassembler enabled on'), the output stream needs to support styling,
     and libopcodes styling needs to be supported for the current
     architecture, and not disabled by the user.  */
  bool use_libopcodes_for_styling () const;
};

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

  /* The buffer used to hold the opcode bytes (if required).  */
  gdb::byte_vector m_opcode_data;
};

/* 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 const 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 /* GDB_DISASM_H */
