/* Python interface to program spaces.

   Copyright (C) 2010-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 "charset.h"
#include "progspace.h"
#include "objfiles.h"
#include "language.h"
#include "arch-utils.h"
#include "solib.h"
#include "block.h"
#include "py-event.h"
#include "observable.h"
#include "inferior.h"

struct pspace_object : public gdbpy_dict_wrapper
{
  /* The corresponding pspace.  */
  struct program_space *pspace;

  /* The pretty-printer list of functions.  */
  PyObject *printers;

  /* The frame filter list of functions.  */
  PyObject *frame_filters;

  /* The frame unwinder list.  */
  PyObject *frame_unwinders;

  /* The type-printer list.  */
  PyObject *type_printers;

  /* The debug method list.  */
  PyObject *xmethods;

  /* The missing file handler list.  */
  PyObject *missing_file_handlers;
};

extern PyTypeObject pspace_object_type;

/* Clear the PSPACE pointer in a Pspace object and remove the reference.  */
struct pspace_deleter
{
  void operator() (pspace_object *obj)
  {
    /* This is a fiction, but we're in a nasty spot: The pspace is in the
       process of being deleted, we can't rely on anything in it.  Plus
       this is one time when the current program space and current inferior
       are not in sync: All inferiors that use PSPACE may no longer exist.
       We don't need to do much here, and since "there is always an inferior"
       using the current inferior's arch suffices.
       Note: We cannot call get_current_arch because it may try to access
       the target, which may involve accessing data in the pspace currently
       being deleted.  */
    gdbarch *arch = current_inferior ()->arch ();

    gdbpy_enter enter_py (arch);
    gdbpy_ref<pspace_object> object (obj);
    object->pspace = NULL;
  }
};

static const registry<program_space>::key<pspace_object, pspace_deleter>
     pspy_pspace_data_key;

/* Require that PSPACE_OBJ be a valid program space ID.  */
#define PSPY_REQUIRE_VALID(pspace_obj)				\
  do {								\
    if (pspace_obj->pspace == nullptr)				\
      {								\
	PyErr_SetString (PyExc_RuntimeError,			\
			 _("Program space no longer exists."));	\
	return NULL;						\
      }								\
  } while (0)

/* An Objfile method which returns the objfile's file name, or None.  */

static PyObject *
pspy_get_filename (PyObject *self, void *closure)
{
  pspace_object *obj = (pspace_object *) self;

  if (obj->pspace)
    {
      struct objfile *objfile = obj->pspace->symfile_object_file;

      if (objfile)
	return (host_string_to_python_string (objfile_name (objfile))
		.release ());
    }
  Py_RETURN_NONE;
}

/* Implement the gdb.Progspace.symbol_file attribute.  Return the
   gdb.Objfile corresponding to the currently loaded symbol-file, or None
   if no symbol-file is loaded.  If the Progspace is invalid then raise an
   exception.  */

static PyObject *
pspy_get_symbol_file (PyObject *self, void *closure)
{
  pspace_object *obj = (pspace_object *) self;

  PSPY_REQUIRE_VALID (obj);

  struct objfile *objfile = obj->pspace->symfile_object_file;

  if (objfile != nullptr)
    return objfile_to_objfile_object (objfile).release ();

  Py_RETURN_NONE;
}

/* Implement the gdb.Progspace.executable_filename attribute.  Return a
   string containing the name of the current executable, or None if no
   executable is currently set.  If the Progspace is invalid then raise an
   exception.  */

static PyObject *
pspy_get_exec_file (PyObject *self, void *closure)
{
  pspace_object *obj = (pspace_object *) self;

  PSPY_REQUIRE_VALID (obj);

  const char *filename = obj->pspace->exec_filename ();
  if (filename != nullptr)
    return host_string_to_python_string (filename).release ();

  Py_RETURN_NONE;
}

