/* Python interface to instruction disassembly.

   Copyright (C) 2021-2026 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 "python-internal.h"
#include "language.h"
#include "dis-asm.h"
#include "arch-utils.h"
#include "charset.h"
#include "disasm.h"
#include "progspace.h"

/* Implement gdb.disassembler.DisassembleInfo type.  An object of this type
   represents a single disassembler request from GDB.  */

struct disasm_info_object : public PyObject
{
  /* The architecture in which we are disassembling.  */
  struct gdbarch *gdbarch;

  /* The program_space in which we are disassembling.  */
  struct program_space *program_space;

  /* Address of the instruction to disassemble.  */
  bfd_vma address;

  /* The disassemble_info passed from core GDB, this contains the
     callbacks necessary to read the instruction from core GDB, and to
     print the disassembled instruction.  */
  disassemble_info *gdb_info;

  /* If copies of this object are created then they are chained together
     via this NEXT pointer, this allows all the copies to be invalidated at
     the same time as the parent object.  */
  struct disasm_info_object *next;
};

static_assert (gdb::is_python_allocatable_v<disasm_info_object>);

extern PyTypeObject disasm_info_object_type;

/* Implement gdb.disassembler.DisassembleAddressPart type.  An object of
   this type represents a small part of a disassembled instruction; a part
   that is an address that should be printed using a call to GDB's
   internal print_address function.  */

struct disasm_addr_part_object : public PyObject
{
  /* The address to be formatted.  */
  bfd_vma address;

  /* A gdbarch.  This is only needed in the case where the user asks for
     the DisassemblerAddressPart to be converted to a string.  When we
     return this part to GDB within a DisassemblerResult then GDB will use
     the gdbarch from the initial disassembly request.  */
  struct gdbarch *gdbarch;
};

static_assert (gdb::is_python_allocatable_v<disasm_addr_part_object>);

extern PyTypeObject disasm_addr_part_object_type;

/* Implement gdb.disassembler.DisassembleTextPart type.  An object of
   this type represents a small part of a disassembled instruction; a part
   that is a piece of test along with an associated style.  */

struct disasm_text_part_object : public PyObject
{
  /* The string that is this part.  */
  std::string *string;

  /* The style to use when displaying this part.  */
  enum disassembler_style style;
};

static_assert (gdb::is_python_allocatable_v<disasm_text_part_object>);

extern PyTypeObject disasm_text_part_object_type;

extern PyTypeObject disasm_part_object_type;

/* Implement gdb.disassembler.DisassemblerResult type, an object that holds
   the result of calling the disassembler.  This is mostly the length of
   the disassembled instruction (in bytes), and the string representing the
   disassembled instruction.  */

struct disasm_result_object : public PyObject
{
  /* The length of the disassembled instruction in bytes.  */
  int length;

  /* A vector containing all the parts of the disassembled instruction.
     Each part will be a DisassemblerPart sub-class.  */
  std::vector<gdbpy_ref<>> *parts;
};

static_assert (gdb::is_python_allocatable_v<disasm_result_object>);

extern PyTypeObject disasm_result_object_type;

/* When this is false we fast path out of gdbpy_print_insn, which should
   keep the performance impact of the Python disassembler down.  This is
   set to true from Python by calling gdb.disassembler._set_enabled() when
   the user registers a disassembler.  */

static bool python_print_insn_enabled = false;

/* A sub-class of gdb_disassembler that holds a pointer to a Python
   DisassembleInfo object.  A pointer to an instance of this class is
   placed in the application_data field of the disassemble_info that is
   used when we call gdbarch_print_insn.  */

struct gdbpy_disassembler : public gdb_disassemble_info
{
  /* Constructor.  */
  gdbpy_disassembler (disasm_info_object *obj);

  /* Get the DisassembleInfo object pointer.  */
  disasm_info_object *
  py_disasm_info () const
  {
    return m_disasm_info_object;
  }

  /* Callbacks used by disassemble_info.  */
  static void memory_error_func (int status, bfd_vma memaddr,
				 struct disassemble_info *info) noexcept;
  static void print_address_func (bfd_vma addr,
				  struct disassemble_info *info) noexcept;
  static int read_memory_func (bfd_vma memaddr, gdb_byte *buff,
			       unsigned int len,
			       struct disassemble_info *info) noexcept;

  /* Callback used as the disassemble_info's fprintf_func callback.  The
     DIS_INFO pointer is a pointer to a gdbpy_disassembler object.  */
  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 gdbpy_disassembler.  */
  static int fprintf_styled_func (void *dis_info,
				  enum disassembler_style style,
				  const char *format, ...) noexcept
    ATTRIBUTE_PRINTF(3,4);

  /* Helper used by fprintf_func and fprintf_styled_func.  This function
     creates a new DisassemblerTextPart and adds it to the disassembler's
     parts list.  The actual disassembler is accessed through DIS_INFO,
     which is a pointer to the gdbpy_disassembler object.  */
  static int vfprintf_styled_func (void *dis_info,
				   enum disassembler_style style,
				   const char *format, va_list args) noexcept
    ATTRIBUTE_PRINTF(3,0);

  /* Return a reference to an optional that contains the address at which a
     memory error occurred.  The optional will only have a value if a
     memory error actually occurred.  */
  const std::optional<CORE_ADDR> &memory_error_address () const
  { return m_memory_error_address; }

  /* Return the content of the disassembler as a string.  The contents are
     moved out of the disassembler, so after this call the disassembler
     contents have been reset back to empty.  */
  std::vector<gdbpy_ref<>> release ()
  {
    return std::move (m_parts);
  }

  /* If there is a Python exception stored in this disassembler then
     restore it (i.e. set the PyErr_* state), clear the exception within
     this disassembler, and return true.  There must be no current
     exception set (i.e. !PyErr_Occurred()) when this function is called,
     as any such exception might get lost.

     Otherwise, there is no exception stored in this disassembler, return
     false.  */
  bool restore_exception ()
  {
    gdb_assert (!PyErr_Occurred ());
    if (m_stored_exception.has_value ())
      {
	gdbpy_err_fetch ex = std::move (*m_stored_exception);
	m_stored_exception.reset ();
	ex.restore ();
	return true;
      }

    return false;
  }

private:

  /* The list of all the parts that make up this disassembled instruction.
     This is populated as a result of the callbacks from libopcodes as the
     instruction is disassembled.  */
  std::vector<gdbpy_ref<>> m_parts;

  /* The DisassembleInfo object we are disassembling for.  */
  disasm_info_object *m_disasm_info_object;

  /* When the user indicates that a memory error has occurred then the
     address of the memory error is stored in here.  */
  std::optional<CORE_ADDR> m_memory_error_address;

  /* Move the exception EX into this disassembler object.  */
  void store_exception (gdbpy_err_fetch &&ex)
  {
    /* The only calls to store_exception are from read_memory_func, which
       will return early if there's already an exception stored.  */
    gdb_assert (!m_stored_exception.has_value ());
    m_stored_exception.emplace (std::move (ex));
  }

  /* Return true if there is an exception stored in this disassembler.  */
  bool has_stored_exception () const
  {
    return m_stored_exception.has_value ();
  }

  /* Store a single exception.  This is used to pass Python exceptions back
     from ::memory_read to disasmpy_builtin_disassemble.  */
  std::optional<gdbpy_err_fetch> m_stored_exception;
};

/* Return true if OBJ is still valid, otherwise, return false.  A valid OBJ
   will have a non-nullptr gdb_info field.  */

static bool
disasm_info_object_is_valid (disasm_info_object *obj)
{
  return obj->gdb_info != nullptr;
}

/* Fill in OBJ with all the other arguments.  */

static void
disasm_info_fill (disasm_info_object &obj, struct gdbarch *gdbarch,
		  program_space *progspace, bfd_vma address,
		  disassemble_info *di, disasm_info_object *next)
{
  obj.gdbarch = gdbarch;
  obj.program_space = progspace;
  obj.address = address;
  obj.gdb_info = di;
  obj.next = next;
}

