/* Gdb/Python header for private use by Python module.

   Copyright (C) 2008-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/>.  */

#ifndef GDB_PYTHON_PYTHON_INTERNAL_H
#define GDB_PYTHON_PYTHON_INTERNAL_H

#include "extension.h"
#include "extension-priv.h"
#include "registry.h"

/* /usr/include/features.h on linux systems will define _POSIX_C_SOURCE
   if it sees _GNU_SOURCE (which config.h will define).
   pyconfig.h defines _POSIX_C_SOURCE to a different value than
   /usr/include/features.h does causing compilation to fail.
   To work around this, undef _POSIX_C_SOURCE before we include Python.h.

   Same problem with _XOPEN_SOURCE.  */
#undef _POSIX_C_SOURCE
#undef _XOPEN_SOURCE

/* On sparc-solaris, /usr/include/sys/feature_tests.h defines
   _FILE_OFFSET_BITS, which pyconfig.h also defines.  Same work
   around technique as above.  */
#undef _FILE_OFFSET_BITS

/* A kludge to avoid redefinition of snprintf on Windows by pyerrors.h.  */
#if defined(_WIN32) && defined(HAVE_DECL_SNPRINTF)
#define HAVE_SNPRINTF 1
#endif

/* Another kludge to avoid compilation errors because MinGW defines
   'hypot' to '_hypot', but the C++ headers says "using ::hypot".  */
#ifdef __MINGW32__
# define _hypot hypot
#endif

/* Request clean size types from Python.  */
#define PY_SSIZE_T_CLEAN

/* Include the Python header files using angle brackets rather than
   double quotes.  On case-insensitive filesystems, this prevents us
   from including our python/python.h header file.  */
#include <Python.h>
#include <frameobject.h>
#include "py-ref.h"

static_assert (PY_VERSION_HEX >= 0x03040000);

/* If Python.h does not define WITH_THREAD, then the various
   GIL-related functions will not be defined.  However,
   PyGILState_STATE will be.  */
#ifndef WITH_THREAD
#define PyGILState_Ensure() ((PyGILState_STATE) 0)
#define PyGILState_Release(ARG) ((void)(ARG))
#define PyEval_InitThreads()
#define PyThreadState_Swap(ARG) ((void)(ARG))
#define PyEval_ReleaseLock()
#endif

/* Python supplies HAVE_LONG_LONG and some `long long' support when it
   is available.  These defines let us handle the differences more
   cleanly.

   Starting with python 3.6, support for platforms without long long support
   has been removed [1].  HAVE_LONG_LONG and PY_LONG_LONG are still defined,
   but only for compatibility, so we no longer rely on them.

   [1] https://github.com/python/cpython/issues/72148.  */
#if PY_VERSION_HEX >= 0x03060000 || defined (HAVE_LONG_LONG)

#define GDB_PY_LL_ARG "L"
#define GDB_PY_LLU_ARG "K"
#if PY_VERSION_HEX >= 0x03060000
typedef long long gdb_py_longest;
typedef unsigned long long gdb_py_ulongest;
#else
typedef PY_LONG_LONG gdb_py_longest;
typedef unsigned PY_LONG_LONG gdb_py_ulongest;
#endif
#define gdb_py_long_as_ulongest PyLong_AsUnsignedLongLong
#define gdb_py_long_as_long_and_overflow PyLong_AsLongLongAndOverflow

#else /* HAVE_LONG_LONG */

#define GDB_PY_LL_ARG "l"
#define GDB_PY_LLU_ARG "k"
typedef long gdb_py_longest;
typedef unsigned long gdb_py_ulongest;
#define gdb_py_long_as_ulongest PyLong_AsUnsignedLong
#define gdb_py_long_as_long_and_overflow PyLong_AsLongAndOverflow

#endif /* HAVE_LONG_LONG */

#if PY_VERSION_HEX < 0x030a0000
static inline PyObject *
Py_NewRef (PyObject *obj)
{
  Py_INCREF (obj);
  return obj;
}
#endif

/* A template variable holding the format character (as for
   Py_BuildValue) for a given type.  */
template<typename T>
struct gdbpy_method_format {};

template<>
struct gdbpy_method_format<gdb_py_longest>
{
  static constexpr char format = GDB_PY_LL_ARG[0];
};

template<>
struct gdbpy_method_format<gdb_py_ulongest>
{
  static constexpr char format = GDB_PY_LLU_ARG[0];
};

template<>
struct gdbpy_method_format<int>
{
  static constexpr char format = 'i';
};

template<>
struct gdbpy_method_format<unsigned>
{
  static constexpr char format = 'I';
};

/* A helper function to compute the PyObject_CallMethod /
   Py_BuildValue format given the argument types.  */

template<typename... Args>
constexpr std::array<char, sizeof... (Args) + 1>
gdbpy_make_fmt ()
{
  return { gdbpy_method_format<Args>::format..., '\0' };
}

/* Typesafe wrapper around PyObject_CallMethod.

   This variant accepts no arguments.  */

static inline gdbpy_ref<>
gdbpy_call_method (PyObject *o, const char *method)
{
  /* PyObject_CallMethod's 'method' and 'format' parameters were missing the
     'const' qualifier before Python 3.4.  */
  return gdbpy_ref<> (PyObject_CallMethod (o,
					   const_cast<char *> (method),
					   nullptr));
}

/* Typesafe wrapper around PyObject_CallMethod.

   This variant accepts any number of arguments and automatically
   computes the format string, ensuring that format/argument
   mismatches are impossible.  */

template<typename Arg, typename... Args>
static inline gdbpy_ref<>
gdbpy_call_method (PyObject *o, const char *method,
		   Arg arg, Args... args)
{
  constexpr const auto fmt = gdbpy_make_fmt<Arg, Args...> ();

  /* PyObject_CallMethod's 'method' and 'format' parameters were missing the
     'const' qualifier before Python 3.4.  */
  return gdbpy_ref<> (PyObject_CallMethod (o,
					   const_cast<char *> (method),
					   const_cast<char *> (fmt.data ()),
					   arg, args...));
}

