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:
BreakpointResolverScripted(const BreakpointSP & bkpt,const llvm::StringRef class_name,lldb::SearchDepth depth,const StructuredDataImpl & args_data)28e19adf54SJim Ingham BreakpointResolverScripted::BreakpointResolverScripted(
296c17cc53STatyana Krasnukha     const BreakpointSP &bkpt, const llvm::StringRef class_name,
30*82de8df2SPavel Labath     lldb::SearchDepth depth, const StructuredDataImpl &args_data)
31e19adf54SJim Ingham     : BreakpointResolver(bkpt, BreakpointResolver::PythonResolver),
32*82de8df2SPavel Labath       m_class_name(std::string(class_name)), m_depth(depth), m_args(args_data) {
336c17cc53STatyana Krasnukha   CreateImplementationIfNeeded(bkpt);
34e19adf54SJim Ingham }
35e19adf54SJim Ingham 
CreateImplementationIfNeeded(BreakpointSP breakpoint_sp)366c17cc53STatyana Krasnukha void BreakpointResolverScripted::CreateImplementationIfNeeded(
376c17cc53STatyana Krasnukha     BreakpointSP breakpoint_sp) {
38e19adf54SJim Ingham   if (m_implementation_sp)
39e19adf54SJim Ingham     return;
40e19adf54SJim Ingham 
41e19adf54SJim Ingham   if (m_class_name.empty())
42e19adf54SJim Ingham     return;
43e19adf54SJim Ingham 
446c17cc53STatyana Krasnukha   if (!breakpoint_sp)
456c17cc53STatyana Krasnukha     return;
466c17cc53STatyana Krasnukha 
476c17cc53STatyana Krasnukha   TargetSP target_sp = breakpoint_sp->GetTargetSP();
48e19adf54SJim Ingham   ScriptInterpreter *script_interp = target_sp->GetDebugger()
49e19adf54SJim Ingham                                               .GetScriptInterpreter();
50e19adf54SJim Ingham   if (!script_interp)
51e19adf54SJim Ingham     return;
526c17cc53STatyana Krasnukha 
53e19adf54SJim Ingham   m_implementation_sp = script_interp->CreateScriptedBreakpointResolver(
54*82de8df2SPavel Labath       m_class_name.c_str(), m_args, breakpoint_sp);
55e19adf54SJim Ingham }
56e19adf54SJim Ingham 
NotifyBreakpointSet()57e19adf54SJim Ingham void BreakpointResolverScripted::NotifyBreakpointSet() {
586c17cc53STatyana Krasnukha   CreateImplementationIfNeeded(GetBreakpoint());
59e19adf54SJim Ingham }
60e19adf54SJim Ingham 
61e19adf54SJim Ingham BreakpointResolver *
CreateFromStructuredData(const BreakpointSP & bkpt,const StructuredData::Dictionary & options_dict,Status & error)62e19adf54SJim Ingham BreakpointResolverScripted::CreateFromStructuredData(
636c17cc53STatyana Krasnukha     const BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict,
64e19adf54SJim Ingham     Status &error) {
65e19adf54SJim Ingham   llvm::StringRef class_name;
66e19adf54SJim Ingham   bool success;
67e19adf54SJim Ingham 
68e19adf54SJim Ingham   success = options_dict.GetValueForKeyAsString(
69e19adf54SJim Ingham       GetKey(OptionNames::PythonClassName), class_name);
70e19adf54SJim Ingham   if (!success) {
71e19adf54SJim Ingham     error.SetErrorString("BRFL::CFSD: Couldn't find class name entry.");
72e19adf54SJim Ingham     return nullptr;
73e19adf54SJim Ingham   }
7447b33dccSJim Ingham   // The Python function will actually provide the search depth, this is a
7547b33dccSJim Ingham   // placeholder.
7647b33dccSJim Ingham   lldb::SearchDepth depth = lldb::eSearchDepthTarget;
77e19adf54SJim Ingham 
78*82de8df2SPavel Labath   StructuredDataImpl args_data_impl;
796d7fb299SKonrad Kleine   StructuredData::Dictionary *args_dict = nullptr;
80*82de8df2SPavel Labath   if (options_dict.GetValueForKeyAsDictionary(GetKey(OptionNames::ScriptArgs),
81*82de8df2SPavel Labath                                               args_dict))
82*82de8df2SPavel Labath     args_data_impl.SetObjectSP(args_dict->shared_from_this());
8347b33dccSJim Ingham   return new BreakpointResolverScripted(bkpt, class_name, depth,
8447b33dccSJim Ingham                                         args_data_impl);
85e19adf54SJim Ingham }
86e19adf54SJim Ingham 
87e19adf54SJim Ingham StructuredData::ObjectSP
SerializeToStructuredData()88e19adf54SJim Ingham BreakpointResolverScripted::SerializeToStructuredData() {
89e19adf54SJim Ingham   StructuredData::DictionarySP options_dict_sp(
90e19adf54SJim Ingham       new StructuredData::Dictionary());
91e19adf54SJim Ingham 
92e19adf54SJim Ingham   options_dict_sp->AddStringItem(GetKey(OptionNames::PythonClassName),
93e19adf54SJim Ingham                                    m_class_name);
94*82de8df2SPavel Labath   if (m_args.IsValid())
9547b33dccSJim Ingham     options_dict_sp->AddItem(GetKey(OptionNames::ScriptArgs),
96*82de8df2SPavel Labath                              m_args.GetObjectSP());
9747b33dccSJim Ingham 
98e19adf54SJim Ingham   return WrapOptionsDict(options_dict_sp);
99e19adf54SJim Ingham }
100e19adf54SJim Ingham 
GetScriptInterpreter()101e19adf54SJim Ingham ScriptInterpreter *BreakpointResolverScripted::GetScriptInterpreter() {
1026c17cc53STatyana Krasnukha   return GetBreakpoint()->GetTarget().GetDebugger().GetScriptInterpreter();
103e19adf54SJim Ingham }
104e19adf54SJim Ingham 
SearchCallback(SearchFilter & filter,SymbolContext & context,Address * addr)10595e264fcSRaphael Isemann Searcher::CallbackReturn BreakpointResolverScripted::SearchCallback(
10695e264fcSRaphael Isemann     SearchFilter &filter, SymbolContext &context, Address *addr) {
107e19adf54SJim Ingham   bool should_continue = true;
108e19adf54SJim Ingham   if (!m_implementation_sp)
109e19adf54SJim Ingham     return Searcher::eCallbackReturnStop;
110e19adf54SJim Ingham 
111e19adf54SJim Ingham   ScriptInterpreter *interp = GetScriptInterpreter();
112e19adf54SJim Ingham   should_continue = interp->ScriptedBreakpointResolverSearchCallback(
113e19adf54SJim Ingham       m_implementation_sp,
114e19adf54SJim Ingham       &context);
115e19adf54SJim Ingham   if (should_continue)
116e19adf54SJim Ingham     return Searcher::eCallbackReturnContinue;
1176c17cc53STatyana Krasnukha 
118e19adf54SJim Ingham   return Searcher::eCallbackReturnStop;
119e19adf54SJim Ingham }
120e19adf54SJim Ingham 
121e19adf54SJim Ingham lldb::SearchDepth
GetDepth()122e19adf54SJim Ingham BreakpointResolverScripted::GetDepth() {
123e19adf54SJim Ingham   lldb::SearchDepth depth = lldb::eSearchDepthModule;
124e19adf54SJim Ingham   if (m_implementation_sp) {
125e19adf54SJim Ingham     ScriptInterpreter *interp = GetScriptInterpreter();
126e19adf54SJim Ingham     depth = interp->ScriptedBreakpointResolverSearchDepth(
127e19adf54SJim Ingham         m_implementation_sp);
128e19adf54SJim Ingham   }
129e19adf54SJim Ingham   return depth;
130e19adf54SJim Ingham }
131e19adf54SJim Ingham 
GetDescription(Stream * s)132e19adf54SJim Ingham void BreakpointResolverScripted::GetDescription(Stream *s) {
133e19adf54SJim Ingham   StructuredData::GenericSP generic_sp;
134e19adf54SJim Ingham   std::string short_help;
135e19adf54SJim Ingham 
136e19adf54SJim Ingham   if (m_implementation_sp) {
137e19adf54SJim Ingham     ScriptInterpreter *interp = GetScriptInterpreter();
138e19adf54SJim Ingham     interp->GetShortHelpForCommandObject(m_implementation_sp,
139e19adf54SJim Ingham                                          short_help);
140e19adf54SJim Ingham   }
141e19adf54SJim Ingham   if (!short_help.empty())
142e19adf54SJim Ingham     s->PutCString(short_help.c_str());
143e19adf54SJim Ingham   else
144e19adf54SJim Ingham     s->Printf("python class = %s", m_class_name.c_str());
145e19adf54SJim Ingham }
146e19adf54SJim Ingham 
Dump(Stream * s) const147e19adf54SJim Ingham void BreakpointResolverScripted::Dump(Stream *s) const {}
148e19adf54SJim Ingham 
149e19adf54SJim Ingham lldb::BreakpointResolverSP
CopyForBreakpoint(BreakpointSP & breakpoint)1506c17cc53STatyana Krasnukha BreakpointResolverScripted::CopyForBreakpoint(BreakpointSP &breakpoint) {
151*82de8df2SPavel Labath   return std::make_shared<BreakpointResolverScripted>(breakpoint, m_class_name,
152*82de8df2SPavel Labath                                                       m_depth, m_args);
153e19adf54SJim Ingham }
154