/* Implement DisassembleInfo.__init__.  Takes a single argument that must
   be another DisassembleInfo object and copies the contents from the
   argument into this new object.  */

static int
disasm_info_init (PyObject *self, PyObject *args, PyObject *kwargs)
{
  static const char *keywords[] = { "info", NULL };
  PyObject *info_obj;
  if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "O!", keywords,
					&disasm_info_object_type,
					&info_obj))
    return -1;

  disasm_info_object *other = (disasm_info_object *) info_obj;
  disasm_info_object *info = (disasm_info_object *) self;
  disasm_info_fill (*info, other->gdbarch, other->program_space,
		    other->address, other->gdb_info, other->next);
  other->next = info;

  /* As the OTHER object now holds a pointer to INFO we inc the ref count
     on INFO.  This stops INFO being deleted until OTHER has gone away.  */
  Py_INCREF ((PyObject *) info);
  return 0;
}

/* The tp_dealloc callback for the DisassembleInfo type.  */

static void
disasm_info_dealloc (PyObject *self)
{
  disasm_info_object *obj = (disasm_info_object *) self;

  /* We no longer care about the object our NEXT pointer points at, so we
     can decrement its reference count.  This macro handles the case when
     NEXT is nullptr.  */
  Py_XDECREF ((PyObject *) obj->next);

  /* Now core deallocation behavior.  */
  Py_TYPE (self)->tp_free (self);
}

/* Implement __repr__ for the DisassembleInfo type.  */

static PyObject *
disasmpy_info_repr (PyObject *self)
{
  disasm_info_object *obj = (disasm_info_object *) self;

  const char *arch_name
    = (gdbarch_bfd_arch_info (obj->gdbarch))->printable_name;
  return PyUnicode_FromFormat ("<%s address=%s architecture=%s>",
			       gdbpy_py_obj_tp_name (self).c_str (),
			       core_addr_to_string_nz (obj->address),
			       arch_name);
}

/* Implement DisassembleInfo.is_valid(), really just a wrapper around the
   disasm_info_object_is_valid function above.  */

static PyObject *
disasmpy_info_is_valid (PyObject *self, PyObject *args)
{
  disasm_info_object *disasm_obj = (disasm_info_object *) self;

  if (disasm_info_object_is_valid (disasm_obj))
    return py_true ().release ();

  return py_false ().release ();
}

/* Set the Python exception to be a gdb.MemoryError object, with ADDRESS
   as its payload.  */

static void
disasmpy_set_memory_error_for_address (CORE_ADDR address)
{
  PyObject *address_obj = gdb_py_object_from_longest (address).release ();
  PyErr_SetObject (gdbpy_gdb_memory_error, address_obj);
}

/* Create a new DisassemblerTextPart and return a gdbpy_ref wrapper for
   the new object.  STR is the string content of the part and STYLE is the
   style to be used when GDB displays this part.  */

static gdbpy_ref<>
make_disasm_text_part (std::string &&str, enum disassembler_style style)
{
  PyTypeObject *type = &disasm_text_part_object_type;
  disasm_text_part_object *text_part
    = (disasm_text_part_object *) type->tp_alloc (type, 0);
  text_part->string = new std::string (str);
  text_part->style = style;

  return gdbpy_ref<> ((PyObject *) text_part);
}

/* Create a new DisassemblerAddressPart and return a gdbpy_ref wrapper for
   the new object.  GDBARCH is the architecture used when formatting the
   address, and ADDRESS is the numerical address to be displayed.  */

static gdbpy_ref<>
make_disasm_addr_part (struct gdbarch *gdbarch, CORE_ADDR address)
{
  PyTypeObject *type = &disasm_addr_part_object_type;
  disasm_addr_part_object *addr_part
    = (disasm_addr_part_object *) type->tp_alloc (type, 0);
  addr_part->address = address;
  addr_part->gdbarch = gdbarch;

  return gdbpy_ref<> ((PyObject *) addr_part);
}

/* Ensure that a gdb.disassembler.DisassembleInfo is valid.  */

#define DISASMPY_DISASM_INFO_REQUIRE_VALID(Info)			\
  do {									\
    if (!disasm_info_object_is_valid (Info))				\
      {									\
	PyErr_SetString (PyExc_RuntimeError,				\
			 _("DisassembleInfo is no longer valid."));	\
	return nullptr;							\
      }									\
  } while (0)

/* Implement DisassembleInfo.text_part method.  Creates and returns a new
   DisassemblerTextPart object.  */

static PyObject *
disasmpy_info_make_text_part (PyObject *self, PyObject *args,
			      PyObject *kwargs)
{
  disasm_info_object *obj = (disasm_info_object *) self;
  DISASMPY_DISASM_INFO_REQUIRE_VALID (obj);

  static const char *keywords[] = { "style", "string", NULL };
  int style_num;
  const char *string;
  if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "is", keywords,
					&style_num, &string))
    return nullptr;

  if (style_num < 0 || style_num > ((int) dis_style_comment_start))
    {
      PyErr_SetString (PyExc_ValueError,
		       _("Invalid disassembler style."));
      return nullptr;
    }

  if (strlen (string) == 0)
    {
      PyErr_SetString (PyExc_ValueError,
		       _("String must not be empty."));
      return nullptr;
    }

  gdbpy_ref<> text_part
    = make_disasm_text_part (std::string (string),
			     (enum disassembler_style) style_num);
  return text_part.release ();
}

/* Implement DisassembleInfo.address_part method.  Creates and returns a
   new DisassemblerAddressPart object.  */

static PyObject *
disasmpy_info_make_address_part (PyObject *self, PyObject *args,
				 PyObject *kwargs)
{
  disasm_info_object *obj = (disasm_info_object *) self;
  DISASMPY_DISASM_INFO_REQUIRE_VALID (obj);

  static const char *keywords[] = { "address", NULL };
  CORE_ADDR address;
  PyObject *address_object;
  if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "O", keywords,
					&address_object))
    return nullptr;

  if (get_addr_from_python (address_object, &address) < 0)
    return nullptr;

  return make_disasm_addr_part (obj->gdbarch, address).release ();
}

/* Return a string representation of TEXT_PART.  The returned string does
   not include any styling.  */

static std::string
disasmpy_part_to_string (const disasm_text_part_object *text_part)
{
  gdb_assert (text_part->string != nullptr);
  return *(text_part->string);
}

/* Return a string representation of ADDR_PART.  The returned string does
   not include any styling.  */

static std::string
disasmpy_part_to_string (const disasm_addr_part_object *addr_part)
{
  string_file buf;
  print_address (addr_part->gdbarch, addr_part->address, &buf);
  return buf.release ();
}

/* PARTS is a vector of Python objects, each is a sub-class of
   DisassemblerPart.  Create a string by concatenating the string
   representation of each part, and return this new string.

   Converting an address part requires that we call back into GDB core,
   which could throw an exception.  As such, calls to this function should
   be wrapped with a try/catch.  */

static std::string
disasmpy_parts_list_to_string (const std::vector<gdbpy_ref<>> &parts)
{
  std::string str;
  for (auto p : parts)
    {
      if (Py_TYPE (p.get ()) == &disasm_text_part_object_type)
	{
	  disasm_text_part_object *text_part
	    = (disasm_text_part_object *) p.get ();
	  str += disasmpy_part_to_string (text_part);
	}
      else
	{
	  gdb_assert (Py_TYPE (p.get ()) == &disasm_addr_part_object_type);

	  disasm_addr_part_object *addr_part
	    = (disasm_addr_part_object *) p.get ();
	  str += disasmpy_part_to_string (addr_part);
	}
    }

  return str;
}

/* Initialise OBJ, a DisassemblerResult object with LENGTH and PARTS.
   OBJ might already have been initialised, in which case any existing
   content should be discarded before the new PARTS are moved in.  */