/* An overload that takes a gdbpy_ref<> rather than a raw 'PyObject *'.  */

template<typename... Args>
static inline gdbpy_ref<>
gdbpy_call_method (const gdbpy_ref<> &o, const char *method, Args... args)
{
  return gdbpy_call_method (o.get (), method, args...);
}

/* Poison PyObject_CallMethod.  The typesafe wrapper gdbpy_call_method should be
   used instead.  */
#undef PyObject_CallMethod
#ifdef __GNUC__
# pragma GCC poison PyObject_CallMethod
#else
# define PyObject_CallMethod POISONED_PyObject_CallMethod
#endif

/* The 'name' parameter of PyErr_NewException was missing the 'const'
   qualifier in Python <= 3.4.  Hence, we wrap it in a function to
   avoid errors when compiled with -Werror.  */

static inline PyObject*
gdb_PyErr_NewException (const char *name, PyObject *base, PyObject *dict)
{
  return PyErr_NewException (const_cast<char *> (name), base, dict);
}

#define PyErr_NewException gdb_PyErr_NewException

/* PySys_GetObject's 'name' parameter was missing the 'const'
   qualifier before Python 3.4.  Hence, we wrap it in a function to
   avoid errors when compiled with -Werror.  */

static inline PyObject *
gdb_PySys_GetObject (const char *name)
{
  return PySys_GetObject (const_cast<char *> (name));
}

#define PySys_GetObject gdb_PySys_GetObject

/* PySys_SetPath was deprecated in Python 3.11.  Disable the deprecated
   code for Python 3.10 and newer.  */
#if PY_VERSION_HEX < 0x030a0000

/* PySys_SetPath's 'path' parameter was missing the 'const' qualifier
   before Python 3.6.  Hence, we wrap it in a function to avoid errors
   when compiled with -Werror.  */

# define GDB_PYSYS_SETPATH_CHAR wchar_t

static inline void
gdb_PySys_SetPath (const GDB_PYSYS_SETPATH_CHAR *path)
{
  PySys_SetPath (const_cast<GDB_PYSYS_SETPATH_CHAR *> (path));
}

#define PySys_SetPath gdb_PySys_SetPath
#endif

/* Wrap PyGetSetDef to allow convenient construction with string
   literals.  Unfortunately, PyGetSetDef's 'name' and 'doc' members
   are 'char *' instead of 'const char *', meaning that in order to
   list-initialize PyGetSetDef arrays with string literals (and
   without the wrapping below) would require writing explicit 'char *'
   casts.  Instead, we extend PyGetSetDef and add constexpr
   constructors that accept const 'name' and 'doc', hiding the ugly
   casts here in a single place.  */

struct gdb_PyGetSetDef : PyGetSetDef
{
  constexpr gdb_PyGetSetDef (const char *name_, getter get_, setter set_,
			     const char *doc_, void *closure_)
    : PyGetSetDef {const_cast<char *> (name_), get_, set_,
		   const_cast<char *> (doc_), closure_}
  {}

  /* Alternative constructor that allows omitting the closure in list
     initialization.  */
  constexpr gdb_PyGetSetDef (const char *name_, getter get_, setter set_,
			     const char *doc_)
    : gdb_PyGetSetDef {name_, get_, set_, doc_, NULL}
  {}

  /* Constructor for the sentinel entries.  */
  constexpr gdb_PyGetSetDef (std::nullptr_t)
    : gdb_PyGetSetDef {NULL, NULL, NULL, NULL, NULL}
  {}
};

/* The 'keywords' parameter of PyArg_ParseTupleAndKeywords has type
   'char **'.  However, string literals are const in C++, and so to
   avoid casting at every keyword array definition, we'll need to make
   the keywords array an array of 'const char *'.  To avoid having all
   callers add a 'const_cast<char **>' themselves when passing such an
   array through 'char **', we define our own version of
   PyArg_ParseTupleAndKeywords here with a corresponding 'keywords'
   parameter type that does the cast in a single place.  (This is not
   an overload of PyArg_ParseTupleAndKeywords in order to make it
   clearer that we're calling our own function instead of a function
   that exists in some newer Python version.)  */

static inline int
gdb_PyArg_ParseTupleAndKeywords (PyObject *args, PyObject *kw,
				 const char *format, const char **keywords, ...)
{
  va_list ap;
  int res;

  va_start (ap, keywords);
  res = PyArg_VaParseTupleAndKeywords (args, kw, format,
				       const_cast<char **> (keywords),
				       ap);
  va_end (ap);

  return res;
}

/* In order to be able to parse symtab_and_line_to_sal_object function
   a real symtab_and_line structure is needed.  */
#include "symtab.h"

/* Also needed to parse enum var_types. */
#include "command.h"
#include "breakpoint.h"

enum gdbpy_iter_kind { iter_keys, iter_values, iter_items };

struct block;
struct value;
struct language_defn;
struct program_space;
struct bpstat;
struct inferior;

extern int gdb_python_initialized;

extern PyObject *gdb_module;
extern PyObject *gdb_python_module;
extern PyTypeObject value_object_type;
extern PyTypeObject block_object_type;
extern PyTypeObject symbol_object_type;
extern PyTypeObject event_object_type;
extern PyTypeObject breakpoint_object_type;
extern PyTypeObject frame_object_type;
extern PyTypeObject thread_object_type;

/* Ensure that breakpoint_object_type is initialized and return true.  If
   breakpoint_object_type can't be initialized then set a suitable Python
   error and return false.

   This function needs to be called from any gdbpy_initialize_* function
   that wants to reference breakpoint_object_type.  After all the
   gdbpy_initialize_* functions have been called then breakpoint_object_type
   is guaranteed to have been initialized, and this function does not need
   calling before referencing breakpoint_object_type.  */

