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