/* Python interface to architecture

   Copyright (C) 2013-2022 Free Software Foundation, Inc.

   This file is part of GDB.

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

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

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

#include "defs.h"
#include "gdbarch.h"
#include "arch-utils.h"
#include "disasm.h"
#include "python-internal.h"

struct arch_object {
  PyObject_HEAD
  struct gdbarch *gdbarch;
};

static struct gdbarch_data *arch_object_data = NULL;

/* Require a valid Architecture.  */
#define ARCHPY_REQUIRE_VALID(arch_obj, arch)			\
  do {								\
    arch = arch_object_to_gdbarch (arch_obj);			\
    if (arch == NULL)						\
      {								\
	PyErr_SetString (PyExc_RuntimeError,			\
			 _("Architecture is invalid."));	\
	return NULL;						\
      }								\
  } while (0)

extern PyTypeObject arch_object_type
    CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("arch_object");

/* Associates an arch_object with GDBARCH as gdbarch_data via the gdbarch
   post init registration mechanism (gdbarch_data_register_post_init).  */

static void *
arch_object_data_init (struct gdbarch *gdbarch)
{
  arch_object *arch_obj = PyObject_New (arch_object, &arch_object_type);

  if (arch_obj == NULL)
    return NULL;

  arch_obj->gdbarch = gdbarch;

  return (void *) arch_obj;
}

/* Returns the struct gdbarch value corresponding to the given Python
   architecture object OBJ, which must be a gdb.Architecture object.  */

struct gdbarch *
arch_object_to_gdbarch (PyObject *obj)
{
  gdb_assert (gdbpy_is_architecture (obj));

  arch_object *py_arch = (arch_object *) obj;
  return py_arch->gdbarch;
}

/* See python-internal.h.  */

bool
gdbpy_is_architecture (PyObject *obj)
{
  return PyObject_TypeCheck (obj, &arch_object_type);
}

/* Returns the Python architecture object corresponding to GDBARCH.
   Returns a new reference to the arch_object associated as data with
   GDBARCH.  */

PyObject *
gdbarch_to_arch_object (struct gdbarch *gdbarch)
{
  PyObject *new_ref = (PyObject *) gdbarch_data (gdbarch, arch_object_data);

  /* new_ref could be NULL if registration of arch_object with GDBARCH failed
     in arch_object_data_init.  */
  Py_XINCREF (new_ref);

  return new_ref;
}

/* Implementation of gdb.Architecture.name (self) -> String.
   Returns the name of the architecture as a string value.  */

static PyObject *
archpy_name (PyObject *self, PyObject *args)
{
  struct gdbarch *gdbarch = NULL;
  const char *name;

  ARCHPY_REQUIRE_VALID (self, gdbarch);

  name = (gdbarch_bfd_arch_info (gdbarch))->printable_name;
  return PyUnicode_FromString (name);
}

/* Implementation of
   gdb.Architecture.disassemble (self, start_pc [, end_pc [,count]]) -> List.
   Returns a list of instructions in a memory address range.  Each instruction
   in the list is a Python dict object.
*/