extern bool gdbpy_breakpoint_init_breakpoint_type ();

struct gdbpy_breakpoint_object : public PyObject
{
  /* The breakpoint number according to gdb.  */
  int number;

  /* The gdb breakpoint object, or NULL if the breakpoint has been
     deleted.  */
  struct breakpoint *bp;

  /* 1 is this is a FinishBreakpoint object, 0 otherwise.  */
  int is_finish_bp;
};

/* Require that BREAKPOINT be a valid breakpoint ID; throw a Python
   exception if it is invalid.  */
#define BPPY_REQUIRE_VALID(Breakpoint)                                  \
    do {                                                                \
      if ((Breakpoint)->bp == NULL)                                     \
	return PyErr_Format (PyExc_RuntimeError,                        \
			     _("Breakpoint %d is invalid."),            \
			     (Breakpoint)->number);                     \
    } while (0)

/* Require that BREAKPOINT be a valid breakpoint ID; throw a Python
   exception if it is invalid.  This macro is for use in setter functions.  */
#define BPPY_SET_REQUIRE_VALID(Breakpoint)                              \
    do {                                                                \
      if ((Breakpoint)->bp == NULL)                                     \
	{                                                               \
	  PyErr_Format (PyExc_RuntimeError, _("Breakpoint %d is invalid."), \
			(Breakpoint)->number);                          \
	  return -1;                                                    \
	}                                                               \
    } while (0)


/* Variables used to pass information between the Breakpoint
   constructor and the breakpoint-created hook function.  */
extern gdbpy_breakpoint_object *bppy_pending_object;


struct thread_object : public gdbpy_dict_wrapper
{
  /* The thread we represent.  */
  struct thread_info *thread;

  /* The Inferior object to which this thread belongs.  */
  PyObject *inf_obj;
};

using thread_map_t
  = gdb::unordered_map<thread_info *, gdbpy_ref<thread_object>>;

struct inferior_object : public gdbpy_dict_wrapper
{
  /* The inferior we represent.  */
  struct inferior *inferior;

  /* thread_object instances under this inferior.  This owns a
     reference to each object it contains.  */
  thread_map_t *threads;
};

extern struct cmd_list_element *set_python_list;
extern struct cmd_list_element *show_python_list;

/* extension_language_script_ops "methods".  */

/* Return true if auto-loading Python scripts is enabled.
   This is the extension_language_script_ops.auto_load_enabled "method".  */

extern bool gdbpy_auto_load_enabled (const struct extension_language_defn *);

/* extension_language_ops "methods".  */

extern enum ext_lang_rc gdbpy_apply_val_pretty_printer
  (const struct extension_language_defn *,
   struct value *value,
   struct ui_file *stream, int recurse,
   const struct value_print_options *options,
   const struct language_defn *language);
extern void gdbpy_load_ptwrite_filter
  (const struct extension_language_defn *extlang,
   struct btrace_thread_info *btinfo);
extern enum ext_lang_bt_status gdbpy_apply_frame_filter
  (const struct extension_language_defn *,
   const frame_info_ptr &frame, frame_filter_flags flags,
   enum ext_lang_frame_args args_type,
   struct ui_out *out, int frame_low, int frame_high);
extern void gdbpy_preserve_values (const struct extension_language_defn *,
				   struct objfile *objfile,
				   copied_types_hash_t &copied_types);
extern enum ext_lang_bp_stop gdbpy_breakpoint_cond_says_stop
  (const struct extension_language_defn *, struct breakpoint *);
extern int gdbpy_breakpoint_has_cond (const struct extension_language_defn *,
				      struct breakpoint *b);

extern enum ext_lang_rc gdbpy_get_matching_xmethod_workers
  (const struct extension_language_defn *extlang,
   struct type *obj_type, const char *method_name,
   std::vector<xmethod_worker_up> *dm_vec);


PyObject *gdbpy_history (PyObject *self, PyObject *args);
PyObject *gdbpy_add_history (PyObject *self, PyObject *args);
extern PyObject *gdbpy_history_count (PyObject *self, PyObject *args);
PyObject *gdbpy_convenience_variable (PyObject *self, PyObject *args);
PyObject *gdbpy_set_convenience_variable (PyObject *self, PyObject *args);
PyObject *gdbpy_breakpoints (PyObject *, PyObject *);
PyObject *gdbpy_frame_stop_reason_string (PyObject *, PyObject *);
PyObject *gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw);
PyObject *gdbpy_lookup_global_symbol (PyObject *self, PyObject *args,
				      PyObject *kw);
PyObject *gdbpy_lookup_static_symbol (PyObject *self, PyObject *args,
				      PyObject *kw);
PyObject *gdbpy_lookup_static_symbols (PyObject *self, PyObject *args,
					   PyObject *kw);
PyObject *gdbpy_start_recording (PyObject *self, PyObject *args);
PyObject *gdbpy_current_recording (PyObject *self, PyObject *args);
PyObject *gdbpy_stop_recording (PyObject *self, PyObject *args);
PyObject *gdbpy_newest_frame (PyObject *self, PyObject *args);
PyObject *gdbpy_selected_frame (PyObject *self, PyObject *args);
PyObject *gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw);
int gdbpy_is_field (PyObject *obj);
PyObject *gdbpy_create_lazy_string_object (CORE_ADDR address, long length,
					   const char *encoding,
					   struct type *type);
PyObject *gdbpy_inferiors (PyObject *unused, PyObject *unused2);

/* Return a reference to a new Python Tuple object representing a ptid_t.
   The object is a tuple containing (pid, lwp, tid).  */

extern gdbpy_ref<> gdbpy_create_ptid_object (ptid_t ptid);

