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