static void
disasmpy_init_disassembler_result (disasm_result_object *obj, int length,
				   std::vector<gdbpy_ref<>> &&parts)
{
  if (obj->parts == nullptr)
    obj->parts = new std::vector<gdbpy_ref<>>;
  else
    obj->parts->clear ();

  obj->length = length;
  *(obj->parts) = std::move (parts);
}

/* Implement gdb.disassembler.builtin_disassemble().  Calls back into GDB's
   builtin disassembler.  The first argument is a DisassembleInfo object
   describing what to disassemble.  The second argument is optional and
   provides a mechanism to modify the memory contents that the builtin
   disassembler will actually disassemble.

   Returns an instance of gdb.disassembler.DisassemblerResult, an object
   that wraps a disassembled instruction, or it raises a
   gdb.MemoryError.  */

static PyObject *
disasmpy_builtin_disassemble (PyObject *self, PyObject *args, PyObject *kw)
{
  PyObject *info_obj;
  static const char *keywords[] = { "info", nullptr };
  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O!", keywords,
					&disasm_info_object_type, &info_obj))
    return nullptr;

  disasm_info_object *disasm_info = (disasm_info_object *) info_obj;
  DISASMPY_DISASM_INFO_REQUIRE_VALID (disasm_info);

  /* Where the result will be written.  */
  gdbpy_disassembler disassembler (disasm_info);

  /* Now actually perform the disassembly.  LENGTH is set to the length of
     the disassembled instruction, or -1 if there was a memory-error
     encountered while disassembling.  See below more more details on
     handling of -1 return value.  */
  int length = gdbarch_print_insn (disasm_info->gdbarch, disasm_info->address,
				   disassembler.disasm_info ());

  /* It is possible that, while calling a user overridden memory read
     function, a Python exception was raised that couldn't be
     translated into a standard memory-error.  In this case the first such
     exception is stored in the disassembler and restored here.  */
  if (disassembler.restore_exception ())
    return nullptr;

  if (length == -1)
    {

      /* In an ideal world, every disassembler should always call the
	 memory error function before returning a status of -1 as the only
	 error a disassembler should encounter is a failure to read
	 memory.  Unfortunately, there are some disassemblers who don't
	 follow this rule, and will return -1 without calling the memory
	 error function.

	 To make the Python API simpler, we just classify everything as a
	 memory error, but the message has to be modified for the case
	 where the disassembler didn't call the memory error function.  */
      if (disassembler.memory_error_address ().has_value ())
	{
	  CORE_ADDR addr = *disassembler.memory_error_address ();
	  disasmpy_set_memory_error_for_address (addr);
	}
      else
	{
	  auto content = disassembler.release ();
	  std::string str;

	  try
	    {
	      str = disasmpy_parts_list_to_string (content);
	    }
	  catch (const gdb_exception &except)
	    {
	      return gdbpy_handle_gdb_exception (nullptr, except);
	    }
	  if (!str.empty ())
	    PyErr_SetString (gdbpy_gdberror_exc, str.c_str ());
	  else
	    PyErr_SetString (gdbpy_gdberror_exc,
			     _("Unknown disassembly error."));
	}
      return nullptr;
    }

  /* Instructions are either non-zero in length, or we got an error,
     indicated by a length of -1, which we handled above.  */
  gdb_assert (length > 0);

  /* We should not have seen a memory error in this case.  */
  gdb_assert (!disassembler.memory_error_address ().has_value ());

  /* Create a DisassemblerResult containing the results.  */
  PyTypeObject *type = &disasm_result_object_type;
  gdbpy_ref<disasm_result_object> res
    ((disasm_result_object *) type->tp_alloc (type, 0));
  auto content = disassembler.release ();
  disasmpy_init_disassembler_result (res.get (), length, std::move (content));
  return reinterpret_cast<PyObject *> (res.release ());
}

/* Implement gdb._set_enabled function.  Takes a boolean parameter, and
   sets whether GDB should enter the Python disassembler code or not.

   This is called from within the Python code when a new disassembler is
   registered.  When no disassemblers are registered the global C++ flag
   is set to false, and GDB never even enters the Python environment to
   check for a disassembler.

   When the user registers a new Python disassembler, the global C++ flag
   is set to true, and now GDB will enter the Python environment to check
   if there's a disassembler registered for the current architecture.  */

static PyObject *
disasmpy_set_enabled (PyObject *self, PyObject *args, PyObject *kw)
{
  PyObject *newstate;
  static const char *keywords[] = { "state", nullptr };
  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O!", keywords,
					&PyBool_Type, &newstate))
    return nullptr;

  python_print_insn_enabled = newstate == Py_True;
  return py_none ().release ();
}

/* Implement DisassembleInfo.read_memory(LENGTH, OFFSET).  Read LENGTH
   bytes at OFFSET from the start of the instruction currently being
   disassembled, and return a memory buffer containing the bytes.

   OFFSET defaults to zero if it is not provided.  LENGTH is required.  If
   the read fails then this will raise a gdb.MemoryError exception.  */

static PyObject *
disasmpy_info_read_memory (PyObject *self, PyObject *args, PyObject *kw)
{
  disasm_info_object *obj = (disasm_info_object *) self;
  DISASMPY_DISASM_INFO_REQUIRE_VALID (obj);

  gdb_py_longest length, offset = 0;
  gdb::unique_xmalloc_ptr<gdb_byte> buffer;
  static const char *keywords[] = { "length", "offset", nullptr };

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw,
					GDB_PY_LL_ARG "|" GDB_PY_LL_ARG,
					keywords, &length, &offset))
    return nullptr;

  /* The apparent address from which we are reading memory.  Note that in
     some cases GDB actually disassembles instructions from a buffer, so
     we might not actually be reading this information directly from the
     inferior memory.  This is all hidden behind the read_memory_func API
     within the disassemble_info structure.  */
  CORE_ADDR address = obj->address + offset;

  /* Setup a buffer to hold the result.  */
  buffer.reset ((gdb_byte *) xmalloc (length));

  /* Read content into BUFFER.  If the read fails then raise a memory
     error, otherwise, convert BUFFER to a Python memory buffer, and return
     it to the user.  */
  disassemble_info *info = obj->gdb_info;
  if (info->read_memory_func ((bfd_vma) address, buffer.get (),
			      (unsigned int) length, info) != 0)
    {
      disasmpy_set_memory_error_for_address (address);
      return nullptr;
    }
  return gdbpy_buffer_to_membuf (std::move (buffer), address, length);
}

/* Implement DisassembleInfo.address attribute, return the address at which
   GDB would like an instruction disassembled.  */

static PyObject *
disasmpy_info_address (PyObject *self, void *closure)
{
  disasm_info_object *obj = (disasm_info_object *) self;
  DISASMPY_DISASM_INFO_REQUIRE_VALID (obj);
  return gdb_py_object_from_longest (obj->address).release ();
}

/* Implement DisassembleInfo.architecture attribute.  Return the
   gdb.Architecture in which we are disassembling.  */

static PyObject *
disasmpy_info_architecture (PyObject *self, void *closure)
{
  disasm_info_object *obj = (disasm_info_object *) self;
  DISASMPY_DISASM_INFO_REQUIRE_VALID (obj);
  return gdbarch_to_arch_object (obj->gdbarch).release ();
}

/* Implement DisassembleInfo.progspace attribute.  Return the
   gdb.Progspace in which we are disassembling.  */

static PyObject *
disasmpy_info_progspace (PyObject *self, void *closure)
{
  disasm_info_object *obj = (disasm_info_object *) self;
  DISASMPY_DISASM_INFO_REQUIRE_VALID (obj);
  return pspace_to_pspace_object (obj->program_space).release ();
}

/* Helper function called when the libopcodes disassembler produces some
   output.  FORMAT and ARGS are used to create a string which GDB will
   display using STYLE.  The string is either added as a new
   DisassemblerTextPart to the list of parts being built in the current
   gdbpy_disassembler object (accessed through DIS_INFO).  Or, if the last
   part in the gdbpy_disassembler is a text part in the same STYLE, then
   the new string is appended to the previous part.

   The merging behavior make the Python API a little more user friendly,
   some disassemblers produce their output character at a time, there's no
   particular reason for this, it's just how they are implemented.  By
   merging parts with the same style we make it easier for the user to
   analyse the disassembler output.  */

