/* 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"
#include "py-event.h"

/* A gdb.Corefile object.  */

struct corefile_object : public gdbpy_dict_wrapper
{
  /* 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;

  /* 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 : public PyObject
{
  /* 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;
};

static_assert (gdb::is_python_allocatable_v<corefile_mapped_file_object>);

extern PyTypeObject corefile_mapped_file_object_type;

/* A gdb.CorefileMappedFileRegion object.  */

struct corefile_mapped_file_region_object : public PyObject
{
  /* 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;
};

static_assert (gdb::is_python_allocatable_v<corefile_mapped_file_region_object>);

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 py_none ();

  PyObject *result = (PyObject *) cfpy_inferior_corefile_data_key.get (inf);
  if (result != nullptr)
    return gdbpy_ref<>::new_reference (result);

  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;
  if (!object->allocate_dict ())
    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;

  /* PyObject_New initializes the new object with a refcount of 1.  This counts
     for the reference we are keeping in the inferior corefile data.  */
  cfpy_inferior_corefile_data_key.set (inf, object.get ());

  return gdbpy_ref<>::new_reference (object.release ());
}

/* 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))
    return py_false ().release ();

  return py_true ().release ();
}

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

/* Emit a CorefileChangedEvent event, INF is the inferior in which the core
   file changed.  Return 0 on success, or a negative value on error.  */

static int
emit_corefile_changed_event (inferior *inf)
{
  /* If there are no listeners then we are done.  */
  if (evregpy_no_listeners_p (gdb_py_events.corefile_changed))
    return 0;

  gdbpy_ref<> event_obj
    = create_event_object (&corefile_changed_event_object_type);
  if (event_obj == nullptr)
    return -1;

  gdbpy_ref<inferior_object> inf_obj = inferior_to_inferior_object (inf);
  if (inf_obj == nullptr
      || evpy_add_attribute (event_obj.get (), "inferior",
			     inf_obj.get ()) < 0)
    return -1;

  return evpy_emit_event (event_obj.get (), gdb_py_events.corefile_changed);
}

/* Callback from gdb::observers::core_file_changed.  The core file for
   INF has been changed.  */

static void
cfpy_corefile_changed (inferior *inf)
{
  /* It's safe to do this even if Python is not initialized, but there
     should be nothing to clear in that case.  */
  cfpy_inferior_corefile_data_key.clear (inf);

  if (!gdb_python_initialized)
    return;

  gdbpy_enter enter_py;

  if (emit_corefile_changed_event (inf) < 0)
    gdbpy_print_stack ();
}

/* 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'>",
			       gdbpy_py_obj_tp_name (self).c_str (),
			       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)
    return py_true ().release ();
  else
    return py_false ().release ();
}



/* 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[] =
{
  gdbpy_dict_wrapper_cfg_dict_getter ("corefile"),
  { "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*/
  gdbpy_dict_wrapper_getsetattro,
  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 */
  0,				  /* 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 */
};
