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

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

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)
    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))
    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;
}

/* 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),
			       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[] =
{
  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 */
};
