/* Python interface to core files.

   Copyright (C) 2025-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 "progspace.h"
#include "observable.h"
#include "inferior.h"
#include "gdbcore.h"
#include "gdbsupport/rsp-low.h"

/* A gdb.Corefile object.  */

struct corefile_object
{
  PyObject_HEAD

  /* The inferior this core file is attached to.  This will be set to NULL
     when the inferior is deleted, or if a different core file is loaded
     for the inferior.  When this is NULL the gdb.Corefile object is
     considered invalid.*/
  struct inferior *inferior;

  /* Dictionary holding user-added attributes.  This is the __dict__
     attribute of the object.  This is an owning reference.  */
  PyObject *dict;

  /* A Tuple of gdb.CorefileMappedFile objects.  This tuple is only created
     the first time the user calls gdb.Corefile.mapped_files(), the result
     is cached here.  If this pointer is not NULL then this is an owning
     pointer (i.e. this owns a reference to the Tuple).  */
  PyObject *mapped_files;
};

extern PyTypeObject corefile_object_type;

/* A gdb.CorefileMapped object.  */

struct corefile_mapped_file_object
{
  PyObject_HEAD

  /* The name of a file that was mapped when the core file was created.
     This is a 'str' object.  */
  PyObject *filename;

  /* The build-id of a file that was mapped when the core file was
     created.  This is either a 'str' if the file had a build-id, or
     'None' if there was no build-id for this file.  */
  PyObject *build_id;

  /* A List of gdb.CorefileMappedFileRegion objects.  */
  PyObject *regions;

  /* True if this represents the main executable from which the core file
     was created.  */
  bool is_main_exec_p;
};

extern PyTypeObject corefile_mapped_file_object_type;

/* A gdb.CorefileMappedFileRegion object.  */

struct corefile_mapped_file_region_object
{
  PyObject_HEAD

  /* The start and end addresses for this mapping, these are addresses
     within the inferior's address space.  */
  CORE_ADDR start;
  CORE_ADDR end;

  /* The offset within the mapped file for this mapping.  */
  ULONGEST file_offset;
};

extern PyTypeObject corefile_mapped_file_region_object_type;

/* Clear the inferior pointer in a Corefile object OBJ when an inferior is
   deleted.  */

struct inferior_corefile_deleter
{
  void operator() (corefile_object *obj)
  {
    if (!gdb_python_initialized)
      return;

    gdbpy_enter enter_py;

    /* When OBJECT goes out of scope this will Py_DECREF on OBJ.  */
    gdbpy_ref<corefile_object> object (obj);

    /* Clearing the inferior pointer marks the gdb.Corefile as invalid.  */
    object->inferior = nullptr;
  }
};

/* Store a gdb.Corefile object in an inferior's registry.  */

static const registry<inferior>::key<corefile_object,
				     inferior_corefile_deleter>
     cfpy_inferior_corefile_data_key;

/* See python-internal.h.  */

gdbpy_ref<>
gdbpy_core_file_from_inferior (inferior *inf)
{
  gdb_assert (inf != nullptr);
  gdb_assert (inf->pspace != nullptr);

  if (get_inferior_core_bfd (inf) == nullptr)
    return gdbpy_ref<>::new_reference (Py_None);

  PyObject *result = (PyObject *) cfpy_inferior_corefile_data_key.get (inf);
  if (result == nullptr)
    {
      gdbpy_ref<corefile_object> object
	(PyObject_New (corefile_object, &corefile_object_type));
      if (object == nullptr)
	return nullptr;

      /* Ensure the 'inferior' field is set to NULL.  If the PyDict_New
	 call fails then the gdb.Corefile will be discarded and
	 cfpy_dealloc will be called, which requires that the 'inferior' be
	 set to NULL.  */
      object->inferior = nullptr;
      object->mapped_files = nullptr;
      object->dict = PyDict_New ();
      if (object->dict == nullptr)
	return nullptr;

      /* Now that the gdb.Corefile has been successfully initialised and we
	 know that it is going to be passed back to the user, move it out
	 of the invalid state by setting the 'inferior' field to a non NULL
	 value.  */
      object->inferior = inf;
      cfpy_inferior_corefile_data_key.set (inf, object.get ());
      result = (PyObject *) object.release ();
    }

  return gdbpy_ref<>::new_reference (result);
}

/* Return true if OBJ is valid.  */

static bool
cfpy_corefile_object_is_valid (const corefile_object *obj)
{
  if (obj->inferior == nullptr)
    return false;

  return get_inferior_core_bfd (obj->inferior) != nullptr;
}

/* Require that COREFILE_OBJ be a valid core file.  A valid core file
   object has a valid program space, and the program space has a core file
   loaded into it.  */
