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