static PyObject *
archpy_disassemble (PyObject *self, PyObject *args, PyObject *kw)
{
  static const char *keywords[] = { "start_pc", "end_pc", "count", NULL };
  CORE_ADDR start = 0, end = 0;
  CORE_ADDR pc;
  long count = 0, i;
  PyObject *start_obj = nullptr, *end_obj = nullptr, *count_obj = nullptr;
  struct gdbarch *gdbarch = NULL;

  ARCHPY_REQUIRE_VALID (self, gdbarch);

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "O|OO",
					keywords, &start_obj, &end_obj,
					&count_obj))
    return NULL;

  if (get_addr_from_python (start_obj, &start) < 0)
    return nullptr;

  if (end_obj != nullptr)
    {
      if (get_addr_from_python (end_obj, &end) < 0)
	return nullptr;

      if (end < start)
	{
	  PyErr_SetString (PyExc_ValueError,
			   _("Argument 'end_pc' should be greater than or "
			     "equal to the argument 'start_pc'."));

	  return NULL;
	}
    }
  if (count_obj)
    {
      count = PyLong_AsLong (count_obj);
      if (PyErr_Occurred () || count < 0)
	{
	  PyErr_SetString (PyExc_TypeError,
			   _("Argument 'count' should be an non-negative "
			     "integer."));

	  return NULL;
	}
    }

  gdbpy_ref<> result_list (PyList_New (0));
  if (result_list == NULL)
    return NULL;

  for (pc = start, i = 0;
       /* All args are specified.  */
       (end_obj && count_obj && pc <= end && i < count)
       /* end_pc is specified, but no count.  */
       || (end_obj && count_obj == NULL && pc <= end)
       /* end_pc is not specified, but a count is.  */
       || (end_obj == NULL && count_obj && i < count)
       /* Both end_pc and count are not specified.  */
       || (end_obj == NULL && count_obj == NULL && pc == start);)
    {
      int insn_len = 0;
      gdbpy_ref<> insn_dict (PyDict_New ());

      if (insn_dict == NULL)
	return NULL;
      if (PyList_Append (result_list.get (), insn_dict.get ()))
	return NULL;  /* PyList_Append Sets the exception.  */

      string_file stb;

      try
	{
	  insn_len = gdb_print_insn (gdbarch, pc, &stb, NULL);
	}
      catch (const gdb_exception &except)
	{
	  gdbpy_convert_exception (except);
	  return NULL;
	}

      gdbpy_ref<> pc_obj = gdb_py_object_from_ulongest (pc);
      if (pc_obj == nullptr)
	return nullptr;

      gdbpy_ref<> asm_obj
	(PyUnicode_FromString (!stb.empty () ? stb.c_str () : "<unknown>"));
      if (asm_obj == nullptr)
	return nullptr;

      gdbpy_ref<> len_obj = gdb_py_object_from_longest (insn_len);
      if (len_obj == nullptr)
	return nullptr;

      if (PyDict_SetItemString (insn_dict.get (), "addr", pc_obj.get ())
	  || PyDict_SetItemString (insn_dict.get (), "asm", asm_obj.get ())
	  || PyDict_SetItemString (insn_dict.get (), "length", len_obj.get ()))
	return NULL;

      pc += insn_len;
      i++;
    }

  return result_list.release ();
}

/* Implementation of gdb.Architecture.registers (self, reggroup) -> Iterator.
   Returns an iterator over register descriptors for registers in GROUP
   within the architecture SELF.  */

static PyObject *
archpy_registers (PyObject *self, PyObject *args, PyObject *kw)
{
  static const char *keywords[] = { "reggroup", NULL };
  struct gdbarch *gdbarch = NULL;
  const char *group_name = NULL;

  /* Parse method arguments.  */
  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "|s", keywords,
					&group_name))
    return NULL;

  /* Extract the gdbarch from the self object.  */
  ARCHPY_REQUIRE_VALID (self, gdbarch);

  return gdbpy_new_register_descriptor_iterator (gdbarch, group_name);
}

/* Implementation of gdb.Architecture.register_groups (self) -> Iterator.
   Returns an iterator that will give up all valid register groups in the
   architecture SELF.  */

static PyObject *
archpy_register_groups (PyObject *self, PyObject *args)
{
  struct gdbarch *gdbarch = NULL;

  /* Extract the gdbarch from the self object.  */
  ARCHPY_REQUIRE_VALID (self, gdbarch);
  return gdbpy_new_reggroup_iterator (gdbarch);
}

