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 BreakpointResolverSP BreakpointResolverScripted::CreateFromStructuredData( 62 const StructuredData::Dictionary &options_dict, Status &error) { 63 llvm::StringRef class_name; 64 bool success; 65 66 success = options_dict.GetValueForKeyAsString( 67 GetKey(OptionNames::PythonClassName), class_name); 68 if (!success) { 69 error.SetErrorString("BRFL::CFSD: Couldn't find class name entry."); 70 return nullptr; 71 } 72 // The Python function will actually provide the search depth, this is a 73 // placeholder. 74 lldb::SearchDepth depth = lldb::eSearchDepthTarget; 75 76 StructuredDataImpl args_data_impl; 77 StructuredData::Dictionary *args_dict = nullptr; 78 if (options_dict.GetValueForKeyAsDictionary(GetKey(OptionNames::ScriptArgs), 79 args_dict)) 80 args_data_impl.SetObjectSP(args_dict->shared_from_this()); 81 return std::make_shared<BreakpointResolverScripted>(nullptr, class_name, 82 depth, args_data_impl); 83 } 84 85 StructuredData::ObjectSP 86 BreakpointResolverScripted::SerializeToStructuredData() { 87 StructuredData::DictionarySP options_dict_sp( 88 new StructuredData::Dictionary()); 89 90 options_dict_sp->AddStringItem(GetKey(OptionNames::PythonClassName), 91 m_class_name); 92 if (m_args.IsValid()) 93 options_dict_sp->AddItem(GetKey(OptionNames::ScriptArgs), 94 m_args.GetObjectSP()); 95 96 return WrapOptionsDict(options_dict_sp); 97 } 98 99 ScriptInterpreter *BreakpointResolverScripted::GetScriptInterpreter() { 100 return GetBreakpoint()->GetTarget().GetDebugger().GetScriptInterpreter(); 101 } 102 103 Searcher::CallbackReturn BreakpointResolverScripted::SearchCallback( 104 SearchFilter &filter, SymbolContext &context, Address *addr) { 105 bool should_continue = true; 106 if (!m_implementation_sp) 107 return Searcher::eCallbackReturnStop; 108 109 ScriptInterpreter *interp = GetScriptInterpreter(); 110 should_continue = interp->ScriptedBreakpointResolverSearchCallback( 111 m_implementation_sp, 112 &context); 113 if (should_continue) 114 return Searcher::eCallbackReturnContinue; 115 116 return Searcher::eCallbackReturnStop; 117 } 118 119 lldb::SearchDepth 120 BreakpointResolverScripted::GetDepth() { 121 lldb::SearchDepth depth = lldb::eSearchDepthModule; 122 if (m_implementation_sp) { 123 ScriptInterpreter *interp = GetScriptInterpreter(); 124 depth = interp->ScriptedBreakpointResolverSearchDepth( 125 m_implementation_sp); 126 } 127 return depth; 128 } 129 130 void BreakpointResolverScripted::GetDescription(Stream *s) { 131 StructuredData::GenericSP generic_sp; 132 std::string short_help; 133 134 if (m_implementation_sp) { 135 ScriptInterpreter *interp = GetScriptInterpreter(); 136 interp->GetShortHelpForCommandObject(m_implementation_sp, 137 short_help); 138 } 139 if (!short_help.empty()) 140 s->PutCString(short_help.c_str()); 141 else 142 s->Printf("python class = %s", m_class_name.c_str()); 143 } 144 145 void BreakpointResolverScripted::Dump(Stream *s) const {} 146 147 lldb::BreakpointResolverSP 148 BreakpointResolverScripted::CopyForBreakpoint(BreakpointSP &breakpoint) { 149 return std::make_shared<BreakpointResolverScripted>(breakpoint, m_class_name, 150 m_depth, m_args); 151 } 152