static void
pspy_dealloc (PyObject *self)
{
  pspace_object *ps_self = (pspace_object *) self;

  Py_XDECREF (ps_self->dict);
  Py_XDECREF (ps_self->printers);
  Py_XDECREF (ps_self->frame_filters);
  Py_XDECREF (ps_self->frame_unwinders);
  Py_XDECREF (ps_self->type_printers);
  Py_XDECREF (ps_self->xmethods);
  Py_XDECREF (ps_self->missing_file_handlers);
  Py_TYPE (self)->tp_free (self);
}

/* Initialize a pspace_object.
   The result is a boolean indicating success.  */

static int
pspy_initialize (pspace_object *self)
{
  self->pspace = NULL;

  self->dict = PyDict_New ();
  if (self->dict == NULL)
    return 0;

  self->printers = PyList_New (0);
  if (self->printers == NULL)
    return 0;

  self->frame_filters = PyDict_New ();
  if (self->frame_filters == NULL)
    return 0;

  self->frame_unwinders = PyList_New (0);
  if (self->frame_unwinders == NULL)
    return 0;

  self->type_printers = PyList_New (0);
  if (self->type_printers == NULL)
    return 0;

  self->xmethods = PyList_New (0);
  if (self->xmethods == NULL)
    return 0;

  self->missing_file_handlers = PyList_New (0);
  if (self->missing_file_handlers == nullptr)
    return 0;

  return 1;
}

PyObject *
pspy_get_printers (PyObject *o, void *ignore)
{
  pspace_object *self = (pspace_object *) o;

  Py_INCREF (self->printers);
  return self->printers;
}

static int
pspy_set_printers (PyObject *o, PyObject *value, void *ignore)
{
  pspace_object *self = (pspace_object *) o;

  if (! value)
    {
      PyErr_SetString (PyExc_TypeError,
		       "cannot delete the pretty_printers attribute");
      return -1;
    }

  if (! PyList_Check (value))
    {
      PyErr_SetString (PyExc_TypeError,
		       "the pretty_printers attribute must be a list");
      return -1;
    }

  /* Take care in case the LHS and RHS are related somehow.  */
  gdbpy_ref<> tmp (self->printers);
  Py_INCREF (value);
  self->printers = value;

  return 0;
}

/* Return the Python dictionary attribute containing frame filters for
   this program space.  */
PyObject *
pspy_get_frame_filters (PyObject *o, void *ignore)
{
  pspace_object *self = (pspace_object *) o;

  Py_INCREF (self->frame_filters);
  return self->frame_filters;
}

/* Set this object file's frame filters dictionary to FILTERS.  */
static int
pspy_set_frame_filters (PyObject *o, PyObject *frame, void *ignore)
{
  pspace_object *self = (pspace_object *) o;

  if (! frame)
    {
      PyErr_SetString (PyExc_TypeError,
		       "cannot delete the frame filter attribute");
      return -1;
    }

  if (! PyDict_Check (frame))
    {
      PyErr_SetString (PyExc_TypeError,
		       "the frame filter attribute must be a dictionary");
      return -1;
    }

  /* Take care in case the LHS and RHS are related somehow.  */
  gdbpy_ref<> tmp (self->frame_filters);
  Py_INCREF (frame);
  self->frame_filters = frame;

  return 0;
}

/* Return the list of the frame unwinders for this program space.  */

PyObject *
pspy_get_frame_unwinders (PyObject *o, void *ignore)
{
  pspace_object *self = (pspace_object *) o;

  Py_INCREF (self->frame_unwinders);
  return self->frame_unwinders;
}

/* Set this program space's list of the unwinders to UNWINDERS.  */