/* Implementation of gdb.integer_type.  */
static PyObject *
archpy_integer_type (PyObject *self, PyObject *args, PyObject *kw)
{
  static const char *keywords[] = { "size", "signed", NULL };
  int size;
  PyObject *is_signed_obj = nullptr;

  if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "i|O", keywords,
					&size, &is_signed_obj))
    return nullptr;

  /* Assume signed by default.  */
  bool is_signed = (is_signed_obj == nullptr
		    || PyObject_IsTrue (is_signed_obj));

  struct gdbarch *gdbarch;
  ARCHPY_REQUIRE_VALID (self, gdbarch);

  const struct builtin_type *builtins = builtin_type (gdbarch);
  struct type *type = nullptr;
  switch (size)
    {
    case 0:
      type = builtins->builtin_int0;
      break;
    case 8:
      type = is_signed ? builtins->builtin_int8 : builtins->builtin_uint8;
      break;
    case 16:
      type = is_signed ? builtins->builtin_int16 : builtins->builtin_uint16;
      break;
    case 24:
      type = is_signed ? builtins->builtin_int24 : builtins->builtin_uint24;
      break;
    case 32:
      type = is_signed ? builtins->builtin_int32 : builtins->builtin_uint32;
      break;
    case 64:
      type = is_signed ? builtins->builtin_int64 : builtins->builtin_uint64;
      break;
    case 128:
      type = is_signed ? builtins->builtin_int128 : builtins->builtin_uint128;
      break;

    default:
      PyErr_SetString (PyExc_ValueError,
		       _("no integer type of that size is available"));
      return nullptr;
    }

  return type_to_type_object (type);
}

/* Implementation of gdb.architecture_names().  Return a list of all the
   BFD architecture names that GDB understands.  */

PyObject *
gdbpy_all_architecture_names (PyObject *self, PyObject *args)
{
  gdbpy_ref<> list (PyList_New (0));
  if (list == nullptr)
    return nullptr;

  std::vector<const char *> name_list = gdbarch_printable_names ();
  for (const char *name : name_list)
    {
      gdbpy_ref <> py_name (PyUnicode_FromString (name));
      if (py_name == nullptr)
	return nullptr;
      if (PyList_Append (list.get (), py_name.get ()) < 0)
	return nullptr;
    }

 return list.release ();
}

void _initialize_py_arch ();
void
_initialize_py_arch ()
{
  arch_object_data = gdbarch_data_register_post_init (arch_object_data_init);
}

/* Initializes the Architecture class in the gdb module.  */

int
gdbpy_initialize_arch (void)
{
  arch_object_type.tp_new = PyType_GenericNew;
  if (PyType_Ready (&arch_object_type) < 0)
    return -1;

  return gdb_pymodule_addobject (gdb_module, "Architecture",
				 (PyObject *) &arch_object_type);
}

static PyMethodDef arch_object_methods [] = {
  { "name", archpy_name, METH_NOARGS,
    "name () -> String.\n\
Return the name of the architecture as a string value." },
  { "disassemble", (PyCFunction) archpy_disassemble,
    METH_VARARGS | METH_KEYWORDS,
    "disassemble (start_pc [, end_pc [, count]]) -> List.\n\
Return a list of at most COUNT disassembled instructions from START_PC to\n\
END_PC." },
  { "integer_type", (PyCFunction) archpy_integer_type,
    METH_VARARGS | METH_KEYWORDS,
    "integer_type (size [, signed]) -> type\n\
Return an integer Type corresponding to the given bitsize and signed-ness.\n\
If not specified, the type defaults to signed." },
  { "registers", (PyCFunction) archpy_registers,
    METH_VARARGS | METH_KEYWORDS,
    "registers ([ group-name ]) -> Iterator.\n\
Return an iterator of register descriptors for the registers in register\n\
group GROUP-NAME." },
  { "register_groups", archpy_register_groups,
    METH_NOARGS,
    "register_groups () -> Iterator.\n\
Return an iterator over all of the register groups in this architecture." },
  {NULL}  /* Sentinel */
};

PyTypeObject arch_object_type = {
  PyVarObject_HEAD_INIT (NULL, 0)
  "gdb.Architecture",                 /* tp_name */
  sizeof (arch_object),               /* 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 architecture object",          /* tp_doc */
  0,                                  /* tp_traverse */
  0,                                  /* tp_clear */
  0,                                  /* tp_richcompare */
  0,                                  /* tp_weaklistoffset */
  0,                                  /* tp_iter */
  0,                                  /* tp_iternext */
  arch_object_methods,                /* 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 */
  0,                                  /* tp_init */
  0,                                  /* tp_alloc */
};
