/* Python interface to program spaces.

   Copyright (C) 2010-2025 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
{
  PyObject_HEAD

  /* The corresponding pspace.  */
  struct program_space *pspace;

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

  /* 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
    CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("pspace_object");

/* 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_pc_compunit_symtab (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_pc_line (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 CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION
gdbpy_initialize_pspace (void)
{
  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, NULL,
    "The __dict__ for this progspace.", &pspace_object_type },
  { "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*/
  0,				  /*tp_getattro*/
  0,				  /*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 */
  offsetof (pspace_object, dict), /* tp_dictoffset */
  0,				  /* tp_init */
  0,				  /* tp_alloc */
  0,				  /* tp_new */
};