static int
pspy_set_frame_unwinders (PyObject *o, PyObject *unwinders, void *ignore)
{
  pspace_object *self = (pspace_object *) o;

  if (!unwinders)
    {
      PyErr_SetString (PyExc_TypeError,
		       "cannot delete the frame unwinders list");
      return -1;
    }

  if (!PyList_Check (unwinders))
    {
      PyErr_SetString (PyExc_TypeError,
		       "the frame unwinders attribute must be a list");
      return -1;
    }

  /* Take care in case the LHS and RHS are related somehow.  */
  gdbpy_ref<> tmp (self->frame_unwinders);
  Py_INCREF (unwinders);
  self->frame_unwinders = unwinders;

  return 0;
}

/* Get the 'type_printers' attribute.  */

static PyObject *
pspy_get_type_printers (PyObject *o, void *ignore)
{
  pspace_object *self = (pspace_object *) o;

  Py_INCREF (self->type_printers);
  return self->type_printers;
}

/* Get the 'xmethods' attribute.  */

PyObject *
pspy_get_xmethods (PyObject *o, void *ignore)
{
  pspace_object *self = (pspace_object *) o;

  Py_INCREF (self->xmethods);
  return self->xmethods;
}

/* Return the list of missing debug handlers for this program space.  */

static PyObject *
pspy_get_missing_file_handlers (PyObject *o, void *ignore)
{
  pspace_object *self = (pspace_object *) o;

  Py_INCREF (self->missing_file_handlers);
  return self->missing_file_handlers;
}

/* Set this program space's list of missing debug handlers to HANDLERS.  */

static int
pspy_set_missing_file_handlers (PyObject *o, PyObject *handlers,
				 void *ignore)
{
  pspace_object *self = (pspace_object *) o;

  if (handlers == nullptr)
    {
      PyErr_SetString (PyExc_TypeError,
		       "cannot delete the missing debug handlers list");
      return -1;
    }

  if (!PyList_Check (handlers))
    {
      PyErr_SetString (PyExc_TypeError,
		       "the missing debug handlers attribute must be a list");
      return -1;
    }

  /* Take care in case the LHS and RHS are related somehow.  */
  gdbpy_ref<> tmp (self->missing_file_handlers);
  Py_INCREF (handlers);
  self->missing_file_handlers = handlers;

  return 0;
}

/* Set the 'type_printers' attribute.  */

static int
pspy_set_type_printers (PyObject *o, PyObject *value, void *ignore)
{
  pspace_object *self = (pspace_object *) o;

  if (! value)
    {
      PyErr_SetString (PyExc_TypeError,
		       "cannot delete the type_printers attribute");
      return -1;
    }

  if (! PyList_Check (value))
    {
      PyErr_SetString (PyExc_TypeError,
		       "the type_printers attribute must be a list");
      return -1;
    }

  /* Take care in case the LHS and RHS are related somehow.  */
  gdbpy_ref<> tmp (self->type_printers);
  Py_INCREF (value);
  self->type_printers = value;

  return 0;
}

/* Implement the objfiles method.  */

static PyObject *
pspy_get_objfiles (PyObject *self_, PyObject *args)
{
  pspace_object *self = (pspace_object *) self_;

  PSPY_REQUIRE_VALID (self);

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

  if (self->pspace != NULL)
    {
      for (objfile &objf : self->pspace->objfiles ())
	{
	  gdbpy_ref<> item = objfile_to_objfile_object (&objf);

	  if (item == nullptr
	      || PyList_Append (list.get (), item.get ()) == -1)
	    return NULL;
	}
    }

  return list.release ();
}

/* Implementation of solib_name (Long) -> String.
   Returns the name of the shared library holding a given address, or None.  */

static PyObject *
pspy_solib_name (PyObject *o, PyObject *args)
{
  CORE_ADDR pc;
  PyObject *pc_obj;

  pspace_object *self = (pspace_object *) o;

  PSPY_REQUIRE_VALID (self);

  if (!PyArg_ParseTuple (args, "O", &pc_obj))
    return NULL;
  if (get_addr_from_python (pc_obj, &pc) < 0)
    return nullptr;

  const char *soname = solib_name_from_address (self->pspace, pc);
  if (soname == nullptr)
    Py_RETURN_NONE;
  return host_string_to_python_string (soname).release ();
}

