/* 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"
#include "py-obj-type.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.

     The GIL will be held while calling the finalizers.  */

  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;
  const char *tp_name = gdb_py_tp_name (type);
  if (mod == nullptr)
    {
      gdb_assert (startswith (tp_name, "gdb."));
      mod = gdb_module;
    }
  const char *dot = strrchr (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 */