#define CFPY_REQUIRE_VALID(corefile_obj)				\
  do {									\
    if (!cfpy_corefile_object_is_valid (corefile_obj))			\
      {									\
	PyErr_SetString (PyExc_RuntimeError,				\
			 _("Corefile no longer exists."));		\
	return nullptr;							\
      }									\
  } while (0)

/* Read the gdb.Corefile.filename attribute.  */

static PyObject *
cfpy_get_filename (PyObject *self, void *closure)
{
  corefile_object *obj = (corefile_object *) self;

  CFPY_REQUIRE_VALID (obj);

  /* If the program space's core file had been cleared, then this Corefile
     object would have been invalidated.  */
  bfd *abfd = get_inferior_core_bfd (obj->inferior);
  gdb_assert (abfd != nullptr);

  return host_string_to_python_string (bfd_get_filename (abfd)).release ();
}

/* Implementation of gdb.Corefile.is_valid (self) -> Boolean.
   Returns True if this core file object is associated with a program space
   that still exists, an the program space still has a core file loaded.  */

static PyObject *
cfpy_is_valid (PyObject *self, PyObject *args)
{
  corefile_object *obj = (corefile_object *) self;

  if (!cfpy_corefile_object_is_valid (obj))
    Py_RETURN_FALSE;

  Py_RETURN_TRUE;
}

/* Implement gdb.Corefile.mapped_files ().  Return a List of
   gdb.CorefileMappedFile objects.  The list is created the first time
   this method is called, and then cached within the gdb.Corefile object,
   future calls just return a reference to the same list.  */