/* Implement objfile_for_address.  */

static PyObject *
pspy_objfile_for_address (PyObject *o, PyObject *args)
{
  CORE_ADDR addr;
  PyObject *addr_obj;

  pspace_object *self = (pspace_object *) o;

  PSPY_REQUIRE_VALID (self);

  if (!PyArg_ParseTuple (args, "O", &addr_obj))
    return nullptr;
  if (get_addr_from_python (addr_obj, &addr) < 0)
    return nullptr;

  struct objfile *objf = self->pspace->objfile_for_address (addr);
  if (objf == nullptr)
    Py_RETURN_NONE;

  return objfile_to_objfile_object (objf).release ();
}

/* Return the innermost lexical block containing the specified pc value,
   or 0 if there is none.  */
static PyObject *
pspy_block_for_pc (PyObject *o, PyObject *args)
{
  pspace_object *self = (pspace_object *) o;
  CORE_ADDR pc;
  PyObject *pc_obj;
  const struct block *block = NULL;
  struct compunit_symtab *cust = NULL;

  PSPY_REQUIRE_VALID (self);

  if (!PyArg_ParseTuple (args, "O", &pc_obj))
    return NULL;
  if (get_addr_from_python (pc_obj, &pc) < 0)
    return nullptr;

  try
    {
      scoped_restore_current_program_space saver;

      set_current_program_space (self->pspace);
      cust = find_compunit_symtab_for_pc (pc);

      if (cust != NULL && cust->objfile () != NULL)
	block = block_for_pc (pc);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  if (cust == NULL || cust->objfile () == NULL)
    Py_RETURN_NONE;

  if (block)
    return block_to_block_object (block, cust->objfile ());

  Py_RETURN_NONE;
}

/* Implementation of the find_pc_line function.
   Returns the gdb.Symtab_and_line object corresponding to a PC value.  */

static PyObject *
pspy_find_pc_line (PyObject *o, PyObject *args)
{
  CORE_ADDR pc;
  PyObject *result = NULL; /* init for gcc -Wall */
  PyObject *pc_obj;
  pspace_object *self = (pspace_object *) o;

  PSPY_REQUIRE_VALID (self);

  if (!PyArg_ParseTuple (args, "O", &pc_obj))
    return NULL;
  if (get_addr_from_python (pc_obj, &pc) < 0)
    return nullptr;

  try
    {
      struct symtab_and_line sal;
      scoped_restore_current_program_space saver;

      set_current_program_space (self->pspace);

      sal = find_sal_for_pc (pc, 0);
      result = symtab_and_line_to_sal_object (sal);
    }
  catch (const gdb_exception &except)
    {
      return gdbpy_handle_gdb_exception (nullptr, except);
    }

  return result;
}

/* Implementation of is_valid (self) -> Boolean.
   Returns True if this program space still exists in GDB.  */

static PyObject *
pspy_is_valid (PyObject *o, PyObject *args)
{
  pspace_object *self = (pspace_object *) o;

  if (self->pspace == NULL)
    Py_RETURN_FALSE;

  Py_RETURN_TRUE;
}



/* Return a new reference to the Python object of type Pspace
   representing PSPACE.  If the object has already been created,
   return it.  Otherwise, create it.  Return NULL and set the Python
   error on failure.  */

gdbpy_ref<>
pspace_to_pspace_object (struct program_space *pspace)
{
  PyObject *result = (PyObject *) pspy_pspace_data_key.get (pspace);
  if (result == NULL)
    {
      gdbpy_ref<pspace_object> object
	((pspace_object *) PyObject_New (pspace_object, &pspace_object_type));
      if (object == NULL)
	return NULL;
      if (!pspy_initialize (object.get ()))
	return NULL;

      object->pspace = pspace;
      pspy_pspace_data_key.set (pspace, object.get ());
      result = (PyObject *) object.release ();
    }

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

/* See python-internal.h.  */

struct program_space *
progspace_object_to_program_space (PyObject *obj)
{
  gdb_assert (gdbpy_is_progspace (obj));
  return ((pspace_object *) obj)->pspace;
}

/* See python-internal.h.  */

bool
gdbpy_is_progspace (PyObject *obj)
{
  return PyObject_TypeCheck (obj, &pspace_object_type);
}

/* Emit an ExecutableChangedEvent event to REGISTRY.  Return 0 on success,
   or a negative value on error.  PSPACE is the program_space in which the
   current executable has changed, and RELOAD_P is true if the executable
   path stayed the same, but the file on disk changed, or false if the
   executable path actually changed.  */

static int
emit_executable_changed_event (eventregistry_object *registry,
			       struct program_space *pspace, bool reload_p)
{
  gdbpy_ref<> event_obj
    = create_event_object (&executable_changed_event_object_type);
  if (event_obj == nullptr)
    return -1;

  gdbpy_ref<> py_pspace = pspace_to_pspace_object (pspace);
  if (py_pspace == nullptr
      || evpy_add_attribute (event_obj.get (), "progspace",
			     py_pspace.get ()) < 0)
    return -1;

  gdbpy_ref<> py_reload_p (PyBool_FromLong (reload_p ? 1 : 0));
  if (py_reload_p == nullptr
      || evpy_add_attribute (event_obj.get (), "reload",
			     py_reload_p.get ()) < 0)
    return -1;

  return evpy_emit_event (event_obj.get (), registry);
}

/* Listener for the executable_changed observable, this is called when the
   current executable within PSPACE changes.  RELOAD_P is true if the
   executable path stayed the same but the file changed on disk.  RELOAD_P
   is false if the executable path was changed.  */

static void
gdbpy_executable_changed (struct program_space *pspace, bool reload_p)
{
  if (!gdb_python_initialized)
    return;

  gdbpy_enter enter_py;

  if (!evregpy_no_listeners_p (gdb_py_events.executable_changed))
    if (emit_executable_changed_event (gdb_py_events.executable_changed,
				       pspace, reload_p) < 0)
      gdbpy_print_stack ();
}

/* Helper function to emit NewProgspaceEvent (when ADDING_P is true) or
   FreeProgspaceEvent events (when ADDING_P is false).  */

static void
gdbpy_program_space_event (program_space *pspace, bool adding_p)
{
  if (!gdb_python_initialized)
    return;

  gdbpy_enter enter_py;

  eventregistry_object *registry;
  PyTypeObject *event_type;
  if (adding_p)
    {
      registry = gdb_py_events.new_progspace;
      event_type = &new_progspace_event_object_type;
    }
  else
    {
      registry = gdb_py_events.free_progspace;
      event_type = &free_progspace_event_object_type;
    }

  if (evregpy_no_listeners_p (registry))
    return;

  gdbpy_ref<> pspace_obj = pspace_to_pspace_object (pspace);
  if (pspace_obj == nullptr)
    {
      gdbpy_print_stack ();
      return;
    }

  gdbpy_ref<> event = create_event_object (event_type);
  if (event == nullptr
      || evpy_add_attribute (event.get (), "progspace",
			     pspace_obj.get ()) < 0
      || evpy_emit_event (event.get (), registry) < 0)
    gdbpy_print_stack ();
}

/* Emit a NewProgspaceEvent to indicate PSPACE has been created.  */

static void
gdbpy_new_program_space_event (program_space *pspace)
{
  gdbpy_program_space_event (pspace, true);
}

/* Emit a FreeProgspaceEvent to indicate PSPACE is just about to be removed
   from GDB.  */

static void
gdbpy_free_program_space_event (program_space *pspace)
{
  gdbpy_program_space_event (pspace, false);
}

static int
gdbpy_initialize_pspace ()
{
  gdb::observers::executable_changed.attach (gdbpy_executable_changed,
					     "py-progspace");
  gdb::observers::new_program_space.attach (gdbpy_new_program_space_event,
					    "py-progspace");
  gdb::observers::free_program_space.attach (gdbpy_free_program_space_event,
					     "py-progspace");

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

  return 0;
}

GDBPY_INITIALIZE_FILE (gdbpy_initialize_pspace);



static gdb_PyGetSetDef pspace_getset[] =
{
  { "__dict__", gdb_py_generic_dict_getter, NULL,
    "The __dict__ for this progspace.", NULL },
  { "filename", pspy_get_filename, NULL,
    "The filename of the progspace's main symbol file, or None.", nullptr },
  { "symbol_file", pspy_get_symbol_file, nullptr,
    "The gdb.Objfile for the progspace's main symbol file, or None.",
    nullptr},
  { "executable_filename", pspy_get_exec_file, nullptr,
    "The filename for the progspace's executable, or None.", nullptr},
  { "pretty_printers", pspy_get_printers, pspy_set_printers,
    "Pretty printers.", NULL },
  { "frame_filters", pspy_get_frame_filters, pspy_set_frame_filters,
    "Frame filters.", NULL },
  { "frame_unwinders", pspy_get_frame_unwinders, pspy_set_frame_unwinders,
    "Frame unwinders.", NULL },
  { "type_printers", pspy_get_type_printers, pspy_set_type_printers,
    "Type printers.", NULL },
  { "xmethods", pspy_get_xmethods, NULL,
    "Debug methods.", NULL },
  { "missing_file_handlers", pspy_get_missing_file_handlers,
    pspy_set_missing_file_handlers, "Missing file handlers.", NULL },
  { NULL }
};

static PyMethodDef progspace_object_methods[] =
{
  { "objfiles", pspy_get_objfiles, METH_NOARGS,
    "Return a sequence of objfiles associated to this program space." },
  { "solib_name", pspy_solib_name, METH_VARARGS,
    "solib_name (Long) -> String.\n\
Return the name of the shared library holding a given address, or None." },
  { "objfile_for_address", pspy_objfile_for_address, METH_VARARGS,
    "objfile_for_address (int) -> gdb.Objfile\n\
Return the objfile containing the given address, or None." },
  { "block_for_pc", pspy_block_for_pc, METH_VARARGS,
    "Return the block containing the given pc value, or None." },
  { "find_pc_line", pspy_find_pc_line, METH_VARARGS,
    "find_pc_line (pc) -> Symtab_and_line.\n\
Return the gdb.Symtab_and_line object corresponding to the pc value." },
  { "is_valid", pspy_is_valid, METH_NOARGS,
    "is_valid () -> Boolean.\n\
Return true if this program space is valid, false if not." },
  { NULL }
};

PyTypeObject pspace_object_type =
{
  PyVarObject_HEAD_INIT (NULL, 0)
  "gdb.Progspace",		  /*tp_name*/
  sizeof (pspace_object),	  /*tp_basicsize*/
  0,				  /*tp_itemsize*/
  pspy_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*/
  gdb_py_generic_getattro,	  /*tp_getattro*/
  gdb_py_generic_setattro,	  /*tp_setattro*/
  0,				  /*tp_as_buffer*/
  Py_TPFLAGS_DEFAULT,		  /*tp_flags*/
  "GDB progspace object",	  /* tp_doc */
  0,				  /* tp_traverse */
  0,				  /* tp_clear */
  0,				  /* tp_richcompare */
  0,				  /* tp_weaklistoffset */
  0,				  /* tp_iter */
  0,				  /* tp_iternext */
  progspace_object_methods,	  /* tp_methods */
  0,				  /* tp_members */
  pspace_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 */
};
