180814287SRaphael Isemann //===-- BreakpointResolverScripted.cpp ------------------------------------===// 2e19adf54SJim Ingham // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e19adf54SJim Ingham // 7e19adf54SJim Ingham //===----------------------------------------------------------------------===// 8e19adf54SJim Ingham 9e19adf54SJim Ingham #include "lldb/Breakpoint/BreakpointResolverScripted.h" 10e19adf54SJim Ingham 11e19adf54SJim Ingham 12e19adf54SJim Ingham #include "lldb/Breakpoint/BreakpointLocation.h" 13e19adf54SJim Ingham #include "lldb/Core/Debugger.h" 14e19adf54SJim Ingham #include "lldb/Core/Module.h" 15e19adf54SJim Ingham #include "lldb/Core/Section.h" 16e19adf54SJim Ingham #include "lldb/Core/StructuredDataImpl.h" 17e19adf54SJim Ingham #include "lldb/Interpreter/CommandInterpreter.h" 18e19adf54SJim Ingham #include "lldb/Interpreter/ScriptInterpreter.h" 19e19adf54SJim Ingham #include "lldb/Target/Process.h" 20e19adf54SJim Ingham #include "lldb/Target/Target.h" 21e19adf54SJim Ingham #include "lldb/Utility/Log.h" 22e19adf54SJim Ingham #include "lldb/Utility/StreamString.h" 23e19adf54SJim Ingham 24e19adf54SJim Ingham using namespace lldb; 25e19adf54SJim Ingham using namespace lldb_private; 26e19adf54SJim Ingham 27e19adf54SJim Ingham // BreakpointResolverScripted: 28e19adf54SJim Ingham BreakpointResolverScripted::BreakpointResolverScripted( 29*6c17cc53STatyana Krasnukha const BreakpointSP &bkpt, const llvm::StringRef class_name, 30*6c17cc53STatyana Krasnukha lldb::SearchDepth depth, StructuredDataImpl *args_data) 31e19adf54SJim Ingham : BreakpointResolver(bkpt, BreakpointResolver::PythonResolver), 32adcd0268SBenjamin Kramer m_class_name(std::string(class_name)), m_depth(depth), 33adcd0268SBenjamin Kramer m_args_ptr(args_data) { 34*6c17cc53STatyana Krasnukha CreateImplementationIfNeeded(bkpt); 35e19adf54SJim Ingham } 36e19adf54SJim Ingham 37*6c17cc53STatyana Krasnukha void BreakpointResolverScripted::CreateImplementationIfNeeded( 38*6c17cc53STatyana Krasnukha BreakpointSP breakpoint_sp) { 39e19adf54SJim Ingham if (m_implementation_sp) 40e19adf54SJim Ingham return; 41e19adf54SJim Ingham 42e19adf54SJim Ingham if (m_class_name.empty()) 43e19adf54SJim Ingham return; 44e19adf54SJim Ingham 45*6c17cc53STatyana Krasnukha if (!breakpoint_sp) 46*6c17cc53STatyana Krasnukha return; 47*6c17cc53STatyana Krasnukha 48*6c17cc53STatyana Krasnukha TargetSP target_sp = breakpoint_sp->GetTargetSP(); 49e19adf54SJim Ingham ScriptInterpreter *script_interp = target_sp->GetDebugger() 50e19adf54SJim Ingham .GetScriptInterpreter(); 51e19adf54SJim Ingham if (!script_interp) 52e19adf54SJim Ingham return; 53*6c17cc53STatyana Krasnukha 54e19adf54SJim Ingham m_implementation_sp = script_interp->CreateScriptedBreakpointResolver( 55*6c17cc53STatyana Krasnukha m_class_name.c_str(), m_args_ptr, breakpoint_sp); 56e19adf54SJim Ingham } 57e19adf54SJim Ingham 58e19adf54SJim Ingham void BreakpointResolverScripted::NotifyBreakpointSet() { 59*6c17cc53STatyana Krasnukha CreateImplementationIfNeeded(GetBreakpoint()); 60e19adf54SJim Ingham } 61e19adf54SJim Ingham 62e19adf54SJim Ingham BreakpointResolver * 63e19adf54SJim Ingham BreakpointResolverScripted::CreateFromStructuredData( 64*6c17cc53STatyana Krasnukha const BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict, 65e19adf54SJim Ingham Status &error) { 66e19adf54SJim Ingham llvm::StringRef class_name; 67e19adf54SJim Ingham bool success; 68e19adf54SJim Ingham 69e19adf54SJim Ingham success = options_dict.GetValueForKeyAsString( 70e19adf54SJim Ingham GetKey(OptionNames::PythonClassName), class_name); 71e19adf54SJim Ingham if (!success) { 72e19adf54SJim Ingham error.SetErrorString("BRFL::CFSD: Couldn't find class name entry."); 73e19adf54SJim Ingham return nullptr; 74e19adf54SJim Ingham } 7547b33dccSJim Ingham // The Python function will actually provide the search depth, this is a 7647b33dccSJim Ingham // placeholder. 7747b33dccSJim Ingham lldb::SearchDepth depth = lldb::eSearchDepthTarget; 78e19adf54SJim Ingham 79e19adf54SJim Ingham StructuredDataImpl *args_data_impl = new StructuredDataImpl(); 806d7fb299SKonrad Kleine StructuredData::Dictionary *args_dict = nullptr; 81e19adf54SJim Ingham success = options_dict.GetValueForKeyAsDictionary( 82e19adf54SJim Ingham GetKey(OptionNames::ScriptArgs), args_dict); 83e19adf54SJim Ingham if (success) { 8447b33dccSJim Ingham args_data_impl->SetObjectSP(args_dict->shared_from_this()); 85e19adf54SJim Ingham } 8647b33dccSJim Ingham return new BreakpointResolverScripted(bkpt, class_name, depth, 8747b33dccSJim Ingham args_data_impl); 88e19adf54SJim Ingham } 89e19adf54SJim Ingham 90e19adf54SJim Ingham StructuredData::ObjectSP 91e19adf54SJim Ingham BreakpointResolverScripted::SerializeToStructuredData() { 92e19adf54SJim Ingham StructuredData::DictionarySP options_dict_sp( 93e19adf54SJim Ingham new StructuredData::Dictionary()); 94e19adf54SJim Ingham 95e19adf54SJim Ingham options_dict_sp->AddStringItem(GetKey(OptionNames::PythonClassName), 96e19adf54SJim Ingham m_class_name); 9747b33dccSJim Ingham if (m_args_ptr->IsValid()) 9847b33dccSJim Ingham options_dict_sp->AddItem(GetKey(OptionNames::ScriptArgs), 9947b33dccSJim Ingham m_args_ptr->GetObjectSP()); 10047b33dccSJim Ingham 101e19adf54SJim Ingham return WrapOptionsDict(options_dict_sp); 102e19adf54SJim Ingham } 103e19adf54SJim Ingham 104e19adf54SJim Ingham ScriptInterpreter *BreakpointResolverScripted::GetScriptInterpreter() { 105*6c17cc53STatyana Krasnukha return GetBreakpoint()->GetTarget().GetDebugger().GetScriptInterpreter(); 106e19adf54SJim Ingham } 107e19adf54SJim Ingham 10895e264fcSRaphael Isemann Searcher::CallbackReturn BreakpointResolverScripted::SearchCallback( 10995e264fcSRaphael Isemann SearchFilter &filter, SymbolContext &context, Address *addr) { 110e19adf54SJim Ingham bool should_continue = true; 111e19adf54SJim Ingham if (!m_implementation_sp) 112e19adf54SJim Ingham return Searcher::eCallbackReturnStop; 113e19adf54SJim Ingham 114e19adf54SJim Ingham ScriptInterpreter *interp = GetScriptInterpreter(); 115e19adf54SJim Ingham should_continue = interp->ScriptedBreakpointResolverSearchCallback( 116e19adf54SJim Ingham m_implementation_sp, 117e19adf54SJim Ingham &context); 118e19adf54SJim Ingham if (should_continue) 119e19adf54SJim Ingham return Searcher::eCallbackReturnContinue; 120*6c17cc53STatyana Krasnukha 121e19adf54SJim Ingham return Searcher::eCallbackReturnStop; 122e19adf54SJim Ingham } 123e19adf54SJim Ingham 124e19adf54SJim Ingham lldb::SearchDepth 125e19adf54SJim Ingham BreakpointResolverScripted::GetDepth() { 126e19adf54SJim Ingham lldb::SearchDepth depth = lldb::eSearchDepthModule; 127e19adf54SJim Ingham if (m_implementation_sp) { 128e19adf54SJim Ingham ScriptInterpreter *interp = GetScriptInterpreter(); 129e19adf54SJim Ingham depth = interp->ScriptedBreakpointResolverSearchDepth( 130e19adf54SJim Ingham m_implementation_sp); 131e19adf54SJim Ingham } 132e19adf54SJim Ingham return depth; 133e19adf54SJim Ingham } 134e19adf54SJim Ingham 135e19adf54SJim Ingham void BreakpointResolverScripted::GetDescription(Stream *s) { 136e19adf54SJim Ingham StructuredData::GenericSP generic_sp; 137e19adf54SJim Ingham std::string short_help; 138e19adf54SJim Ingham 139e19adf54SJim Ingham if (m_implementation_sp) { 140e19adf54SJim Ingham ScriptInterpreter *interp = GetScriptInterpreter(); 141e19adf54SJim Ingham interp->GetShortHelpForCommandObject(m_implementation_sp, 142e19adf54SJim Ingham short_help); 143e19adf54SJim Ingham } 144e19adf54SJim Ingham if (!short_help.empty()) 145e19adf54SJim Ingham s->PutCString(short_help.c_str()); 146e19adf54SJim Ingham else 147e19adf54SJim Ingham s->Printf("python class = %s", m_class_name.c_str()); 148e19adf54SJim Ingham } 149e19adf54SJim Ingham 150e19adf54SJim Ingham void BreakpointResolverScripted::Dump(Stream *s) const {} 151e19adf54SJim Ingham 152e19adf54SJim Ingham lldb::BreakpointResolverSP 153*6c17cc53STatyana Krasnukha BreakpointResolverScripted::CopyForBreakpoint(BreakpointSP &breakpoint) { 154e19adf54SJim Ingham // FIXME: Have to make a copy of the arguments from the m_args_ptr and then 155e19adf54SJim Ingham // pass that to the new resolver. 156e19adf54SJim Ingham lldb::BreakpointResolverSP ret_sp( 157*6c17cc53STatyana Krasnukha new BreakpointResolverScripted(breakpoint, m_class_name, m_depth, 15847b33dccSJim Ingham nullptr)); 159e19adf54SJim Ingham return ret_sp; 160e19adf54SJim Ingham } 161