static PyObject *
cfpy_mapped_files (PyObject *self, PyObject *args)
{
  corefile_object *obj = (corefile_object *) self;

  CFPY_REQUIRE_VALID (obj);

  /* If we have already created the List then just return another reference
     to the existing list.  */
  if (obj->mapped_files != nullptr)
    {
      Py_INCREF (obj->mapped_files);
      return obj->mapped_files;
    }

  /* Get all the mapping data from GDB.  */
  std::vector<core_mapped_file> mapped_files;
  try
    {
      mapped_files
	= gdb_read_core_file_mappings (obj->inferior->arch (),
				       get_inferior_core_bfd (obj->inferior));
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  /* Create a new list to hold the results.  */
  gdbpy_ref<> tuple (PyTuple_New (mapped_files.size ()));
  if (tuple == nullptr)
    return nullptr;

  /* Create each gdb.CorefileMappedFile object.  */
  Py_ssize_t tuple_idx = 0;
  for (const core_mapped_file &file : mapped_files)
    {
      /* The filename 'str' object.  */
      gdbpy_ref<> filename
	= host_string_to_python_string (file.filename.c_str ());
      if (filename == nullptr)
	return nullptr;

      /* The build-id object.  Either a 'str' or 'None'.  */
      gdbpy_ref<> build_id;
      if (file.build_id != nullptr)
	{
	  std::string hex_form = bin2hex (file.build_id->data,
					  file.build_id->size);

	  build_id
	    = host_string_to_python_string (hex_form.c_str ());
	  if (build_id == nullptr)
	    return nullptr;
	}
      else
	build_id = gdbpy_ref<>::new_reference (Py_None);

      /* List to hold all the gdb.CorefileMappedFileRegion objects.  */
      gdbpy_ref<> regions (PyTuple_New (file.regions.size ()));
      if (regions == nullptr)
	return nullptr;

      /* Create all the gdb.CorefileMappedFileRegion objects.  */
      Py_ssize_t regions_idx = 0;
      for (const core_mapped_file::region &r : file.regions)
	{
	  /* Actually create the object.  */
	  gdbpy_ref<corefile_mapped_file_region_object> region_obj
	    (PyObject_New (corefile_mapped_file_region_object,
			   &corefile_mapped_file_region_object_type));
	  if (region_obj == nullptr)
	    return nullptr;

	  /* Initialise the object.  */
	  region_obj->start = r.start;
	  region_obj->end = r.end;
	  region_obj->file_offset = r.file_ofs;

	  /* Add to the gdb.CorefileMappedFileRegion list.  */
	  if (PyTuple_SetItem (regions.get (), regions_idx++,
			       (PyObject *) region_obj.release ()) < 0)
	    return nullptr;
	}

      /* Actually create the gdb.CorefileMappedFile object.  */
      gdbpy_ref<corefile_mapped_file_object> entry
	(PyObject_New (corefile_mapped_file_object,
		       &corefile_mapped_file_object_type));
      if (entry == nullptr)
	return nullptr;

      /* Initialise the object.  */
      entry->filename = filename.release ();
      entry->build_id = build_id.release ();
      entry->regions = regions.release ();
      entry->is_main_exec_p = file.is_main_exec;

      /* Add to the gdb.CorefileMappedFile list.  */
      if (PyTuple_SetItem (tuple.get (), tuple_idx++,
			   (PyObject *) entry.release ()) < 0)
	return nullptr;
    }

  /* No errors.  Move the reference currently in LIST into the Corefile
     object itself.  Then create a new reference and hand this back to the
     user.  */
  obj->mapped_files = tuple.release ();
  Py_INCREF (obj->mapped_files);
  return obj->mapped_files;
}

/* Callback from gdb::observers::core_file_changed.  The core file in
   PSPACE has been changed.  */

static void
cfpy_corefile_changed (inferior *inf)
{
  cfpy_inferior_corefile_data_key.clear (inf);
}

/* Called when a gdb.Corefile is destroyed.  */

static void
cfpy_dealloc (PyObject *obj)
{
  corefile_object *corefile = (corefile_object *) obj;

  /* Every gdb.Corefile is cached in an inferior's registry.  The only way
     for a gdb.Corefile to be deallocated is to remove the object reference
     from the registry (and dec its ref count), but before we do that, we
     set the object's inferior pointer to NULL.  */
  gdb_assert (corefile->inferior == nullptr);

  Py_XDECREF (corefile->dict);
  Py_XDECREF (corefile->mapped_files);

  Py_TYPE (obj)->tp_free (obj);
}

/* __repr__ implementation for gdb.Corefile.  */

static PyObject *
cfpy_repr (PyObject *self)
{
  corefile_object *obj = (corefile_object *) self;

  if (!cfpy_corefile_object_is_valid (obj))
    return gdb_py_invalid_object_repr (self);

  bfd *core_bfd = get_inferior_core_bfd (obj->inferior);
  gdb_assert (core_bfd != nullptr);
  return PyUnicode_FromFormat ("<%s inferior=%d filename='%s'>",
			       Py_TYPE (self)->tp_name,
			       obj->inferior->num,
			       bfd_get_filename (core_bfd));
}



/* Called when a gdb.CorefileMappedFile is destroyed.  */

static void
cfmfpy_dealloc (PyObject *obj)
{
  corefile_mapped_file_object *mapped_file
    = (corefile_mapped_file_object *) obj;

  Py_XDECREF (mapped_file->filename);
  Py_XDECREF (mapped_file->build_id);
  Py_XDECREF (mapped_file->regions);

  Py_TYPE (obj)->tp_free (obj);
}

/* Read the gdb.CorefileMappedFile.filename attribute.  */

static PyObject *
cfmfpy_get_filename (PyObject *self, void *closure)
{
  corefile_mapped_file_object *obj
    = (corefile_mapped_file_object *) self;

  gdb_assert (obj->filename != nullptr);

  Py_INCREF (obj->filename);
  return obj->filename;
}

/* Read the gdb.CorefileMappedFile.build_id attribute.  */

static PyObject *
cfmfpy_get_build_id (PyObject *self, void *closure)
{
  corefile_mapped_file_object *obj
    = (corefile_mapped_file_object *) self;

  gdb_assert (obj->build_id != nullptr);

  Py_INCREF (obj->build_id);
  return obj->build_id;
}

/* Read the gdb.CorefileMappedFile.regions attribute.  */

static PyObject *
cfmfpy_get_regions (PyObject *self, void *closure)
{
  corefile_mapped_file_object *obj
    = (corefile_mapped_file_object *) self;

  gdb_assert (obj->regions != nullptr);

  Py_INCREF (obj->regions);
  return obj->regions;
}

/* Read the gdb.CorefileMappedFile.is_main_executable attribute.  */

static PyObject *
cfmf_is_main_exec (PyObject *self, void *closure)
{
  corefile_mapped_file_object *obj
    = (corefile_mapped_file_object *) self;

  if (obj->is_main_exec_p)
    Py_RETURN_TRUE;
  else
    Py_RETURN_FALSE;
}



/* Read the gdb.CorefileMappedFileRegion.start attribute.  */

static PyObject *
cfmfrpy_get_start (PyObject *self, void *closure)
{
  corefile_mapped_file_region_object *obj
    = (corefile_mapped_file_region_object *) self;

  return gdb_py_object_from_ulongest (obj->start).release ();
}

/* Read the gdb.CorefileMappedFileRegion.end attribute.  */

static PyObject *
cfmfrpy_get_end (PyObject *self, void *closure)
{
  corefile_mapped_file_region_object *obj
    = (corefile_mapped_file_region_object *) self;

  return gdb_py_object_from_ulongest (obj->end).release ();
}

/* Read the gdb.CorefileMappedFileRegion.file_offset attribute.  */

static PyObject *
cfmfrpy_get_file_offset (PyObject *self, void *closure)
{
  corefile_mapped_file_region_object *obj
    = (corefile_mapped_file_region_object *) self;

  return gdb_py_object_from_ulongest (obj->file_offset).release ();
}



static int
gdbpy_initialize_corefile ()
{
  gdb::observers::core_file_changed.attach (cfpy_corefile_changed,
					    "py-corefile");

  if (gdbpy_type_ready (&corefile_object_type) < 0)
    return -1;

  if (gdbpy_type_ready (&corefile_mapped_file_object_type) < 0)
    return -1;

  if (gdbpy_type_ready (&corefile_mapped_file_region_object_type) < 0)
    return -1;

  return 0;
}

GDBPY_INITIALIZE_FILE (gdbpy_initialize_corefile);



static gdb_PyGetSetDef corefile_getset[] =
{
  { "__dict__", gdb_py_generic_dict, nullptr,
    "The __dict__ for the gdb.Corefile.", &corefile_object_type },
  { "filename", cfpy_get_filename, nullptr,
    "The filename of a valid Corefile object.", nullptr },
  { nullptr }
};

static PyMethodDef corefile_object_methods[] =
{
  { "is_valid", cfpy_is_valid, METH_NOARGS,
    "is_valid () -> Boolean.\n\
Return true if this Corefile is valid, false if not." },
  { "mapped_files", cfpy_mapped_files, METH_NOARGS,
    "mapped_files () -> List of mapping tuples.\n\
Return a list of tuples.  Each tuple represents a mapping from the\
core file." },
  { nullptr }
};

PyTypeObject corefile_object_type =
{
  PyVarObject_HEAD_INIT (nullptr, 0)
  "gdb.Corefile",		  /*tp_name*/
  sizeof (corefile_object),	  /*tp_basicsize*/
  0,				  /*tp_itemsize*/
  cfpy_dealloc,			  /*tp_dealloc*/
  0,				  /*tp_print*/
  0,				  /*tp_getattr*/
  0,				  /*tp_setattr*/
  0,				  /*tp_compare*/
  cfpy_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,		  /*tp_flags*/
  "GDB corefile object",	  /* tp_doc */
  0,				  /* tp_traverse */
  0,				  /* tp_clear */
  0,				  /* tp_richcompare */
  0,				  /* tp_weaklistoffset */
  0,				  /* tp_iter */
  0,				  /* tp_iternext */
  corefile_object_methods,	  /* tp_methods */
  0,				  /* tp_members */
  corefile_getset,		  /* tp_getset */
  0,				  /* tp_base */
  0,				  /* tp_dict */
  0,				  /* tp_descr_get */
  0,				  /* tp_descr_set */
  offsetof (corefile_object, dict), /* tp_dictoffset */
  0,				  /* tp_init */
  0,				  /* tp_alloc */
  0,				  /* tp_new */
};

static gdb_PyGetSetDef corefile_mapped_file_object_getset[] =
{
  { "filename", cfmfpy_get_filename, nullptr,
    "The filename of a CorefileMappedFile object.", nullptr },
  { "build_id", cfmfpy_get_build_id, nullptr,
    "The build-id of a CorefileMappedFile object or None.", nullptr },
  { "regions", cfmfpy_get_regions, nullptr,
    "The list of regions from a CorefileMappedFile object.", nullptr },
  { "is_main_executable", cfmf_is_main_exec, nullptr,
    "True for the main executable mapping, otherwise False.", nullptr },
  { nullptr }
};

PyTypeObject corefile_mapped_file_object_type =
{
  PyVarObject_HEAD_INIT (NULL, 0)
  "gdb.CorefileMappedFile",	  /*tp_name*/
  sizeof (corefile_mapped_file_object),	/*tp_basicsize*/
  0,				  /*tp_itemsize*/
  cfmfpy_dealloc,		  /*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 corefile mapped file object",	/* 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 */
  corefile_mapped_file_object_getset,	/* 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 */
  0,				  /* tp_new */
};

static gdb_PyGetSetDef corefile_mapped_file_region_object_getset[] =
{
  { "start", cfmfrpy_get_start, nullptr,
    "The start address of a CorefileMappedFileRegion object.", nullptr },
  { "end", cfmfrpy_get_end, nullptr,
    "The end address of a CorefileMappedFileRegion object.", nullptr },
  { "file_offset", cfmfrpy_get_file_offset, nullptr,
    "The file offset of a CorefileMappedFileRegion object.", nullptr },
  { nullptr }
};

PyTypeObject corefile_mapped_file_region_object_type =
{
  PyVarObject_HEAD_INIT (NULL, 0)
  "gdb.CorefileMappedFileRegion",  /*tp_name*/
  sizeof (corefile_mapped_file_region_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 corefile mapped file region object",	/* 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 */
  corefile_mapped_file_region_object_getset,	/* 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 */
  0,				  /* tp_new */
};
