1 //===-- BreakpointResolverScripted.cpp ------------------------------------===// 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 #include "lldb/Breakpoint/BreakpointResolverScripted.h" 10 11 12 #include "lldb/Breakpoint/BreakpointLocation.h" 13 #include "lldb/Core/Debugger.h" 14 #include "lldb/Core/Module.h" 15 #include "lldb/Core/Section.h" 16 #include "lldb/Core/StructuredDataImpl.h" 17 #include "lldb/Interpreter/CommandInterpreter.h" 18 #include "lldb/Interpreter/ScriptInterpreter.h" 19 #include "lldb/Target/Process.h" 20 #include "lldb/Target/Target.h" 21 #include "lldb/Utility/Log.h" 22 #include "lldb/Utility/StreamString.h" 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 // BreakpointResolverScripted: 28 BreakpointResolverScripted::BreakpointResolverScripted( 29 const BreakpointSP &bkpt, const llvm::StringRef class_name, 30 lldb::SearchDepth depth, const StructuredDataImpl &args_data) 31 : BreakpointResolver(bkpt, BreakpointResolver::PythonResolver), 32 m_class_name(std::string(class_name)), m_depth(depth), m_args(args_data) { 33 CreateImplementationIfNeeded(bkpt); 34 } 35 36 void BreakpointResolverScripted::CreateImplementationIfNeeded( 37 BreakpointSP breakpoint_sp) { 38 if (m_implementation_sp) 39 return; 40 41 if (m_class_name.empty()) 42 return; 43 44 if (!breakpoint_sp) 45 return; 46 47 TargetSP target_sp = breakpoint_sp->GetTargetSP(); 48 ScriptInterpreter *script_interp = target_sp->GetDebugger() 49 .GetScriptInterpreter(); 50 if (!script_interp) 51 return; 52 53 m_implementation_sp = script_interp->CreateScriptedBreakpointResolver( 54 m_class_name.c_str(), m_args, breakpoint_sp); 55 } 56 57 void BreakpointResolverScripted::NotifyBreakpointSet() { 58 CreateImplementationIfNeeded(GetBreakpoint()); 59 } 60 61 BreakpointResolver * 62 BreakpointResolverScripted::CreateFromStructuredData( 63 const BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict, 64 Status &error) { 65 llvm::StringRef class_name; 66 bool success; 67 68 success = options_dict.GetValueForKeyAsString( 69 GetKey(OptionNames::PythonClassName), class_name); 70 if (!success) { 71 error.SetErrorString("BRFL::CFSD: Couldn't find class name entry."); 72 return nullptr; 73 } 74 // The Python function will actually provide the search depth, this is a 75 // placeholder. 76 lldb::SearchDepth depth = lldb::eSearchDepthTarget; 77 78 StructuredDataImpl args_data_impl; 79 StructuredData::Dictionary *args_dict = nullptr; 80 if (options_dict.GetValueForKeyAsDictionary(GetKey(OptionNames::ScriptArgs), 81 args_dict)) 82 args_data_impl.SetObjectSP(args_dict->shared_from_this()); 83 return new BreakpointResolverScripted(bkpt, class_name, depth, 84 args_data_impl); 85 } 86 87 StructuredData::ObjectSP 88 BreakpointResolverScripted::SerializeToStructuredData() { 89 StructuredData::DictionarySP options_dict_sp( 90 new StructuredData::Dictionary()); 91 92 options_dict_sp->AddStringItem(GetKey(OptionNames::PythonClassName), 93 m_class_name); 94 if (m_args.IsValid()) 95 options_dict_sp->AddItem(GetKey(OptionNames::ScriptArgs), 96 m_args.GetObjectSP()); 97 98 return WrapOptionsDict(options_dict_sp); 99 } 100 101 ScriptInterpreter *BreakpointResolverScripted::GetScriptInterpreter() { 102 return GetBreakpoint()->GetTarget().GetDebugger().GetScriptInterpreter(); 103 } 104 105 Searcher::CallbackReturn BreakpointResolverScripted::SearchCallback( 106 SearchFilter &filter, SymbolContext &context, Address *addr) { 107 bool should_continue = true; 108 if (!m_implementation_sp) 109 return Searcher::eCallbackReturnStop; 110 111 ScriptInterpreter *interp = GetScriptInterpreter(); 112 should_continue = interp->ScriptedBreakpointResolverSearchCallback( 113 m_implementation_sp, 114 &context); 115 if (should_continue) 116 return Searcher::eCallbackReturnContinue; 117 118 return Searcher::eCallbackReturnStop; 119 } 120 121 lldb::SearchDepth 122 BreakpointResolverScripted::GetDepth() { 123 lldb::SearchDepth depth = lldb::eSearchDepthModule; 124 if (m_implementation_sp) { 125 ScriptInterpreter *interp = GetScriptInterpreter(); 126 depth = interp->ScriptedBreakpointResolverSearchDepth( 127 m_implementation_sp); 128 } 129 return depth; 130 } 131 132 void BreakpointResolverScripted::GetDescription(Stream *s) { 133 StructuredData::GenericSP generic_sp; 134 std::string short_help; 135 136 if (m_implementation_sp) { 137 ScriptInterpreter *interp = GetScriptInterpreter(); 138 interp->GetShortHelpForCommandObject(m_implementation_sp, 139 short_help); 140 } 141 if (!short_help.empty()) 142 s->PutCString(short_help.c_str()); 143 else 144 s->Printf("python class = %s", m_class_name.c_str()); 145 } 146 147 void BreakpointResolverScripted::Dump(Stream *s) const {} 148 149 lldb::BreakpointResolverSP 150 BreakpointResolverScripted::CopyForBreakpoint(BreakpointSP &breakpoint) { 151 return std::make_shared<BreakpointResolverScripted>(breakpoint, m_class_name, 152 m_depth, m_args); 153 } 154