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
24using namespace lldb;
25using namespace lldb_private;
26
27// BreakpointResolverScripted:
28BreakpointResolverScripted::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
36void 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 class_name: m_class_name.c_str(), args_data: m_args, bkpt_sp&: breakpoint_sp);
55}
56
57void BreakpointResolverScripted::NotifyBreakpointSet() {
58 CreateImplementationIfNeeded(breakpoint_sp: GetBreakpoint());
59}
60
61BreakpointResolverSP 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 key: GetKey(enum_value: OptionNames::PythonClassName), result&: 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(key: GetKey(enum_value: OptionNames::ScriptArgs),
79 result&: args_dict))
80 args_data_impl.SetObjectSP(args_dict->shared_from_this());
81 return std::make_shared<BreakpointResolverScripted>(args: nullptr, args&: class_name,
82 args&: depth, args&: args_data_impl);
83}
84
85StructuredData::ObjectSP
86BreakpointResolverScripted::SerializeToStructuredData() {
87 StructuredData::DictionarySP options_dict_sp(
88 new StructuredData::Dictionary());
89
90 options_dict_sp->AddStringItem(key: GetKey(enum_value: OptionNames::PythonClassName),
91 value: m_class_name);
92 if (m_args.IsValid())
93 options_dict_sp->AddItem(key: GetKey(enum_value: OptionNames::ScriptArgs),
94 value_sp: m_args.GetObjectSP());
95
96 return WrapOptionsDict(options_dict_sp);
97}
98
99ScriptInterpreter *BreakpointResolverScripted::GetScriptInterpreter() {
100 return GetBreakpoint()->GetTarget().GetDebugger().GetScriptInterpreter();
101}
102
103Searcher::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 implementor_sp: m_implementation_sp,
112 sym_ctx: &context);
113 if (should_continue)
114 return Searcher::eCallbackReturnContinue;
115
116 return Searcher::eCallbackReturnStop;
117}
118
119lldb::SearchDepth
120BreakpointResolverScripted::GetDepth() {
121 lldb::SearchDepth depth = lldb::eSearchDepthModule;
122 if (m_implementation_sp) {
123 ScriptInterpreter *interp = GetScriptInterpreter();
124 depth = interp->ScriptedBreakpointResolverSearchDepth(
125 implementor_sp: m_implementation_sp);
126 }
127 return depth;
128}
129
130void 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(cmd_obj_sp: m_implementation_sp,
137 dest&: short_help);
138 }
139 if (!short_help.empty())
140 s->PutCString(cstr: short_help.c_str());
141 else
142 s->Printf(format: "python class = %s", m_class_name.c_str());
143}
144
145void BreakpointResolverScripted::Dump(Stream *s) const {}
146
147lldb::BreakpointResolverSP
148BreakpointResolverScripted::CopyForBreakpoint(BreakpointSP &breakpoint) {
149 return std::make_shared<BreakpointResolverScripted>(args&: breakpoint, args&: m_class_name,
150 args&: m_depth, args&: m_args);
151}
152

source code of lldb/source/Breakpoint/BreakpointResolverScripted.cpp