PyObject *gdbpy_selected_thread (PyObject *self, PyObject *args);
PyObject *gdbpy_selected_inferior (PyObject *self, PyObject *args);
PyObject *gdbpy_string_to_argv (PyObject *self, PyObject *args);
PyObject *gdbpy_parameter_value (const setting &var);
gdb::unique_xmalloc_ptr<char> gdbpy_parse_command_name
  (const char *name, struct cmd_list_element ***base_list,
   struct cmd_list_element **start_list,
   struct cmd_list_element **prefix_cmd = nullptr);
PyObject *gdbpy_register_tui_window (PyObject *self, PyObject *args,
				     PyObject *kw);

gdbpy_ref<> symtab_and_line_to_sal_object (struct symtab_and_line sal);
gdbpy_ref<> symtab_to_symtab_object (struct symtab *symtab);
gdbpy_ref<> symbol_to_symbol_object (struct symbol *sym);
gdbpy_ref<> block_to_block_object (const struct block *block,
				   struct objfile *objfile);
gdbpy_ref<> value_to_value_object (struct value *v);
gdbpy_ref<> type_to_type_object (struct type *);
gdbpy_ref<> frame_info_to_frame_object (const frame_info_ptr &frame);
gdbpy_ref<> symtab_to_linetable_object (PyObject *symtab);
gdbpy_ref<> pspace_to_pspace_object (struct program_space *);
PyObject *pspy_get_printers (PyObject *, void *);
PyObject *pspy_get_frame_filters (PyObject *, void *);
PyObject *pspy_get_frame_unwinders (PyObject *, void *);
PyObject *pspy_get_xmethods (PyObject *, void *);

gdbpy_ref<> objfile_to_objfile_object (struct objfile *);
PyObject *objfpy_get_printers (PyObject *, void *);
PyObject *objfpy_get_frame_filters (PyObject *, void *);
PyObject *objfpy_get_frame_unwinders (PyObject *, void *);
PyObject *objfpy_get_xmethods (PyObject *, void *);
PyObject *gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw);

gdbpy_ref<> gdbarch_to_arch_object (struct gdbarch *gdbarch);
PyObject *gdbpy_all_architecture_names (PyObject *self, PyObject *args);

PyObject *gdbpy_new_register_descriptor_iterator (struct gdbarch *gdbarch,
						  const char *group_name);
PyObject *gdbpy_new_reggroup_iterator (struct gdbarch *gdbarch);

gdbpy_ref<thread_object> create_thread_object (struct thread_info *tp);
gdbpy_ref<> thread_to_thread_object (thread_info *thr);;
gdbpy_ref<inferior_object> inferior_to_inferior_object (inferior *inf);

PyObject *gdbpy_buffer_to_membuf (gdb::unique_xmalloc_ptr<gdb_byte> buffer,
				  CORE_ADDR address, ULONGEST length);

struct process_stratum_target;
gdbpy_ref<> target_to_connection_object (process_stratum_target *target);
PyObject *gdbpy_connections (PyObject *self, PyObject *args);

const struct block *block_object_to_block (PyObject *obj);
struct symbol *symbol_object_to_symbol (PyObject *obj);
struct value *value_object_to_value (PyObject *self);
struct value *convert_value_from_python (PyObject *obj);
struct type *type_object_to_type (PyObject *obj);
struct symtab *symtab_object_to_symtab (PyObject *obj);
struct symtab_and_line *sal_object_to_symtab_and_line (PyObject *obj);
frame_info_ptr frame_object_to_frame_info (PyObject *frame_obj);
struct gdbarch *arch_object_to_gdbarch (PyObject *obj);

/* Return true if OBJ is a gdb.Style object.  OBJ must not be NULL.  */

extern bool gdbpy_is_style (PyObject *obj);

/* Return the ui_file_style from OBJ, a gdb.Style object.  OBJ must not be
   NULL.

   It is possible that OBJ is a gdb.Style object, but the underlying style
   cannot be fetched for some reason.  If this happens then a Python error
   is set and an empty optional is returned.  */

extern std::optional<ui_file_style>
  gdbpy_style_object_to_ui_file_style (PyObject *obj);

extern PyObject *gdbpy_execute_mi_command (PyObject *self, PyObject *args,
					   PyObject *kw);

/* Serialize RESULTS and print it in MI format to the current_uiout.

   This function handles the top-level results passed as a dictionary.
   The caller is responsible for ensuring that.  The values within this
   dictionary can be a wider range of types.  Handling the values of the top-level
   dictionary is done by serialize_mi_result_1, see that function for more
   details.

   If anything goes wrong while parsing and printing the MI output then an
   error is thrown.  */

extern void serialize_mi_results (PyObject *results);

/* Implementation of the gdb.notify_mi function.  */

extern PyObject *gdbpy_notify_mi (PyObject *self, PyObject *args,
				  PyObject *kw);

/* Convert Python object OBJ to a program_space pointer.  OBJ must be a
   gdb.Progspace reference.  Return nullptr if the gdb.Progspace is not
   valid (see gdb.Progspace.is_valid), otherwise return the program_space
   pointer.  */

extern struct program_space *progspace_object_to_program_space (PyObject *obj);

/* A class for managing the initialization, and finalization functions
   from all Python files (e.g. gdb/python/py-*.c).

   Within any Python file, create an instance of this class, passing in
   the initialization function, and, optionally, the finalization
   function.

   These functions are added to a single global list of functions, which
   can then be called from do_start_initialization and finalize_python
   (see python.c) to initialize all the Python files within GDB.  */

class gdbpy_initialize_file
{
  /* The type of a function that can be called just after GDB has setup the
     Python interpreter.  This function will setup any additional Python
     state required by a particular subsystem.  Return 0 if the setup was
     successful, or return -1 if setup failed, in which case a Python
     exception should have been raised.  */

  using gdbpy_initialize_file_ftype = int (*) (void);

