/* Python interface to instruction disassembly.

   Copyright (C) 2021-2023 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 "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
{
  PyObject_HEAD

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

extern PyTypeObject disasm_info_object_type
    CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("disasm_info_object");

/* 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
{
  PyObject_HEAD

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

extern PyTypeObject disasm_addr_part_object_type
    CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("disasm_addr_part_object");

/* 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
{
  PyObject_HEAD

  /* The string that is this part.  */
  std::string *string;

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

extern PyTypeObject disasm_text_part_object_type
    CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("disasm_text_part_object");

extern PyTypeObject disasm_part_object_type
    CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("PyObject");

/* 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
{
  PyObject_HEAD

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

extern PyTypeObject disasm_result_object_type
    CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("disasm_result_object");

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

  /* 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 gdb::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.  */
  gdb::optional<CORE_ADDR> m_memory_error_address;

  /* When the user calls the builtin_disassemble function, if they pass a
     memory source object then a pointer to the object is placed in here,
     otherwise, this field is nullptr.  */
  PyObject *m_memory_source;

  /* 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.  */
  gdb::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 behaviour.  */
  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>",
			       Py_TYPE (obj)->tp_name,
			       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))
    Py_RETURN_TRUE;

  Py_RETURN_FALSE;
}

/* 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, *memory_source_obj = nullptr;
  static const char *keywords[] = { "info", "memory_source", nullptr };
  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O!|O", keywords,
					&disasm_info_object_type, &info_obj,
					&memory_source_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, memory_source_obj);

  /* 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)
	    {
	      GDB_PY_HANDLE_EXCEPTION (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,
					&newstate))
    return nullptr;

  if (!PyBool_Check (newstate))
    {
      PyErr_SetString (PyExc_TypeError,
		       _("The value passed to `_set_enabled' must be a boolean."));
      return nullptr;
    }

  python_print_insn_enabled = PyObject_IsTrue (newstate);
  Py_RETURN_NONE;
}

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

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

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "L|L", 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);
}

/* 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 behaviour 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.  */
  LONGEST offset = (LONGEST) memaddr - (LONGEST) obj->address;

  /* Now call the DisassembleInfo.read_memory method.  This might have been
     overridden by the user.  */
  gdbpy_ref<> result_obj (PyObject_CallMethod ((PyObject *) obj,
					       "read_memory",
					       "KL", 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)
    {
      GDB_PY_HANDLE_EXCEPTION (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."),
		    Py_TYPE (self)->tp_name);
      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\">",
			       Py_TYPE (obj)->tp_name,
			       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,
					PyObject *memory_source)
  : gdb_disassemble_info (obj->gdbarch,
			  read_memory_func,
			  memory_error_func,
			  print_address_func,
			  fprintf_func,
			  fprintf_styled_func),
    m_disasm_info_object (obj),
    m_memory_source (memory_source)
{ /* 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_disasm_info_object
{
  /* Constructor.  */
  scoped_disasm_info_object (struct gdbarch *gdbarch, CORE_ADDR memaddr,
			     disassemble_info *info)
    : m_disasm_info (allocate_disasm_info_object ())
  {
    disasm_info_fill (m_disasm_info.get (), gdbarch, current_program_space,
		      memaddr, info, nullptr);
  }

  /* Upon destruction mark m_diasm_info as invalid.  */
  ~scoped_disasm_info_object ()
  {
    /* 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;
  }

  /* Return a pointer to the underlying disasm_info_object instance.  */
  disasm_info_object *
  get () const
  {
    return m_disasm_info.get ();
  }

private:

  /* Wrapper around the call to PyObject_New, this wrapper function can be
     called from the constructor initialization list, while PyObject_New, a
     macro, can't.  */
  static disasm_info_object *
  allocate_disasm_info_object ()
  {
    return (disasm_info_object *) PyObject_New (disasm_info_object,
						&disasm_info_object_type);
  }

  /* A reference to a gdb.disassembler.DisassembleInfo object.  When this
     containing instance goes out of scope this reference is released,
     however, the user might be holding other references to the
     DisassembleInfo object in Python code, so the underlying object might
     not be deleted.  */
  gdbpy_ref<disasm_info_object> m_disasm_info;
};

/* See python-internal.h.  */

gdb::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.  This
     object will be marked as invalid when we leave this scope.  */
  scoped_disasm_info_object scoped_disasm_info (gdbarch, memaddr, info);
  disasm_info_object *disasm_info = scoped_disasm_info.get ();

  /* Call into the registered disassembler to (possibly) perform the
     disassembly.  */
  PyObject *insn_disas_obj = (PyObject *) disasm_info;
  gdbpy_ref<> result (PyObject_CallFunctionObjArgs (hook.get (),
						    insn_disas_obj,
						    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 gdb::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 gdb::optional<int> (-1);
	}
      else
	{
	  gdbpy_print_stack ();
	  return gdb::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 (or a sub-class).  */
  if (!PyObject_IsInstance (result.get (),
			    (PyObject *) &disasm_result_object_type))
    {
      PyErr_SetString (PyExc_TypeError,
		       _("Result is not a DisassemblerResult."));
      gdbpy_print_stack ();
      return gdb::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 gdb::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 gdb::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 gdb::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_SetString (PyExc_RuntimeError,
		   _("Cannot create instances of DisassemblerPart."));
  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'>",
			       Py_TYPE (obj)->tp_name,
			       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'>",
			       Py_TYPE (obj)->tp_name,
			       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)
    {
      GDB_PY_HANDLE_EXCEPTION (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, MEMORY_SOURCE = None) -> None\n\
Disassemble using GDB's builtin disassembler.  INFO is an instance of\n\
gdb.disassembler.DisassembleInfo.  The MEMORY_SOURCE, if not None, should\n\
be an object with the read_memory method." },
  { "_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 CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
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;
  PyModule_AddObject(gdb_module, "disassembler", gdb_disassembler_module);

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

  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 (PyType_Ready (&disasm_info_object_type) < 0)
    return -1;

  if (gdb_pymodule_addobject (gdb_disassembler_module, "DisassembleInfo",
			      (PyObject *) &disasm_info_object_type) < 0)
    return -1;

  disasm_result_object_type.tp_new = PyType_GenericNew;
  if (PyType_Ready (&disasm_result_object_type) < 0)
    return -1;

  if (gdb_pymodule_addobject (gdb_disassembler_module, "DisassemblerResult",
			      (PyObject *) &disasm_result_object_type) < 0)
    return -1;

  disasm_part_object_type.tp_new = PyType_GenericNew;
  if (PyType_Ready (&disasm_part_object_type) < 0)
    return -1;

  if (gdb_pymodule_addobject (gdb_disassembler_module, "DisassemblerPart",
			      (PyObject *) &disasm_part_object_type) < 0)
    return -1;

  disasm_addr_part_object_type.tp_new = PyType_GenericNew;
  if (PyType_Ready (&disasm_addr_part_object_type) < 0)
    return -1;

  if (gdb_pymodule_addobject (gdb_disassembler_module,
			      "DisassemblerAddressPart",
			      (PyObject *) &disasm_addr_part_object_type) < 0)
    return -1;

  disasm_text_part_object_type.tp_new = PyType_GenericNew;
  if (PyType_Ready (&disasm_text_part_object_type) < 0)
    return -1;

  if (gdb_pymodule_addobject (gdb_disassembler_module,
			      "DisassemblerTextPart",
			      (PyObject *) &disasm_text_part_object_type) < 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 */
};