int
gdbpy_disassembler::vfprintf_styled_func (void *dis_info,
					  enum disassembler_style style,
					  const char *format,
					  va_list args) noexcept
{
  gdb_disassemble_info *di = (gdb_disassemble_info *) dis_info;
  gdbpy_disassembler *dis
    = gdb::checked_static_cast<gdbpy_disassembler *> (di);

  if (!dis->m_parts.empty ()
      && Py_TYPE (dis->m_parts.back ().get ()) == &disasm_text_part_object_type
      && (((disasm_text_part_object *) dis->m_parts.back ().get ())->style
	  == style))
    {
      std::string *string
	= ((disasm_text_part_object *) dis->m_parts.back ().get ())->string;
      string_vappendf (*string, format, args);
    }
  else
    {
      std::string str = string_vprintf (format, args);
      if (str.size () > 0)
	{
	  gdbpy_ref<> text_part
	    = make_disasm_text_part (std::move (str), style);
	  dis->m_parts.emplace_back (std::move (text_part));
	}
    }

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

/* Disassembler callback for architectures where libopcodes doesn't
   created styled output.  In these cases we format all the output using
   the (default) text style.  */

int
gdbpy_disassembler::fprintf_func (void *dis_info,
				  const char *format, ...) noexcept
{
  va_list args;
  va_start (args, format);
  vfprintf_styled_func (dis_info, dis_style_text, format, args);
  va_end (args);

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

/* Disassembler callback for architectures where libopcodes does create
   styled output.  Just creates a new text part with the given STYLE.  */

int
gdbpy_disassembler::fprintf_styled_func (void *dis_info,
					 enum disassembler_style style,
					 const char *format, ...) noexcept
{
  va_list args;
  va_start (args, format);
  vfprintf_styled_func (dis_info, style, format, args);
  va_end (args);

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

/* This implements the disassemble_info read_memory_func callback and is
   called from the libopcodes disassembler when the disassembler wants to
   read memory.

   From the INFO argument we can find the gdbpy_disassembler object for
   which we are disassembling, and from that object we can find the
   DisassembleInfo for the current disassembly call.

   This function reads the instruction bytes by calling the read_memory
   method on the DisassembleInfo object.  This method might have been
   overridden by user code.

   Read LEN bytes from MEMADDR and place them into BUFF.  Return 0 on
   success (in which case BUFF has been filled), or -1 on error, in which
   case the contents of BUFF are undefined.  */

int
gdbpy_disassembler::read_memory_func (bfd_vma memaddr, gdb_byte *buff,
				      unsigned int len,
				      struct disassemble_info *info) noexcept
{
  gdbpy_disassembler *dis
    = static_cast<gdbpy_disassembler *> (info->application_data);
  disasm_info_object *obj = dis->py_disasm_info ();

  /* If a previous read attempt resulted in an exception, then we don't
     allow any further reads to succeed.  We only do this check for the
     read_memory_func as this is the only one the user can hook into,
     thus, this check prevents us calling back into user code if a
     previous call has already thrown an error.  */
  if (dis->has_stored_exception ())
    return -1;

  /* The DisassembleInfo.read_memory method expects an offset from the
     address stored within the DisassembleInfo object; calculate that
     offset here.  */
  gdb_py_longest offset
    = (gdb_py_longest) memaddr - (gdb_py_longest) obj->address;

  /* Now call the DisassembleInfo.read_memory method.  This might have been
     overridden by the user.  */
  gdbpy_ref<> result_obj = gdbpy_call_method ((PyObject *) obj, "read_memory",
					      len, offset);

  /* Handle any exceptions.  */
  if (result_obj == nullptr)
    {
      /* If we got a gdb.MemoryError then we ignore this and just report
	 that the read failed to the caller.  The caller is then
	 responsible for calling the memory_error_func if it wants to.
	 Remember, the disassembler might just be probing to see if these
	 bytes can be read, if we automatically call the memory error
	 function, we can end up registering an error prematurely.  */
      if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error))
	{
	  PyErr_Clear ();
	  return -1;
	}

      /* For any other exception type we capture the value of the Python
	 exception and throw it, this will then be caught in
	 disasmpy_builtin_disassemble, at which point the exception will be
	 restored.  */
      dis->store_exception (gdbpy_err_fetch ());
      return -1;
    }

  /* Convert the result to a buffer.  */
  Py_buffer py_buff;
  if (!PyObject_CheckBuffer (result_obj.get ())
      || PyObject_GetBuffer (result_obj.get(), &py_buff, PyBUF_CONTIG_RO) < 0)
    {
      PyErr_Format (PyExc_TypeError,
		    _("Result from read_memory is not a buffer"));
      dis->store_exception (gdbpy_err_fetch ());
      return -1;
    }

  /* Wrap PY_BUFF so that it is cleaned up correctly at the end of this
     scope.  */
  Py_buffer_up buffer_up (&py_buff);

  /* Validate that the buffer is the correct length.  */
  if (py_buff.len != len)
    {
      PyErr_Format (PyExc_ValueError,
		    _("Buffer returned from read_memory is sized %d instead of the expected %d"),
		    py_buff.len, len);
      dis->store_exception (gdbpy_err_fetch ());
      return -1;
    }

  /* Copy the data out of the Python buffer and return success.  */
  const gdb_byte *buffer = (const gdb_byte *) py_buff.buf;
  memcpy (buff, buffer, len);
  return 0;
}

/* Implement __str__ for the DisassemblerResult type.  */

static PyObject *
disasmpy_result_str (PyObject *self)
{
  disasm_result_object *obj = (disasm_result_object *) self;

  /* These conditions are all enforced when the DisassemblerResult object
     is created.  */
  gdb_assert (obj->parts != nullptr);
  gdb_assert (obj->parts->size () > 0);
  gdb_assert (obj->length > 0);

  std::string str;

  try
    {
      str = disasmpy_parts_list_to_string (*obj->parts);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return PyUnicode_Decode (str.c_str (), str.size (),
			   host_charset (), nullptr);
}

/* Implement DisassemblerResult.length attribute, return the length of the
   disassembled instruction.  */

static PyObject *
disasmpy_result_length (PyObject *self, void *closure)
{
  disasm_result_object *obj = (disasm_result_object *) self;
  return gdb_py_object_from_longest (obj->length).release ();
}

/* Implement DisassemblerResult.string attribute, return the content string
   of the disassembled instruction.  */

static PyObject *
disasmpy_result_string (PyObject *self, void *closure)
{
  return disasmpy_result_str (self);
}

/* Implement DisassemblerResult.parts method.  Returns a list of all the
   parts that make up this result.  There should always be at least one
   part, so the returned list should never be empty.  */

static PyObject *
disasmpy_result_parts (PyObject *self, void *closure)
{
  disasm_result_object *obj = (disasm_result_object *) self;

  /* These conditions are all enforced when the DisassemblerResult object
     is created.  */
  gdb_assert (obj->parts != nullptr);
  gdb_assert (obj->parts->size () > 0);
  gdb_assert (obj->length > 0);

  gdbpy_ref<> result_list (PyList_New (obj->parts->size ()));
  if (result_list == nullptr)
    return nullptr;
  Py_ssize_t idx = 0;
  for (auto p : *obj->parts)
    {
      gdbpy_ref<> item = gdbpy_ref<>::new_reference (p.get ());
      PyList_SET_ITEM (result_list.get (), idx, item.release ());
      ++idx;
    }

  /* This should follow naturally from the obj->parts list being
     non-empty.  */
  gdb_assert (PyList_Size (result_list.get()) > 0);

  return result_list.release ();
}

/* Implement DisassemblerResult.__init__.  Takes two arguments, an
   integer, the length in bytes of the disassembled instruction, and a
   string, the disassembled content of the instruction.  */

static int
disasmpy_result_init (PyObject *self, PyObject *args, PyObject *kwargs)
{
  static const char *keywords[] = { "length", "string", "parts", NULL };
  int length;
  const char *string = nullptr;
  PyObject *parts_list = nullptr;
  if (!gdb_PyArg_ParseTupleAndKeywords (args, kwargs, "i|zO", keywords,
					&length, &string, &parts_list))
    return -1;

  if (length <= 0)
    {
      PyErr_SetString (PyExc_ValueError,
		       _("Length must be greater than 0."));
      return -1;
    }

  if (parts_list == Py_None)
    parts_list = nullptr;

  if (string != nullptr && parts_list != nullptr)
    {
      PyErr_Format (PyExc_ValueError,
		    _("Cannot use 'string' and 'parts' when creating %s."),
		    gdbpy_py_obj_tp_name (self).c_str ());
      return -1;
    }

  if (string != nullptr)
    {
      if (strlen (string) == 0)
	{
	  PyErr_SetString (PyExc_ValueError,
			   _("String must not be empty."));
	  return -1;
	}

      disasm_result_object *obj = (disasm_result_object *) self;
      std::vector<gdbpy_ref<>> content;
      gdbpy_ref<> text_part
	= make_disasm_text_part (std::string (string), dis_style_text);
      content.emplace_back (text_part.release ());
      disasmpy_init_disassembler_result (obj, length, std::move (content));
    }
  else
    {
      if (!PySequence_Check (parts_list))
	{
	  PyErr_SetString (PyExc_TypeError,
			   _("'parts' argument is not a sequence"));
	  return -1;
	}

      Py_ssize_t parts_count = PySequence_Size (parts_list);
      if (parts_count <= 0)
	{
	  PyErr_SetString (PyExc_ValueError,
			   _("'parts' list must not be empty."));
	  return -1;
	}

      disasm_result_object *obj = (disasm_result_object *) self;
      std::vector<gdbpy_ref<>> content (parts_count);

      struct gdbarch *gdbarch = nullptr;
      for (Py_ssize_t i = 0; i < parts_count; ++i)
	{
	  gdbpy_ref<> part (PySequence_GetItem (parts_list, i));

	  if (part == nullptr)
	    return -1;

	  if (Py_TYPE (part.get ()) == &disasm_addr_part_object_type)
	    {
	      disasm_addr_part_object *addr_part
		= (disasm_addr_part_object *) part.get ();
	      gdb_assert (addr_part->gdbarch != nullptr);
	      if (gdbarch == nullptr)
		gdbarch = addr_part->gdbarch;
	      else if (addr_part->gdbarch != gdbarch)
		{
		  PyErr_SetString (PyExc_ValueError,
				   _("Inconsistent gdb.Architectures used "
				     "in 'parts' sequence."));
		  return -1;
		}
	    }

	  content[i] = std::move (part);
	}

      disasmpy_init_disassembler_result (obj, length, std::move (content));
    }

  return 0;

}

/* Implement __repr__ for the DisassemblerResult type.  */

static PyObject *
disasmpy_result_repr (PyObject *self)
{
  disasm_result_object *obj = (disasm_result_object *) self;

  gdb_assert (obj->parts != nullptr);

  return PyUnicode_FromFormat ("<%s length=%d string=\"%U\">",
			       gdbpy_py_obj_tp_name (self).c_str (),
			       obj->length,
			       disasmpy_result_str (self));
}

/* Implement memory_error_func callback for disassemble_info.  Extract the
   underlying DisassembleInfo Python object, and set a memory error on
   it.  */

void
gdbpy_disassembler::memory_error_func (int status, bfd_vma memaddr,
				       struct disassemble_info *info) noexcept
{
  gdbpy_disassembler *dis
    = static_cast<gdbpy_disassembler *> (info->application_data);
  dis->m_memory_error_address.emplace (memaddr);
}

/* Wrapper of print_address.  */

void
gdbpy_disassembler::print_address_func (bfd_vma addr,
					struct disassemble_info *info) noexcept
{
  gdbpy_disassembler *dis
    = static_cast<gdbpy_disassembler *> (info->application_data);

  gdbpy_ref<> addr_part
    = make_disasm_addr_part (dis->arch (), addr);
  dis->m_parts.emplace_back (std::move (addr_part));
}

/* constructor.  */

gdbpy_disassembler::gdbpy_disassembler (disasm_info_object *obj)
  : gdb_disassemble_info (obj->gdbarch,
			  read_memory_func,
			  memory_error_func,
			  print_address_func,
			  fprintf_func,
			  fprintf_styled_func),
    m_disasm_info_object (obj)
{ /* Nothing.  */ }

/* A wrapper around a reference to a Python DisassembleInfo object, which
   ensures that the object is marked as invalid when we leave the enclosing
   scope.

   Each DisassembleInfo is created in gdbpy_print_insn, and is done with by
   the time that function returns.  However, there's nothing to stop a user
   caching a reference to the DisassembleInfo, and thus keeping the object
   around.

   We therefore have the notion of a DisassembleInfo becoming invalid, this
   happens when gdbpy_print_insn returns.  This class is responsible for
   marking the DisassembleInfo as invalid in its destructor.  */

struct scoped_invalidate_disasm_info
{
  /* Constructor.  Just cache DISASM_INFO for use in the destructor.  */
  scoped_invalidate_disasm_info
    (gdbpy_ref<disasm_info_object> disasm_info)
      : m_disasm_info (std::move (disasm_info))
  {
    /* Nothing.  */
  }

  /* Upon destruction mark m_disasm_info as invalid.  */
  ~scoped_invalidate_disasm_info ()
  {
    /* Invalidate the original DisassembleInfo object as well as any copies
       that the user might have made.  */
    for (disasm_info_object *obj = m_disasm_info.get ();
	 obj != nullptr;
	 obj = obj->next)
      obj->gdb_info = nullptr;
  }

private:

  /* A reference to a gdb.disassembler.DisassembleInfo object.  When this
     object goes out of scope this reference is released, however, the user
     might be holding other references to the DisassembleInfo (either
     directly, or via copies of this object), in which case the underlying
     object will not be deleted.  The destructor of this class ensures
     that this DisassembleInfo object, and any copies, are all marked
     invalid.  */
  gdbpy_ref<disasm_info_object> m_disasm_info;
};

/* See python-internal.h.  */

std::optional<int>
gdbpy_print_insn (struct gdbarch *gdbarch, CORE_ADDR memaddr,
		  disassemble_info *info)
{
  /* Early exit case.  This must be done as early as possible, and
     definitely before we enter Python environment.  The
     python_print_insn_enabled flag is set (from Python) only when the user
     has installed one (or more) Python disassemblers.  So in the common
     case (no custom disassembler installed) this flag will be false,
     allowing for a quick return.  */
  if (!gdb_python_initialized || !python_print_insn_enabled)
    return {};

  gdbpy_enter enter_py (get_current_arch (), current_language);

  /* Import the gdb.disassembler module.  */
  gdbpy_ref<> gdb_python_disassembler_module
    (PyImport_ImportModule ("gdb.disassembler"));
  if (gdb_python_disassembler_module == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  /* Get the _print_insn attribute from the module, this should be the
     function we are going to call to actually perform the disassembly.  */
  gdbpy_ref<> hook
    (PyObject_GetAttrString (gdb_python_disassembler_module.get (),
			     "_print_insn"));
  if (hook == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  /* Create the new DisassembleInfo object we will pass into Python.  */
  gdbpy_ref<disasm_info_object> disasm_info
    ((disasm_info_object *) PyObject_New (disasm_info_object,
					  &disasm_info_object_type));
  if (disasm_info == nullptr)
    {
      gdbpy_print_stack ();
      return {};
    }

  /* Initialise the DisassembleInfo object.  */
  disasm_info_fill (*disasm_info.get (), gdbarch, current_program_space,
		    memaddr, info, nullptr);

  /* Ensure the DisassembleInfo, along with any copies the user makes, are
     marked as invalid when we leave this scope.  */
  scoped_invalidate_disasm_info invalidate_disasm (disasm_info);

  /* Call into the registered disassembler to (possibly) perform the
     disassembly.  */
  gdbpy_ref<> result
    (PyObject_CallFunctionObjArgs (hook.get (),
				   (PyObject *) disasm_info.get (),
				   nullptr));

  if (result == nullptr)
    {
      /* The call into Python code resulted in an exception.  If this was a
	 gdb.MemoryError, then we can figure out an address and call the
	 disassemble_info::memory_error_func to report the error back to
	 core GDB.  Any other exception type we report back to core GDB as
	 an unknown error (return -1 without first calling the
	 memory_error_func callback).  */

      if (PyErr_ExceptionMatches (gdbpy_gdb_memory_error))
	{
	  /* A gdb.MemoryError might have an address attribute which
	     contains the address at which the memory error occurred.  If
	     this is the case then use this address, otherwise, fallback to
	     just using the address of the instruction we were asked to
	     disassemble.  */
	  gdbpy_err_fetch err;
	  PyErr_Clear ();

	  CORE_ADDR addr;
	  if (err.value () != nullptr
	      && PyObject_HasAttrString (err.value ().get (), "address"))
	    {
	      PyObject *addr_obj
		= PyObject_GetAttrString (err.value ().get (), "address");
	      if (get_addr_from_python (addr_obj, &addr) < 0)
		addr = disasm_info->address;
	    }
	  else
	    addr = disasm_info->address;

	  info->memory_error_func (-1, addr, info);
	  return std::optional<int> (-1);
	}
      else if (PyErr_ExceptionMatches (gdbpy_gdberror_exc))
	{
	  gdbpy_err_fetch err;
	  gdb::unique_xmalloc_ptr<char> msg = err.to_string ();

	  info->fprintf_func (info->stream, "%s", msg.get ());
	  return std::optional<int> (-1);
	}
      else
	{
	  gdbpy_print_stack_or_quit ();
	  return std::optional<int> (-1);
	}

    }
  else if (result == Py_None)
    {
      /* A return value of None indicates that the Python code could not,
	 or doesn't want to, disassemble this instruction.  Just return an
	 empty result and core GDB will try to disassemble this for us.  */
      return {};
    }

  /* Check the result is a DisassemblerResult.  */
  if (!PyObject_TypeCheck (result.get (), &disasm_result_object_type))
    {
      PyErr_Format
	(PyExc_TypeError,
	 _("Result from Disassembler must be gdb.DisassemblerResult, not %s."),
	 gdbpy_py_obj_tp_name (result.get ()).c_str ());
      gdbpy_print_stack ();
      return std::optional<int> (-1);
    }

  /* The result from the Python disassembler has the correct type.  Convert
     this back to the underlying C++ object and read the state directly
     from this object.  */
  struct disasm_result_object *result_obj
    = (struct disasm_result_object *) result.get ();

  /* Validate the length of the disassembled instruction.  */
  long length = result_obj->length;
  long max_insn_length = (gdbarch_max_insn_length_p (gdbarch) ?
			  gdbarch_max_insn_length (gdbarch) : INT_MAX);
  if (length <= 0)
    {
      PyErr_SetString
	(PyExc_ValueError,
	 _("Invalid length attribute: length must be greater than 0."));
      gdbpy_print_stack ();
      return std::optional<int> (-1);
    }
  if (length > max_insn_length)
    {
      PyErr_Format
	(PyExc_ValueError,
	 _("Invalid length attribute: length %d greater than architecture maximum of %d"),
	 length, max_insn_length);
      gdbpy_print_stack ();
      return std::optional<int> (-1);
    }

  /* It is impossible to create a DisassemblerResult object with an empty
     parts list.  We know that each part results in a non-empty string, so
     we know that the instruction disassembly will not be the empty
     string.  */
  gdb_assert (result_obj->parts->size () > 0);

  /* Now print out the parts that make up this instruction.  */
  for (auto &p : *result_obj->parts)
    {
      if (Py_TYPE (p.get ()) == &disasm_text_part_object_type)
	{
	  disasm_text_part_object *text_part
	    = (disasm_text_part_object *) p.get ();
	  gdb_assert (text_part->string != nullptr);
	  info->fprintf_styled_func (info->stream, text_part->style,
				     "%s", text_part->string->c_str ());
	}
      else
	{
	  gdb_assert (Py_TYPE (p.get ()) == &disasm_addr_part_object_type);
	  disasm_addr_part_object *addr_part
	    = (disasm_addr_part_object *) p.get ();
	  /* A DisassemblerAddressPart can only be created by calling a
	     method on DisassembleInfo, and the gdbarch is copied from the
	     DisassembleInfo into the DisassemblerAddressPart.  As the
	     DisassembleInfo has its gdbarch initialised from GDBARCH in
	     this scope, and this architecture can't be changed, then the
	     following assert should hold.  */
	  gdb_assert (addr_part->gdbarch == gdbarch);
	  info->print_address_func (addr_part->address, info);
	}
    }

  return std::optional<int> (length);
}

/* The tp_dealloc callback for the DisassemblerResult type.  Takes care of
   deallocating the content buffer.  */

static void
disasmpy_dealloc_result (PyObject *self)
{
  disasm_result_object *obj = (disasm_result_object *) self;
  delete obj->parts;
  Py_TYPE (self)->tp_free (self);
}

/* The tp_init callback for the DisassemblerPart type.  This just raises an
   exception, which prevents the user from creating objects of this type.
   Instead the user should create instances of a sub-class.  */

static int
disasmpy_part_init (PyObject *self, PyObject *args, PyObject *kwargs)
{
  PyErr_Format (PyExc_RuntimeError,
		_("Cannot create instances of %s."),
		gdbpy_py_obj_tp_name (self).c_str ());
  return -1;
}

/* Return a string representing STYLE.  The returned string is used as a
   constant defined in the gdb.disassembler module.  */

static const char *
get_style_name (enum disassembler_style style)
{
  switch (style)
    {
    case dis_style_text: return "STYLE_TEXT";
    case dis_style_mnemonic: return "STYLE_MNEMONIC";
    case dis_style_sub_mnemonic: return "STYLE_SUB_MNEMONIC";
    case dis_style_assembler_directive: return "STYLE_ASSEMBLER_DIRECTIVE";
    case dis_style_register: return "STYLE_REGISTER";
    case dis_style_immediate: return "STYLE_IMMEDIATE";
    case dis_style_address: return "STYLE_ADDRESS";
    case dis_style_address_offset: return "STYLE_ADDRESS_OFFSET";
    case dis_style_symbol: return "STYLE_SYMBOL";
    case dis_style_comment_start: return "STYLE_COMMENT_START";
    }

  gdb_assert_not_reached ("unknown disassembler style");
}

/* Implement DisassemblerTextPart.__repr__ method.  */

static PyObject *
disasmpy_text_part_repr (PyObject *self)
{
  disasm_text_part_object *obj = (disasm_text_part_object *) self;

  gdb_assert (obj->string != nullptr);

  return PyUnicode_FromFormat ("<%s string='%s', style='%s'>",
			       gdbpy_py_obj_tp_name (self).c_str (),
			       obj->string->c_str (),
			       get_style_name (obj->style));
}

/* Implement DisassemblerTextPart.__str__ attribute.  */

static PyObject *
disasmpy_text_part_str (PyObject *self)
{
  disasm_text_part_object *obj = (disasm_text_part_object *) self;

  return PyUnicode_Decode (obj->string->c_str (), obj->string->size (),
			   host_charset (), nullptr);
}

/* Implement DisassemblerTextPart.string attribute.  */

static PyObject *
disasmpy_text_part_string (PyObject *self, void *closure)
{
  return disasmpy_text_part_str (self);
}

/* Implement DisassemblerTextPart.style attribute.   */

static PyObject *
disasmpy_text_part_style (PyObject *self, void *closure)
{
  disasm_text_part_object *obj = (disasm_text_part_object *) self;

  LONGEST style_val = (LONGEST) obj->style;
  return gdb_py_object_from_longest (style_val).release ();
}

/* Implement DisassemblerAddressPart.__repr__ method.  */

static PyObject *
disasmpy_addr_part_repr (PyObject *self)
{
  disasm_addr_part_object *obj = (disasm_addr_part_object *) self;

  return PyUnicode_FromFormat ("<%s address='%s'>",
			       gdbpy_py_obj_tp_name (self).c_str (),
			       core_addr_to_string_nz (obj->address));
}

/* Implement DisassemblerAddressPart.__str__ attribute.  */

static PyObject *
disasmpy_addr_part_str (PyObject *self)
{
  disasm_addr_part_object *obj = (disasm_addr_part_object *) self;

  std::string str;
  try
    {
      string_file buf;
      print_address (obj->gdbarch, obj->address, &buf);
      str = buf.release ();
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return PyUnicode_Decode (str.c_str (), str.size (),
			   host_charset (), nullptr);
}

/* Implement DisassemblerAddressPart.string attribute.  */

static PyObject *
disasmpy_addr_part_string (PyObject *self, void *closure)
{
  return disasmpy_addr_part_str (self);
}

/* Implement DisassemblerAddressPart.address attribute.  */

static PyObject *
disasmpy_addr_part_address (PyObject *self, void *closure)
{
  disasm_addr_part_object *obj = (disasm_addr_part_object *) self;

  return gdb_py_object_from_longest (obj->address).release ();
}

/* The get/set attributes of the gdb.disassembler.DisassembleInfo type.  */

static gdb_PyGetSetDef disasm_info_object_getset[] = {
  { "address", disasmpy_info_address, nullptr,
    "Start address of the instruction to disassemble.", nullptr },
  { "architecture", disasmpy_info_architecture, nullptr,
    "Architecture to disassemble in", nullptr },
  { "progspace", disasmpy_info_progspace, nullptr,
    "Program space to disassemble in", nullptr },
  { nullptr }   /* Sentinel */
};

/* The methods of the gdb.disassembler.DisassembleInfo type.  */

static PyMethodDef disasm_info_object_methods[] = {
  { "read_memory", (PyCFunction) disasmpy_info_read_memory,
    METH_VARARGS | METH_KEYWORDS,
    "read_memory (LEN, OFFSET = 0) -> Octets[]\n\
Read LEN octets for the instruction to disassemble." },
  { "is_valid", disasmpy_info_is_valid, METH_NOARGS,
    "is_valid () -> Boolean.\n\
Return true if this DisassembleInfo is valid, false if not." },
  { "text_part", (PyCFunction) disasmpy_info_make_text_part,
    METH_VARARGS | METH_KEYWORDS,
    "text_part (STRING, STYLE) -> DisassemblerTextPart\n\
Create a new text part, with contents STRING styled with STYLE." },
  { "address_part", (PyCFunction) disasmpy_info_make_address_part,
    METH_VARARGS | METH_KEYWORDS,
    "address_part (ADDRESS) -> DisassemblerAddressPart\n\
Create a new address part representing ADDRESS." },
  {nullptr}  /* Sentinel */
};

/* The get/set attributes of the gdb.disassembler.DisassemblerResult type.  */

static gdb_PyGetSetDef disasm_result_object_getset[] = {
  { "length", disasmpy_result_length, nullptr,
    "Length of the disassembled instruction.", nullptr },
  { "string", disasmpy_result_string, nullptr,
    "String representing the disassembled instruction.", nullptr },
  { "parts", disasmpy_result_parts, nullptr,
    "List of all the separate disassembly parts", nullptr },
  { nullptr }   /* Sentinel */
};

/* The get/set attributes of the gdb.disassembler.DisassemblerTextPart type.  */

static gdb_PyGetSetDef disasmpy_text_part_getset[] = {
  { "string", disasmpy_text_part_string, nullptr,
    "String representing a text part.", nullptr },
  { "style", disasmpy_text_part_style, nullptr,
    "The style of this text part.", nullptr },
  { nullptr }   /* Sentinel */
};

/* The get/set attributes of the gdb.disassembler.DisassemblerAddressPart type.  */

static gdb_PyGetSetDef disasmpy_addr_part_getset[] = {
  { "string", disasmpy_addr_part_string, nullptr,
    "String representing an address part.", nullptr },
  { "address", disasmpy_addr_part_address, nullptr,
    "The address of this address part.", nullptr },
  { nullptr }   /* Sentinel */
};

/* These are the methods we add into the _gdb.disassembler module, which
   are then imported into the gdb.disassembler module.  These are global
   functions that support performing disassembly.  */

PyMethodDef python_disassembler_methods[] =
{
  { "builtin_disassemble", (PyCFunction) disasmpy_builtin_disassemble,
    METH_VARARGS | METH_KEYWORDS,
    "builtin_disassemble (INFO) -> None\n\
Disassemble using GDB's builtin disassembler.  INFO is an instance of\n\
gdb.disassembler.DisassembleInfo." },
  { "_set_enabled", (PyCFunction) disasmpy_set_enabled,
    METH_VARARGS | METH_KEYWORDS,
    "_set_enabled (STATE) -> None\n\
Set whether GDB should call into the Python _print_insn code or not." },
  {nullptr, nullptr, 0, nullptr}
};

/* Structure to define the _gdb.disassembler module.  */

static struct PyModuleDef python_disassembler_module_def =
{
  PyModuleDef_HEAD_INIT,
  "_gdb.disassembler",
  nullptr,
  -1,
  python_disassembler_methods,
  nullptr,
  nullptr,
  nullptr,
  nullptr
};

/* Called to initialize the Python structures in this file.  */

static int
gdbpy_initialize_disasm ()
{
  /* Create the _gdb.disassembler module, and add it to the _gdb module.  */

  PyObject *gdb_disassembler_module;
  gdb_disassembler_module = PyModule_Create (&python_disassembler_module_def);
  if (gdb_disassembler_module == nullptr)
    return -1;
  if (gdb_pymodule_addobject (gdb_module, "disassembler",
			      gdb_disassembler_module) < 0)
    return -1;

  /* This is needed so that 'import _gdb.disassembler' will work.  */
  PyObject *dict = PyImport_GetModuleDict ();
  if (PyDict_SetItemString (dict, "_gdb.disassembler",
			    gdb_disassembler_module) < 0)
    return -1;

  for (int i = 0; i <= (int) dis_style_comment_start; ++i)
    {
      const char *style_name = get_style_name ((enum disassembler_style) i);
      if (PyModule_AddIntConstant (gdb_disassembler_module, style_name, i) < 0)
	return -1;
    }

  disasm_info_object_type.tp_new = PyType_GenericNew;
  if (gdbpy_type_ready (&disasm_info_object_type, gdb_disassembler_module) < 0)
    return -1;

  disasm_result_object_type.tp_new = PyType_GenericNew;
  if (gdbpy_type_ready (&disasm_result_object_type, gdb_disassembler_module) < 0)
    return -1;

  disasm_part_object_type.tp_new = PyType_GenericNew;
  if (gdbpy_type_ready (&disasm_part_object_type, gdb_disassembler_module) < 0)
    return -1;

  disasm_addr_part_object_type.tp_new = PyType_GenericNew;
  if (gdbpy_type_ready (&disasm_addr_part_object_type, gdb_disassembler_module) < 0)
    return -1;

  disasm_text_part_object_type.tp_new = PyType_GenericNew;
  if (gdbpy_type_ready (&disasm_text_part_object_type, gdb_disassembler_module) < 0)
    return -1;

  return 0;
}

GDBPY_INITIALIZE_FILE (gdbpy_initialize_disasm);



/* Describe the gdb.disassembler.DisassembleInfo type.  */

PyTypeObject disasm_info_object_type = {
  PyVarObject_HEAD_INIT (nullptr, 0)
  "gdb.disassembler.DisassembleInfo",		/*tp_name*/
  sizeof (disasm_info_object),			/*tp_basicsize*/
  0,						/*tp_itemsize*/
  disasm_info_dealloc,				/*tp_dealloc*/
  0,						/*tp_print*/
  0,						/*tp_getattr*/
  0,						/*tp_setattr*/
  0,						/*tp_compare*/
  disasmpy_info_repr,				/*tp_repr*/
  0,						/*tp_as_number*/
  0,						/*tp_as_sequence*/
  0,						/*tp_as_mapping*/
  0,						/*tp_hash */
  0,						/*tp_call*/
  0,						/*tp_str*/
  0,						/*tp_getattro*/
  0,						/*tp_setattro*/
  0,						/*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/*tp_flags*/
  "GDB instruction disassembler object",	/* tp_doc */
  0,						/* tp_traverse */
  0,						/* tp_clear */
  0,						/* tp_richcompare */
  0,						/* tp_weaklistoffset */
  0,						/* tp_iter */
  0,						/* tp_iternext */
  disasm_info_object_methods,			/* tp_methods */
  0,						/* tp_members */
  disasm_info_object_getset,			/* tp_getset */
  0,						/* tp_base */
  0,						/* tp_dict */
  0,						/* tp_descr_get */
  0,						/* tp_descr_set */
  0,						/* tp_dictoffset */
  disasm_info_init,				/* tp_init */
  0,						/* tp_alloc */
};

/* Describe the gdb.disassembler.DisassemblerResult type.  */

PyTypeObject disasm_result_object_type = {
  PyVarObject_HEAD_INIT (nullptr, 0)
  "gdb.disassembler.DisassemblerResult",	/*tp_name*/
  sizeof (disasm_result_object),		/*tp_basicsize*/
  0,						/*tp_itemsize*/
  disasmpy_dealloc_result,			/*tp_dealloc*/
  0,						/*tp_print*/
  0,						/*tp_getattr*/
  0,						/*tp_setattr*/
  0,						/*tp_compare*/
  disasmpy_result_repr,				/*tp_repr*/
  0,						/*tp_as_number*/
  0,						/*tp_as_sequence*/
  0,						/*tp_as_mapping*/
  0,						/*tp_hash */
  0,						/*tp_call*/
  disasmpy_result_str,				/*tp_str*/
  0,						/*tp_getattro*/
  0,						/*tp_setattro*/
  0,						/*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT,				/*tp_flags*/
  "GDB object, representing a disassembler result",	/* tp_doc */
  0,						/* tp_traverse */
  0,						/* tp_clear */
  0,						/* tp_richcompare */
  0,						/* tp_weaklistoffset */
  0,						/* tp_iter */
  0,						/* tp_iternext */
  0,						/* tp_methods */
  0,						/* tp_members */
  disasm_result_object_getset,			/* tp_getset */
  0,						/* tp_base */
  0,						/* tp_dict */
  0,						/* tp_descr_get */
  0,						/* tp_descr_set */
  0,						/* tp_dictoffset */
  disasmpy_result_init,				/* tp_init */
  0,						/* tp_alloc */
};

/* Describe the gdb.disassembler.DisassemblerPart type.  This type exists
   only as an abstract base-class for the various part sub-types.  The
   init method for this type throws an error.  As such we don't both to
   provide a tp_repr method for this parent class.  */

PyTypeObject disasm_part_object_type = {
  PyVarObject_HEAD_INIT (nullptr, 0)
  "gdb.disassembler.DisassemblerPart",		/*tp_name*/
  sizeof (PyObject),				/*tp_basicsize*/
  0,						/*tp_itemsize*/
  0,						/*tp_dealloc*/
  0,						/*tp_print*/
  0,						/*tp_getattr*/
  0,						/*tp_setattr*/
  0,						/*tp_compare*/
  0,						/*tp_repr*/
  0,						/*tp_as_number*/
  0,						/*tp_as_sequence*/
  0,						/*tp_as_mapping*/
  0,						/*tp_hash */
  0,						/*tp_call*/
  0,						/*tp_str*/
  0,						/*tp_getattro*/
  0,						/*tp_setattro*/
  0,						/*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT,				/*tp_flags*/
  "GDB object, representing part of a disassembled instruction",  /* tp_doc */
  0,						/* tp_traverse */
  0,						/* tp_clear */
  0,						/* tp_richcompare */
  0,						/* tp_weaklistoffset */
  0,						/* tp_iter */
  0,						/* tp_iternext */
  0,						/* tp_methods */
  0,						/* tp_members */
  0,						/* tp_getset */
  0,						/* tp_base */
  0,						/* tp_dict */
  0,						/* tp_descr_get */
  0,						/* tp_descr_set */
  0,						/* tp_dictoffset */
  disasmpy_part_init,				/* tp_init */
  0,						/* tp_alloc */
};

/* Describe the gdb.disassembler.DisassemblerTextPart type.  */

PyTypeObject disasm_text_part_object_type = {
  PyVarObject_HEAD_INIT (nullptr, 0)
  "gdb.disassembler.DisassemblerTextPart",	/*tp_name*/
  sizeof (disasm_text_part_object_type),	/*tp_basicsize*/
  0,						/*tp_itemsize*/
  0,						/*tp_dealloc*/
  0,						/*tp_print*/
  0,						/*tp_getattr*/
  0,						/*tp_setattr*/
  0,						/*tp_compare*/
  disasmpy_text_part_repr,			/*tp_repr*/
  0,						/*tp_as_number*/
  0,						/*tp_as_sequence*/
  0,						/*tp_as_mapping*/
  0,						/*tp_hash */
  0,						/*tp_call*/
  disasmpy_text_part_str,			/*tp_str*/
  0,						/*tp_getattro*/
  0,						/*tp_setattro*/
  0,						/*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT,				/*tp_flags*/
  "GDB object, representing a text part of an instruction",  /* tp_doc */
  0,						/* tp_traverse */
  0,						/* tp_clear */
  0,						/* tp_richcompare */
  0,						/* tp_weaklistoffset */
  0,						/* tp_iter */
  0,						/* tp_iternext */
  0,						/* tp_methods */
  0,						/* tp_members */
  disasmpy_text_part_getset,			/* tp_getset */
  &disasm_part_object_type,			/* tp_base */
  0,						/* tp_dict */
  0,						/* tp_descr_get */
  0,						/* tp_descr_set */
  0,						/* tp_dictoffset */
  0,						/* tp_init */
  0,						/* tp_alloc */
};

/* Describe the gdb.disassembler.DisassemblerAddressPart type.  */

PyTypeObject disasm_addr_part_object_type = {
  PyVarObject_HEAD_INIT (nullptr, 0)
  "gdb.disassembler.DisassemblerAddressPart",	/*tp_name*/
  sizeof (disasm_addr_part_object),		/*tp_basicsize*/
  0,						/*tp_itemsize*/
  0,						/*tp_dealloc*/
  0,						/*tp_print*/
  0,						/*tp_getattr*/
  0,						/*tp_setattr*/
  0,						/*tp_compare*/
  disasmpy_addr_part_repr,			/*tp_repr*/
  0,						/*tp_as_number*/
  0,						/*tp_as_sequence*/
  0,						/*tp_as_mapping*/
  0,						/*tp_hash */
  0,						/*tp_call*/
  disasmpy_addr_part_str,			/*tp_str*/
  0,						/*tp_getattro*/
  0,						/*tp_setattro*/
  0,						/*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT,				/*tp_flags*/
  "GDB object, representing an address part of an instruction",  /* tp_doc */
  0,						/* tp_traverse */
  0,						/* tp_clear */
  0,						/* tp_richcompare */
  0,						/* tp_weaklistoffset */
  0,						/* tp_iter */
  0,						/* tp_iternext */
  0,						/* tp_methods */
  0,						/* tp_members */
  disasmpy_addr_part_getset,						/* tp_getset */
  &disasm_part_object_type,			/* tp_base */
  0,						/* tp_dict */
  0,						/* tp_descr_get */
  0,						/* tp_descr_set */
  0,						/* tp_dictoffset */
  0,						/* tp_init */
  0,						/* tp_alloc */
};