  /* The type of a function that can be called just before GDB shuts down
     the Python interpreter.  This function can cleanup an Python state
     that is cached within GDB, for example, if GDB is holding any
     references to Python objects, these should be released before the
     Python interpreter is shut down.

     There is no error return in this case.  This function is only called
     when GDB is already shutting down.  The function should make a best
     effort to clean up, and then return.  */

  using gdbpy_finalize_file_ftype = void (*) (void);

  /* The type for an initialization and finalization function pair.  */

  using callback_pair_t = std::pair<gdbpy_initialize_file_ftype,
				    gdbpy_finalize_file_ftype>;

  /* Return the vector of callbacks.  The vector is defined as a static
     variable within this function so that it will be initialized the first
     time this function is called.  This is important, as this function is
     called as part of the global object initialization process; if the
     vector was a static variable within this class then we could not
     guarantee that it had been initialized before it was used.  */

  static std::vector<callback_pair_t> &
  callbacks ()
  {
    static std::vector<callback_pair_t> list;
    return list;
  }

public:

  /* Register the initialization (INIT) and finalization (FINI) functions
     for a Python file.  See the comments on the function types above for
     when these functions will be called.

     Either of these functions can be nullptr, in which case no function
     will be called.

     The FINI argument is optional, and defaults to nullptr (no function to
     call).  */

  gdbpy_initialize_file (gdbpy_initialize_file_ftype init,
			 gdbpy_finalize_file_ftype fini = nullptr)
  {
    callbacks ().emplace_back (init, fini);
  }

  /* Run all the Python file initialize functions and return true.  If any
     of the initialize functions fails then this function returns false.
     In the case of failure it is undefined how many of the initialize
     functions will have been called.  */

  static bool
  initialize_all ()
  {
    /* The initialize_all function should only be called once.  The
       following check reverses the global list, which will effect this
       initialize_all call, as well as the later finalize_all call.

       The environment variable checked here is the same as the one checked
       in the generated init.c file.  */
    if (getenv ("GDB_REVERSE_INIT_FUNCTIONS") != nullptr)
      std::reverse (callbacks ().begin (), callbacks ().end ());

    for (const auto &p : gdbpy_initialize_file::callbacks ())
      {
	if (p.first != nullptr && p.first () < 0)
	  return false;
      }
    return true;
  }

  /* Run all the Python file finalize functions.  */

  static void
  finalize_all ()
  {
    for (const auto &p : gdbpy_initialize_file::callbacks ())
      {
	if (p.second != nullptr)
	  p.second ();
      }
  }
};

/* Macro to simplify registering the initialization and finalization
   functions for a Python file.  */

