1//===-- ScriptInterpreterPython.h -------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
10#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
11
12#include <optional>
13#include <string>
14
15#include "lldb/Host/Config.h"
16
17#if LLDB_ENABLE_PYTHON
18
19// LLDB Python header must be included first
20#include "lldb-python.h"
21
22#include "Plugins/ScriptInterpreter/Python/PythonDataObjects.h"
23#include "lldb/lldb-forward.h"
24#include "lldb/lldb-types.h"
25#include "llvm/Support/Error.h"
26
27namespace lldb {
28class SBEvent;
29class SBCommandReturnObject;
30class SBValue;
31class SBStream;
32class SBStructuredData;
33class SBFileSpec;
34class SBModuleSpec;
35class SBStringList;
36} // namespace lldb
37
38namespace lldb_private {
39namespace python {
40
41typedef struct swig_type_info swig_type_info;
42
43python::PythonObject ToSWIGHelper(void *obj, swig_type_info *info);
44
45/// A class that automatically clears an SB object when it goes out of scope.
46/// Use for cases where the SB object points to a temporary/unowned entity.
47template <typename T> class ScopedPythonObject : PythonObject {
48public:
49 ScopedPythonObject(T *sb, swig_type_info *info)
50 : PythonObject(ToSWIGHelper(sb, info)), m_sb(sb) {}
51 ~ScopedPythonObject() {
52 if (m_sb)
53 *m_sb = T();
54 }
55 ScopedPythonObject(ScopedPythonObject &&rhs)
56 : PythonObject(std::move(rhs)), m_sb(std::exchange(rhs.m_sb, nullptr)) {}
57 ScopedPythonObject(const ScopedPythonObject &) = delete;
58 ScopedPythonObject &operator=(const ScopedPythonObject &) = delete;
59 ScopedPythonObject &operator=(ScopedPythonObject &&) = delete;
60
61 const PythonObject &obj() const { return *this; }
62
63private:
64 T *m_sb;
65};
66
67// TODO: We may want to support other languages in the future w/ SWIG (we
68// already support Lua right now, for example). We could create a generic
69// SWIGBridge class and have this one specialize it, something like this:
70//
71// <typename T>
72// class SWIGBridge {
73// static T ToSWIGWrapper(...);
74// };
75//
76// class SWIGPythonBridge : public SWIGBridge<PythonObject> {
77// template<> static PythonObject ToSWIGWrapper(...);
78// };
79//
80// And we should be able to more easily support things like Lua
81class SWIGBridge {
82public:
83 static PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb);
84 static PythonObject ToSWIGWrapper(lldb::ValueObjectSP value_sp);
85 static PythonObject ToSWIGWrapper(lldb::TargetSP target_sp);
86 static PythonObject ToSWIGWrapper(lldb::ProcessSP process_sp);
87 static PythonObject ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp);
88 static PythonObject ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp);
89 static PythonObject ToSWIGWrapper(const Status &status);
90 static PythonObject ToSWIGWrapper(const StructuredDataImpl &data_impl);
91 static PythonObject ToSWIGWrapper(lldb::ThreadSP thread_sp);
92 static PythonObject ToSWIGWrapper(lldb::StackFrameSP frame_sp);
93 static PythonObject ToSWIGWrapper(lldb::DebuggerSP debugger_sp);
94 static PythonObject ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp);
95 static PythonObject ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp);
96 static PythonObject ToSWIGWrapper(lldb::TypeImplSP type_impl_sp);
97 static PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp);
98 static PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options);
99 static PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx);
100
101 static PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp);
102 static PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp);
103 static PythonObject ToSWIGWrapper(lldb::DataExtractorSP data_extractor_sp);
104
105 static PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBStream> stream_sb);
106 static PythonObject
107 ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb);
108 static PythonObject
109 ToSWIGWrapper(std::unique_ptr<lldb::SBFileSpec> file_spec_sb);
110 static PythonObject
111 ToSWIGWrapper(std::unique_ptr<lldb::SBModuleSpec> module_spec_sb);
112
113 static python::ScopedPythonObject<lldb::SBCommandReturnObject>
114 ToSWIGWrapper(CommandReturnObject &cmd_retobj);
115 static python::ScopedPythonObject<lldb::SBEvent> ToSWIGWrapper(Event *event);
116 // These prototypes are the Pythonic implementations of the required
117 // callbacks. Although these are scripting-language specific, their definition
118 // depends on the public API.
119
120 static llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction(
121 const char *python_function_name, const char *session_dictionary_name,
122 const lldb::StackFrameSP &sb_frame,
123 const lldb::BreakpointLocationSP &sb_bp_loc,
124 const lldb_private::StructuredDataImpl &args_impl);
125
126 static bool LLDBSwigPythonWatchpointCallbackFunction(
127 const char *python_function_name, const char *session_dictionary_name,
128 const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp);
129
130 static bool
131 LLDBSwigPythonFormatterCallbackFunction(const char *python_function_name,
132 const char *session_dictionary_name,
133 lldb::TypeImplSP type_impl_sp);
134
135 static bool LLDBSwigPythonCallTypeScript(
136 const char *python_function_name, const void *session_dictionary,
137 const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper,
138 const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval);
139
140 static python::PythonObject
141 LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name,
142 const char *session_dictionary_name,
143 const lldb::ValueObjectSP &valobj_sp);
144
145 static python::PythonObject
146 LLDBSwigPythonCreateCommandObject(const char *python_class_name,
147 const char *session_dictionary_name,
148 lldb::DebuggerSP debugger_sp);
149
150 static python::PythonObject LLDBSwigPythonCreateScriptedThreadPlan(
151 const char *python_class_name, const char *session_dictionary_name,
152 const StructuredDataImpl &args_data, std::string &error_string,
153 const lldb::ThreadPlanSP &thread_plan_sp);
154
155 static bool LLDBSWIGPythonCallThreadPlan(void *implementor,
156 const char *method_name,
157 lldb_private::Event *event_sp,
158 bool &got_error);
159
160 static bool LLDBSWIGPythonCallThreadPlan(void *implementor,
161 const char *method_name,
162 lldb_private::Stream *stream,
163 bool &got_error);
164
165 static python::PythonObject LLDBSwigPythonCreateScriptedBreakpointResolver(
166 const char *python_class_name, const char *session_dictionary_name,
167 const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp);
168
169 static unsigned int
170 LLDBSwigPythonCallBreakpointResolver(void *implementor,
171 const char *method_name,
172 lldb_private::SymbolContext *sym_ctx);
173
174 static python::PythonObject LLDBSwigPythonCreateScriptedStopHook(
175 lldb::TargetSP target_sp, const char *python_class_name,
176 const char *session_dictionary_name, const StructuredDataImpl &args,
177 lldb_private::Status &error);
178
179 static bool
180 LLDBSwigPythonStopHookCallHandleStop(void *implementor,
181 lldb::ExecutionContextRefSP exc_ctx,
182 lldb::StreamSP stream);
183
184 static size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor,
185 uint32_t max);
186
187 static PyObject *LLDBSwigPython_GetChildAtIndex(PyObject *implementor,
188 uint32_t idx);
189
190 static int LLDBSwigPython_GetIndexOfChildWithName(PyObject *implementor,
191 const char *child_name);
192
193 static lldb::ValueObjectSP
194 LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data);
195
196 static bool LLDBSwigPython_UpdateSynthProviderInstance(PyObject *implementor);
197
198 static bool
199 LLDBSwigPython_MightHaveChildrenSynthProviderInstance(PyObject *implementor);
200
201 static PyObject *
202 LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor);
203
204 static bool
205 LLDBSwigPythonCallCommand(const char *python_function_name,
206 const char *session_dictionary_name,
207 lldb::DebuggerSP debugger, const char *args,
208 lldb_private::CommandReturnObject &cmd_retobj,
209 lldb::ExecutionContextRefSP exe_ctx_ref_sp);
210
211 static bool
212 LLDBSwigPythonCallCommandObject(PyObject *implementor,
213 lldb::DebuggerSP debugger, const char *args,
214 lldb_private::CommandReturnObject &cmd_retobj,
215 lldb::ExecutionContextRefSP exe_ctx_ref_sp);
216 static bool
217 LLDBSwigPythonCallParsedCommandObject(PyObject *implementor,
218 lldb::DebuggerSP debugger,
219 StructuredDataImpl &args_impl,
220 lldb_private::CommandReturnObject &cmd_retobj,
221 lldb::ExecutionContextRefSP exe_ctx_ref_sp);
222
223 static bool LLDBSwigPythonCallModuleInit(const char *python_module_name,
224 const char *session_dictionary_name,
225 lldb::DebuggerSP debugger);
226
227 static python::PythonObject
228 LLDBSWIGPythonCreateOSPlugin(const char *python_class_name,
229 const char *session_dictionary_name,
230 const lldb::ProcessSP &process_sp);
231
232 static python::PythonObject
233 LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name,
234 const char *session_dictionary_name);
235
236 static PyObject *
237 LLDBSwigPython_GetRecognizedArguments(PyObject *implementor,
238 const lldb::StackFrameSP &frame_sp);
239
240 static bool LLDBSWIGPythonRunScriptKeywordProcess(
241 const char *python_function_name, const char *session_dictionary_name,
242 const lldb::ProcessSP &process, std::string &output);
243
244 static std::optional<std::string>
245 LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name,
246 const char *session_dictionary_name,
247 lldb::ThreadSP thread);
248
249 static bool LLDBSWIGPythonRunScriptKeywordTarget(
250 const char *python_function_name, const char *session_dictionary_name,
251 const lldb::TargetSP &target, std::string &output);
252
253 static std::optional<std::string>
254 LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name,
255 const char *session_dictionary_name,
256 lldb::StackFrameSP frame);
257
258 static bool LLDBSWIGPythonRunScriptKeywordValue(
259 const char *python_function_name, const char *session_dictionary_name,
260 const lldb::ValueObjectSP &value, std::string &output);
261
262 static void *
263 LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting,
264 const lldb::TargetSP &target_sp);
265};
266
267void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data);
268void *LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *data);
269void *LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data);
270void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data);
271void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data);
272void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data);
273void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data);
274} // namespace python
275
276} // namespace lldb_private
277
278#endif // LLDB_ENABLE_PYTHON
279#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_SWIGPYTHONBRIDGE_H
280

source code of lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h