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