blob: d0018b6df11454b292067d1d55b2ab827711de8f [file] [log] [blame]
Eugene Zelenko8f30a652015-10-23 18:39:37 +00001//===-- LanguageRuntime.cpp -------------------------------------*- C++ -*-===//
Jim Ingham22777012010-09-23 02:01:19 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Eugene Zelenko8f30a652015-10-23 18:39:37 +000010// C Includes
11// C++ Includes
12// Other libraries and framework includes
13// Project includes
Jim Ingham22777012010-09-23 02:01:19 +000014#include "lldb/Target/LanguageRuntime.h"
Jim Ingham0fcdac32015-11-06 22:48:59 +000015#include "Plugins/Language/ObjC/ObjCLanguage.h"
Jim Ingham22777012010-09-23 02:01:19 +000016#include "lldb/Core/PluginManager.h"
Jim Ingham33df7cd2014-12-06 01:28:03 +000017#include "lldb/Core/SearchFilter.h"
Colin Rileyc9c55a22015-05-04 18:39:38 +000018#include "lldb/Interpreter/CommandInterpreter.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000019#include "lldb/Target/ObjCLanguageRuntime.h"
20#include "lldb/Target/Target.h"
Jim Ingham22777012010-09-23 02:01:19 +000021
22using namespace lldb;
23using namespace lldb_private;
24
Jim Inghame14dc262016-09-12 23:10:56 +000025ExceptionSearchFilter::ExceptionSearchFilter(const lldb::TargetSP &target_sp,
26 lldb::LanguageType language,
27 bool update_module_list)
28 : SearchFilter(target_sp, FilterTy::Exception), m_language(language),
29 m_language_runtime(nullptr), m_filter_sp() {
30 if (update_module_list)
Kate Stoneb9c1b512016-09-06 20:57:50 +000031 UpdateModuleListIfNeeded();
Jim Inghame14dc262016-09-12 23:10:56 +000032}
Greg Claytonbff78252013-03-11 18:42:51 +000033
Jim Inghame14dc262016-09-12 23:10:56 +000034bool ExceptionSearchFilter::ModulePasses(const lldb::ModuleSP &module_sp) {
35 UpdateModuleListIfNeeded();
36 if (m_filter_sp)
37 return m_filter_sp->ModulePasses(module_sp);
38 return false;
39}
Kate Stoneb9c1b512016-09-06 20:57:50 +000040
Jim Inghame14dc262016-09-12 23:10:56 +000041bool ExceptionSearchFilter::ModulePasses(const FileSpec &spec) {
42 UpdateModuleListIfNeeded();
43 if (m_filter_sp)
44 return m_filter_sp->ModulePasses(spec);
45 return false;
46}
Kate Stoneb9c1b512016-09-06 20:57:50 +000047
Jim Inghame14dc262016-09-12 23:10:56 +000048void ExceptionSearchFilter::Search(Searcher &searcher) {
49 UpdateModuleListIfNeeded();
50 if (m_filter_sp)
51 m_filter_sp->Search(searcher);
52}
Kate Stoneb9c1b512016-09-06 20:57:50 +000053
Jim Inghame14dc262016-09-12 23:10:56 +000054void ExceptionSearchFilter::GetDescription(Stream *s) {
55 UpdateModuleListIfNeeded();
56 if (m_filter_sp)
57 m_filter_sp->GetDescription(s);
58}
Greg Claytonbff78252013-03-11 18:42:51 +000059
Jim Inghame14dc262016-09-12 23:10:56 +000060void ExceptionSearchFilter::UpdateModuleListIfNeeded() {
61 ProcessSP process_sp(m_target_sp->GetProcessSP());
62 if (process_sp) {
63 bool refreash_filter = !m_filter_sp;
64 if (m_language_runtime == nullptr) {
65 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
66 refreash_filter = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +000067 } else {
Jim Inghame14dc262016-09-12 23:10:56 +000068 LanguageRuntime *language_runtime =
69 process_sp->GetLanguageRuntime(m_language);
70 if (m_language_runtime != language_runtime) {
71 m_language_runtime = language_runtime;
72 refreash_filter = true;
73 }
Greg Claytonbff78252013-03-11 18:42:51 +000074 }
Jim Inghame14dc262016-09-12 23:10:56 +000075
76 if (refreash_filter && m_language_runtime) {
77 m_filter_sp = m_language_runtime->CreateExceptionSearchFilter();
78 }
79 } else {
80 m_filter_sp.reset();
81 m_language_runtime = nullptr;
Kate Stoneb9c1b512016-09-06 20:57:50 +000082 }
Jim Inghame14dc262016-09-12 23:10:56 +000083}
84
85SearchFilterSP
86ExceptionSearchFilter::DoCopyForBreakpoint(Breakpoint &breakpoint) {
87 return SearchFilterSP(
88 new ExceptionSearchFilter(TargetSP(), m_language, false));
89}
90
91SearchFilter *ExceptionSearchFilter::CreateFromStructuredData(
Jim Ingham1a81b272016-09-13 01:58:08 +000092 Target &target, const StructuredData::Dictionary &data_dict, Error &error) {
Jim Inghame14dc262016-09-12 23:10:56 +000093 SearchFilter *result = nullptr;
94 return result;
95}
96
97StructuredData::ObjectSP ExceptionSearchFilter::SerializeToStructuredData() {
98 StructuredData::ObjectSP result_sp;
99
100 return result_sp;
101}
Greg Claytonbff78252013-03-11 18:42:51 +0000102
103// The Target is the one that knows how to create breakpoints, so this function
Kate Stoneb9c1b512016-09-06 20:57:50 +0000104// is meant to be used either by the target or internally in
105// Set/ClearExceptionBreakpoints.
106class ExceptionBreakpointResolver : public BreakpointResolver {
Greg Claytonbff78252013-03-11 18:42:51 +0000107public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000108 ExceptionBreakpointResolver(lldb::LanguageType language, bool catch_bp,
109 bool throw_bp)
110 : BreakpointResolver(nullptr, BreakpointResolver::ExceptionResolver),
111 m_language(language), m_language_runtime(nullptr), m_catch_bp(catch_bp),
112 m_throw_bp(throw_bp) {}
Greg Claytonbff78252013-03-11 18:42:51 +0000113
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114 ~ExceptionBreakpointResolver() override = default;
Eugene Zelenko8f30a652015-10-23 18:39:37 +0000115
Kate Stoneb9c1b512016-09-06 20:57:50 +0000116 Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
117 SymbolContext &context, Address *addr,
118 bool containing) override {
Greg Claytonbff78252013-03-11 18:42:51 +0000119
Kate Stoneb9c1b512016-09-06 20:57:50 +0000120 if (SetActualResolver())
121 return m_actual_resolver_sp->SearchCallback(filter, context, addr,
122 containing);
123 else
124 return eCallbackReturnStop;
125 }
126
127 Searcher::Depth GetDepth() override {
128 if (SetActualResolver())
129 return m_actual_resolver_sp->GetDepth();
130 else
131 return eDepthTarget;
132 }
133
134 void GetDescription(Stream *s) override {
135 Language *language_plugin = Language::FindPlugin(m_language);
136 if (language_plugin)
137 language_plugin->GetExceptionResolverDescription(m_catch_bp, m_throw_bp,
138 *s);
139 else
140 Language::GetDefaultExceptionResolverDescription(m_catch_bp, m_throw_bp,
141 *s);
142
143 SetActualResolver();
144 if (m_actual_resolver_sp) {
145 s->Printf(" using: ");
146 m_actual_resolver_sp->GetDescription(s);
147 } else
148 s->Printf(" the correct runtime exception handler will be determined "
149 "when you run");
150 }
151
152 void Dump(Stream *s) const override {}
153
154 /// Methods for support type inquiry through isa, cast, and dyn_cast:
155 static inline bool classof(const BreakpointResolverName *) { return true; }
156 static inline bool classof(const BreakpointResolver *V) {
157 return V->getResolverID() == BreakpointResolver::ExceptionResolver;
158 }
Eugene Zelenko8f30a652015-10-23 18:39:37 +0000159
Greg Claytonbff78252013-03-11 18:42:51 +0000160protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161 BreakpointResolverSP CopyForBreakpoint(Breakpoint &breakpoint) override {
162 return BreakpointResolverSP(
163 new ExceptionBreakpointResolver(m_language, m_catch_bp, m_throw_bp));
164 }
Jim Ingham33df7cd2014-12-06 01:28:03 +0000165
Kate Stoneb9c1b512016-09-06 20:57:50 +0000166 bool SetActualResolver() {
167 ProcessSP process_sp;
168 if (m_breakpoint) {
169 process_sp = m_breakpoint->GetTarget().GetProcessSP();
170 if (process_sp) {
171 bool refreash_resolver = !m_actual_resolver_sp;
172 if (m_language_runtime == nullptr) {
173 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
174 refreash_resolver = true;
175 } else {
176 LanguageRuntime *language_runtime =
177 process_sp->GetLanguageRuntime(m_language);
178 if (m_language_runtime != language_runtime) {
179 m_language_runtime = language_runtime;
180 refreash_resolver = true;
181 }
Greg Claytonbff78252013-03-11 18:42:51 +0000182 }
Eugene Zelenko9394d7722016-02-18 00:10:17 +0000183
Kate Stoneb9c1b512016-09-06 20:57:50 +0000184 if (refreash_resolver && m_language_runtime) {
185 m_actual_resolver_sp = m_language_runtime->CreateExceptionResolver(
186 m_breakpoint, m_catch_bp, m_throw_bp);
187 }
188 } else {
189 m_actual_resolver_sp.reset();
190 m_language_runtime = nullptr;
191 }
192 } else {
193 m_actual_resolver_sp.reset();
194 m_language_runtime = nullptr;
195 }
196 return (bool)m_actual_resolver_sp;
197 }
198
199 lldb::BreakpointResolverSP m_actual_resolver_sp;
200 lldb::LanguageType m_language;
201 LanguageRuntime *m_language_runtime;
202 bool m_catch_bp;
203 bool m_throw_bp;
Greg Claytonbff78252013-03-11 18:42:51 +0000204};
205
Kate Stoneb9c1b512016-09-06 20:57:50 +0000206LanguageRuntime *LanguageRuntime::FindPlugin(Process *process,
207 lldb::LanguageType language) {
208 std::unique_ptr<LanguageRuntime> language_runtime_ap;
209 LanguageRuntimeCreateInstance create_callback;
Jim Ingham22777012010-09-23 02:01:19 +0000210
Kate Stoneb9c1b512016-09-06 20:57:50 +0000211 for (uint32_t idx = 0;
212 (create_callback =
213 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) !=
214 nullptr;
215 ++idx) {
216 language_runtime_ap.reset(create_callback(process, language));
Jim Ingham22777012010-09-23 02:01:19 +0000217
Kate Stoneb9c1b512016-09-06 20:57:50 +0000218 if (language_runtime_ap)
219 return language_runtime_ap.release();
220 }
Jim Ingham22777012010-09-23 02:01:19 +0000221
Kate Stoneb9c1b512016-09-06 20:57:50 +0000222 return nullptr;
Jim Ingham22777012010-09-23 02:01:19 +0000223}
224
Kate Stoneb9c1b512016-09-06 20:57:50 +0000225LanguageRuntime::LanguageRuntime(Process *process) : m_process(process) {}
Jim Ingham22777012010-09-23 02:01:19 +0000226
Eugene Zelenko8f30a652015-10-23 18:39:37 +0000227LanguageRuntime::~LanguageRuntime() = default;
Jim Ingham219ba192012-03-05 04:47:34 +0000228
Jim Inghama72b31c2015-04-22 19:42:18 +0000229Breakpoint::BreakpointPreconditionSP
Kate Stoneb9c1b512016-09-06 20:57:50 +0000230LanguageRuntime::CreateExceptionPrecondition(lldb::LanguageType language,
231 bool catch_bp, bool throw_bp) {
232 switch (language) {
233 case eLanguageTypeObjC:
234 if (throw_bp)
235 return Breakpoint::BreakpointPreconditionSP(
236 new ObjCLanguageRuntime::ObjCExceptionPrecondition());
237 break;
238 default:
239 break;
240 }
241 return Breakpoint::BreakpointPreconditionSP();
Jim Inghama72b31c2015-04-22 19:42:18 +0000242}
243
Kate Stoneb9c1b512016-09-06 20:57:50 +0000244BreakpointSP LanguageRuntime::CreateExceptionBreakpoint(
245 Target &target, lldb::LanguageType language, bool catch_bp, bool throw_bp,
246 bool is_internal) {
247 BreakpointResolverSP resolver_sp(
248 new ExceptionBreakpointResolver(language, catch_bp, throw_bp));
249 SearchFilterSP filter_sp(
250 new ExceptionSearchFilter(target.shared_from_this(), language));
251 bool hardware = false;
252 bool resolve_indirect_functions = false;
253 BreakpointSP exc_breakpt_sp(
254 target.CreateBreakpoint(filter_sp, resolver_sp, is_internal, hardware,
255 resolve_indirect_functions));
256 if (exc_breakpt_sp) {
257 Breakpoint::BreakpointPreconditionSP precondition_sp =
258 CreateExceptionPrecondition(language, catch_bp, throw_bp);
259 if (precondition_sp)
260 exc_breakpt_sp->SetPrecondition(precondition_sp);
Jim Inghama72b31c2015-04-22 19:42:18 +0000261
Kate Stoneb9c1b512016-09-06 20:57:50 +0000262 if (is_internal)
263 exc_breakpt_sp->SetBreakpointKind("exception");
264 }
265
266 return exc_breakpt_sp;
Jim Ingham219ba192012-03-05 04:47:34 +0000267}
268
Kate Stoneb9c1b512016-09-06 20:57:50 +0000269void LanguageRuntime::InitializeCommands(CommandObject *parent) {
270 if (!parent)
271 return;
Colin Rileyc9c55a22015-05-04 18:39:38 +0000272
Kate Stoneb9c1b512016-09-06 20:57:50 +0000273 if (!parent->IsMultiwordObject())
274 return;
Colin Rileyc9c55a22015-05-04 18:39:38 +0000275
Kate Stoneb9c1b512016-09-06 20:57:50 +0000276 LanguageRuntimeCreateInstance create_callback;
Colin Rileyc9c55a22015-05-04 18:39:38 +0000277
Kate Stoneb9c1b512016-09-06 20:57:50 +0000278 for (uint32_t idx = 0;
279 (create_callback =
280 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) !=
281 nullptr;
282 ++idx) {
283 if (LanguageRuntimeGetCommandObject command_callback =
284 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(idx)) {
285 CommandObjectSP command =
286 command_callback(parent->GetCommandInterpreter());
287 if (command) {
288 // the CommandObject vended by a Language plugin cannot be created once
Zachary Turnera4496982016-10-05 21:14:38 +0000289 // and cached because we may create multiple debuggers and need one
290 // instance of the command each - the implementing function is meant to
291 // create a new instance of the command each time it is invoked.
292 parent->LoadSubCommand(command->GetCommandName().str().c_str(), command);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000293 }
Colin Rileyc9c55a22015-05-04 18:39:38 +0000294 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000295 }
Colin Rileyc9c55a22015-05-04 18:39:38 +0000296}
297
Kate Stoneb9c1b512016-09-06 20:57:50 +0000298lldb::SearchFilterSP LanguageRuntime::CreateExceptionSearchFilter() {
299 return m_process->GetTarget().GetSearchFilterForModule(nullptr);
Greg Claytonbff78252013-03-11 18:42:51 +0000300}