#define GDBPY_INITIALIZE_FILE(INIT, ...)				\
  static gdbpy_initialize_file						\
    CONCAT(gdbpy_initialize_file_obj_, __LINE__) (INIT, ##__VA_ARGS__)

PyMODINIT_FUNC gdbpy_events_mod_func ();

/* A wrapper for PyErr_Fetch that handles reference counting for the
   caller.  */
class gdbpy_err_fetch
{
public:

  gdbpy_err_fetch ()
  {
#if PY_VERSION_HEX < 0x030c0000
    PyObject *error_type, *error_value, *error_traceback;

    PyErr_Fetch (&error_type, &error_value, &error_traceback);
    m_error_type.reset (error_type);
    m_error_value.reset (error_value);
    m_error_traceback.reset (error_traceback);
#else
    /* PyErr_Fetch is deprecated in python 3.12, use PyErr_GetRaisedException
       instead.  */
    m_exc.reset (PyErr_GetRaisedException ());
#endif
  }

  /* Call PyErr_Restore using the values stashed in this object.
     After this call, this object is invalid and neither the to_string
     nor restore methods may be used again.  */

  void restore ()
  {
#if PY_VERSION_HEX < 0x030c0000
    PyErr_Restore (m_error_type.release (),
		   m_error_value.release (),
		   m_error_traceback.release ());
#else
    /* PyErr_Restore is deprecated in python 3.12, use PyErr_SetRaisedException
       instead.  */
    PyErr_SetRaisedException (m_exc.release ());
#endif
  }

  /* Return the string representation of the exception represented by
     this object.  If the result is NULL a python error occurred, the
     caller must clear it.  */

  gdb::unique_xmalloc_ptr<char> to_string () const;

  /* Return the string representation of the type of the exception
     represented by this object.  If the result is NULL a python error
     occurred, the caller must clear it.  */

  gdb::unique_xmalloc_ptr<char> type_to_string () const;

  /* Return true if the stored type matches TYPE, false otherwise.  */

  bool type_matches (PyObject *type) const
  {
    gdbpy_ref<> err_type = this->type ();
    return PyErr_GivenExceptionMatches (err_type.get (), type);
  }

  /* Return a new reference to the exception value object.  */

  gdbpy_ref<> value () const
  {
#if PY_VERSION_HEX < 0x030c0000
    if (!m_normalized)
      {
	PyObject *error_type, *error_value, *error_traceback;
	error_type = m_error_type.release ();
	error_value = m_error_value.release ();
	error_traceback = m_error_traceback.release ();
	PyErr_NormalizeException (&error_type, &error_value, &error_traceback);
	m_error_type.reset (error_type);
	m_error_value.reset (error_value);
	m_error_traceback.reset (error_traceback);
	m_normalized = true;
      }
    return m_error_value;
#else
    return m_exc;
#endif
  }

  /* Return a new reference to the exception type object.  */

  gdbpy_ref<> type () const
  {
#if PY_VERSION_HEX < 0x030c0000
    return m_error_type;
#else
    if (m_exc.get() == nullptr)
      return nullptr;
    return gdbpy_ref<>::new_reference ((PyObject *)Py_TYPE (m_exc.get ()));
#endif
  }

private:

#if PY_VERSION_HEX < 0x030c0000
  mutable gdbpy_ref<> m_error_type, m_error_value, m_error_traceback;
  mutable bool m_normalized = false;
#else
  gdbpy_ref<> m_exc;
#endif
};

/* Called before entering the Python interpreter to install the
   current language and architecture to be used for Python values.
   Also set the active extension language for GDB so that SIGINT's
   are directed our way, and if necessary install the right SIGINT
   handler.  */
class gdbpy_enter
{
 public:

  /* Set the ambient Python architecture to GDBARCH and the language
     to LANGUAGE.  If GDBARCH is nullptr, then the architecture will
     be computed, when needed, using get_current_arch; see the
     get_gdbarch method.  If LANGUAGE is not nullptr, then the current
     language at time of construction will be saved (to be restored on
     destruction), and the current language will be set to
     LANGUAGE.  */
  explicit gdbpy_enter (struct gdbarch *gdbarch = nullptr,
			const struct language_defn *language = nullptr);

  ~gdbpy_enter ();

  DISABLE_COPY_AND_ASSIGN (gdbpy_enter);

  /* Return the current gdbarch, as known to the Python layer.  This
     is either python_gdbarch (which comes from the most recent call
     to the gdbpy_enter constructor), or, if that is nullptr, the
     result of get_current_arch.  */
  static struct gdbarch *get_gdbarch ();

  /* Called only during gdb shutdown.  This sets python_gdbarch to an
     acceptable value.  */
  static void finalize ();

 private:

  /* The current gdbarch, according to Python.  This can be
     nullptr.  */
  static struct gdbarch *python_gdbarch;

  struct active_ext_lang_state *m_previous_active;
  PyGILState_STATE m_state;
  struct gdbarch *m_gdbarch;
  const struct language_defn *m_language;

  /* An optional is used here because we don't want to call
     PyErr_Fetch too early.  */
  std::optional<gdbpy_err_fetch> m_error;
};

/* Like gdbpy_enter, but takes a varobj.  This is a subclass just to
   make constructor delegation a little nicer.  */
class gdbpy_enter_varobj : public gdbpy_enter
{
 public:

  /* This is defined in varobj.c, where it can access varobj
     internals.  */
  gdbpy_enter_varobj (const struct varobj *var);

};

/* The opposite of gdb_enter: this releases the GIL around a region,
   allowing other Python threads to run.  No Python APIs may be used
   while this is active.  */
class gdbpy_allow_threads
{
public:

  gdbpy_allow_threads ()
    : m_save (PyEval_SaveThread ())
  {
    gdb_assert (m_save != nullptr);
  }

  ~gdbpy_allow_threads ()
  {
    PyEval_RestoreThread (m_save);
  }

  DISABLE_COPY_AND_ASSIGN (gdbpy_allow_threads);

private:

  PyThreadState *m_save;
};

/* A helper class to save and restore the GIL, but without touching
   the other globals that are handled by gdbpy_enter.  */

class gdbpy_gil
{
public:

  gdbpy_gil ()
    : m_state (PyGILState_Ensure ())
  {
  }

  ~gdbpy_gil ()
  {
    PyGILState_Release (m_state);
  }

  DISABLE_COPY_AND_ASSIGN (gdbpy_gil);

private:

  PyGILState_STATE m_state;
};

int gdbpy_print_python_errors_p (void);
void gdbpy_print_stack (void);
void gdbpy_print_stack_or_quit ();
[[noreturn]] void gdbpy_handle_exception ();

/* A wrapper around calling 'error'.  Prefixes the error message with an
   'Error occurred in Python' string.  Use this in C++ code if we spot
   something wrong with an object returned from Python code.  The prefix
   string gives the user a hint that the mistake is within Python code,
   rather than some other part of GDB.

   This always calls error, and never returns.  */

[[noreturn]] void gdbpy_error (const char *fmt, ...) ATTRIBUTE_PRINTF (1, 2);

gdbpy_ref<> python_string_to_unicode (PyObject *obj);
gdb::unique_xmalloc_ptr<char> unicode_to_target_string (PyObject *unicode_str);
gdb::unique_xmalloc_ptr<char> python_string_to_target_string (PyObject *obj);
gdbpy_ref<> python_string_to_target_python_string (PyObject *obj);
gdb::unique_xmalloc_ptr<char> python_string_to_host_string (PyObject *obj);

/* Convert a host string STR to a python string.  */

extern gdbpy_ref<> host_string_to_python_string (std::string_view str);

int gdbpy_is_string (PyObject *obj);
gdb::unique_xmalloc_ptr<char> gdbpy_obj_to_string (PyObject *obj);

int gdbpy_is_lazy_string (PyObject *result);
void gdbpy_extract_lazy_string (PyObject *string, CORE_ADDR *addr,
				struct type **str_type,
				long *length,
				gdb::unique_xmalloc_ptr<char> *encoding);

int gdbpy_is_value_object (PyObject *obj);

/* Note that these are declared here, and not in python.h with the
   other pretty-printer functions, because they refer to PyObject.  */
gdbpy_ref<> apply_varobj_pretty_printer (PyObject *print_obj,
					 struct value **replacement,
					 struct ui_file *stream,
					 const value_print_options *opts);
gdbpy_ref<> gdbpy_get_varobj_pretty_printer (struct value *value);
gdb::unique_xmalloc_ptr<char> gdbpy_get_display_hint (PyObject *printer);
PyObject *gdbpy_default_visualizer (PyObject *self, PyObject *args);

PyObject *gdbpy_print_options (PyObject *self, PyObject *args);
void gdbpy_get_print_options (value_print_options *opts);
extern const struct value_print_options *gdbpy_current_print_options;

void bpfinishpy_pre_stop_hook (struct gdbpy_breakpoint_object *bp_obj);
void bpfinishpy_post_stop_hook (struct gdbpy_breakpoint_object *bp_obj);
void bpfinishpy_pre_delete_hook (struct gdbpy_breakpoint_object *bp_obj);

extern PyObject *gdbpy_doc_cst;
extern PyObject *gdbpy_children_cst;
extern PyObject *gdbpy_to_string_cst;
extern PyObject *gdbpy_display_hint_cst;
extern PyObject *gdbpy_enabled_cst;
extern PyObject *gdbpy_value_cst;

/* Exception types.  */
extern PyObject *gdbpy_gdb_error;
extern PyObject *gdbpy_gdb_memory_error;
extern PyObject *gdbpy_gdberror_exc;

extern void gdbpy_convert_exception (const struct gdb_exception &);

 /* Use this in a 'catch' block to convert the exception E to a Python
    exception and return value VAL to signal that an exception occurred.
    Typically at the use site, that value will be returned immediately.  */

template<typename T>
[[nodiscard]] T
gdbpy_handle_gdb_exception (T val, const gdb_exception &e)
{
  gdbpy_convert_exception (e);
  return val;
}

int get_addr_from_python (PyObject *obj, CORE_ADDR *addr);

gdbpy_ref<> gdb_py_object_from_longest (LONGEST l);
gdbpy_ref<> gdb_py_object_from_ulongest (ULONGEST l);
int gdb_py_int_as_long (PyObject *, long *);

PyObject *gdb_py_generic_dict_getter (PyObject *self, void *closure);
PyObject *gdb_py_generic_getattro (PyObject *self, PyObject *attr);
int gdb_py_generic_setattro (PyObject *self, PyObject *attr, PyObject *value);

int gdb_pymodule_addobject (PyObject *mod, const char *name,
			    PyObject *object);


/* Return a Python string (str) object that represents SELF.  SELF can be
   any object type, but should be in an "invalid" state.  What "invalid"
   means is up to the caller.  The returned string will take the form
   "<TYPENAME (invalid)>", without the quotes, and with TYPENAME replaced
   with the type of SELF.  */

PyObject *gdb_py_invalid_object_repr (PyObject *self);

struct varobj_iter;
struct varobj;
std::unique_ptr<varobj_iter> py_varobj_get_iterator
     (struct varobj *var,
      PyObject *printer,
      const value_print_options *opts);

/* Deleter for Py_buffer unique_ptr specialization.  */

struct Py_buffer_deleter
{
  void operator() (Py_buffer *b) const
  {
    PyBuffer_Release (b);
  }
};

/* A unique_ptr specialization for Py_buffer.  */
typedef std::unique_ptr<Py_buffer, Py_buffer_deleter> Py_buffer_up;

/* Parse a register number from PYO_REG_ID and place the register number
   into *REG_NUM.  The register is a register for GDBARCH.

   If a register is parsed successfully then *REG_NUM will have been
   updated, and true is returned.  Otherwise the contents of *REG_NUM are
   undefined, and false is returned.  When false is returned, the
   Python error is set.

   The PYO_REG_ID object can be a string, the name of the register.  This
   is the slowest approach as GDB has to map the name to a number for each
   call.  Alternatively PYO_REG_ID can be an internal GDB register
   number.  This is quick but should not be encouraged as this means
   Python scripts are now dependent on GDB's internal register numbering.
   Final PYO_REG_ID can be a gdb.RegisterDescriptor object, these objects
   can be looked up by name once, and then cache the register number so
   should be as quick as using a register number.  */

extern bool gdbpy_parse_register_id (struct gdbarch *gdbarch,
				     PyObject *pyo_reg_id, int *reg_num);

/* Return true if OBJ is a gdb.Architecture object, otherwise, return
   false.  */

extern bool gdbpy_is_architecture (PyObject *obj);

/* Return true if OBJ is a gdb.Progspace object, otherwise, return false.  */

extern bool gdbpy_is_progspace (PyObject *obj);

/* Take DOC, the documentation string for a GDB command defined in Python,
   and return an (possibly) modified version of that same string.

   When a command is defined in Python, the documentation string will
   usually be indented based on the indentation of the surrounding Python
   code.  However, the documentation string is a literal string, all the
   white-space added for indentation is included within the documentation
   string.

   This indentation is then included in the help text that GDB displays,
   which looks odd out of the context of the original Python source code.

   This function analyses DOC and tries to figure out what white-space
   within DOC was added as part of the indentation, and then removes that
   white-space from the copy that is returned.

   If the analysis of DOC fails then DOC will be returned unmodified.  */

extern gdb::unique_xmalloc_ptr<char> gdbpy_fix_doc_string_indentation
  (gdb::unique_xmalloc_ptr<char> doc);

/* Implement the 'print_insn' hook for Python.  Disassemble an instruction
   whose address is ADDRESS for architecture GDBARCH.  The bytes of the
   instruction should be read with INFO->read_memory_func as the
   instruction being disassembled might actually be in a buffer.

   Used INFO->fprintf_func to print the results of the disassembly, and
   return the length of the instruction in octets.

   If no instruction can be disassembled then return an empty value.  */

extern std::optional<int> gdbpy_print_insn (struct gdbarch *gdbarch,
					    CORE_ADDR address,
					    disassemble_info *info);

/* Return the gdb.Corefile object representing the core file loaded into
   the program space of INF, or None if there is no core file loaded.  INF
   must not be NULL.  If an error occurs then NULL is returned, and a
   suitable Python error will be set.  */

extern gdbpy_ref<> gdbpy_core_file_from_inferior (inferior *inf);


/* A wrapper for PyType_Ready that also automatically registers the
   type in the appropriate module.  Returns 0 on success, -1 on error.
   If MOD is supplied, then the type is added to that module.  If MOD
   is not supplied, the type name (tp_name field) must be of the form
   "gdb.Mumble", and the type will be added to the gdb module.  */

static inline int
gdbpy_type_ready (PyTypeObject *type, PyObject *mod = nullptr)
{
  if (PyType_Ready (type) < 0)
    return -1;
  if (mod == nullptr)
    {
      gdb_assert (startswith (type->tp_name, "gdb."));
      mod = gdb_module;
    }
  const char *dot = strrchr (type->tp_name, '.');
  gdb_assert (dot != nullptr);
  return gdb_pymodule_addobject (mod, dot + 1, (PyObject *) type);
}

/* Poison PyType_Ready.  Only gdbpy_type_ready should be used, to
   avoid forgetting to register the type.  See PR python/32163.  */
#undef PyType_Ready
#ifdef __GNUC__
# pragma GCC poison PyType_Ready
#else
# define PyType_Ready POISONED_PyType_Ready
#endif

/* A class to manage lifecycle of Python objects for objects that are "owned"
   by an objfile or a gdbarch.  It keeps track of Python objects and when
   the "owning" object (objfile or gdbarch) is about to be freed, ensures that
   all Python objects "owned" by that object are properly invalidated.

   The actual tracking of "owned" Python objects is handled externally
   by storage class.  Storage object is created for each owning object
   on demand and it is deleted when owning object is about to be freed.

   The storage class must provide two member types:

     * obj_type - the type of Python object whose lifecycle is managed.
     * val_type - the type of GDB structure the Python objects are
       representing.

   It must also provide following methods:

     void add (obj_type *obj);
     void remove (obj_type *obj);

   Memoizing storage must in addition to method above provide:

     obj_type *lookup (val_type *val);

   Finally it must invalidate all registered Python objects upon deletion.  */
template <typename Storage>
class gdbpy_registry
{
public:
  using obj_type = typename Storage::obj_type;
  using val_type = typename Storage::val_type;

  static_assert(std::is_base_of<PyObject, obj_type>::value,
		"obj_type must be a subclass of PyObject");

  /* Register Python object OBJ as being "owned" by OWNER.  When OWNER is
     about to be freed, OBJ will be invalidated.  */
  template <typename O>
  void add (O *owner, obj_type *obj) const
  {
    get_storage (owner)->add (obj);
  }

  /* Unregister Python object OBJ.  OBJ will no longer be invalidated when
     OWNER is about to be be freed.  */
  template <typename O>
  void remove (O *owner, obj_type *obj) const
  {
    get_storage (owner)->remove (obj);
  }

  /* Lookup pre-existing Python object for given VAL.  Return such object
     if found, otherwise return NULL.  */
  template <typename O>
  gdbpy_ref<> lookup (O *owner, val_type *val) const
  {
    obj_type *obj = get_storage (owner)->lookup (val);
    Py_XINCREF (static_cast<PyObject *> (obj));
    return gdbpy_ref<> (obj);
  }

private:

  template<typename O>
  using StorageKey = typename registry<O>::template key<Storage>;

  template<typename O>
  Storage *get_storage (O *owner, const StorageKey<O> &key) const
  {
    return &key.try_emplace (owner);
  }

  Storage *get_storage (struct objfile* objf) const
  {
    return get_storage (objf, m_key_for_objf);
  }

  Storage *get_storage (struct gdbarch* arch) const
  {
    return get_storage (arch, m_key_for_arch);
  }

  const registry<objfile>::key<Storage> m_key_for_objf;
  const registry<gdbarch>::key<Storage> m_key_for_arch;
};

/* Default invalidator for Python objects.  */
template <typename P, typename V, V* P::*val_slot>
struct gdbpy_default_invalidator
{
  void operator() (P *obj)
  {
    obj->*val_slot = nullptr;
  }
};

/* A "storage" implementation suitable for temporary (on-demand) objects.  */
template <typename P,
	  typename V,
	  V* P::*val_slot,
	  typename Invalidator = gdbpy_default_invalidator<P, V, val_slot>>
class gdbpy_tracking_registry_storage
{
public:
  using obj_type = P;
  using val_type = V;

  void add (obj_type *obj)
  {
    gdb_assert (obj != nullptr && obj->*val_slot != nullptr);

    m_objects.insert (obj);
  }

  void remove (obj_type *obj)
  {
    gdb_assert (obj != nullptr && obj->*val_slot != nullptr);
    gdb_assert (m_objects.contains (obj));

    m_objects.erase (obj);
  }

  ~gdbpy_tracking_registry_storage ()
  {
    Invalidator invalidate;
    gdbpy_enter enter_py;

    for (auto each : m_objects)
      invalidate (each);
    m_objects.clear ();
  }

protected:
  gdb::unordered_set<obj_type *> m_objects;
};

/* A "storage" implementation suitable for memoized (interned) Python objects.

   Python objects are memoized (interned) temporarily, meaning that when user
   drops all their references the Python object is deallocated and removed
   from storage.
   */
template <typename P,
	  typename V,
	  V* P::*val_slot,
	  typename Invalidator = gdbpy_default_invalidator<P, V, val_slot>>
class gdbpy_memoizing_registry_storage
{
public:
  using obj_type = P;
  using val_type = V;

  void add (obj_type *obj)
  {
    gdb_assert (obj != nullptr && obj->*val_slot != nullptr);

    m_objects[obj->*val_slot] = obj;
  }

  void remove (obj_type *obj)
  {
    gdb_assert (obj != nullptr && obj->*val_slot != nullptr);
    gdb_assert (m_objects.contains (obj->*val_slot));

    m_objects.erase (obj->*val_slot);
  }

  obj_type *lookup (val_type *val) const
  {
    auto result = m_objects.find (val);
    if (result != m_objects.end ())
      return result->second;
    else
      return nullptr;
  }

  ~gdbpy_memoizing_registry_storage ()
  {
    Invalidator invalidate;
    gdbpy_enter enter_py;

    for (auto each : m_objects)
      invalidate (each.second);
    m_objects.clear ();
  }

protected:
  gdb::unordered_map<val_type *, obj_type *> m_objects;
};

extern int eval_python_command (const char *command, int start_symbol,
				const char *filename = nullptr);

#endif /* GDB_PYTHON_PYTHON_INTERNAL_H */
