blob: 22ad2d25ee1235f56f6e6cee3e96b4314f280b99 [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(
Zachary Turner97206d52017-05-12 04:51:55 +000092 Target &target, const StructuredData::Dictionary &data_dict,
93 Status &error) {
Jim Inghame14dc262016-09-12 23:10:56 +000094 SearchFilter *result = nullptr;
95 return result;
96}
97
98StructuredData::ObjectSP ExceptionSearchFilter::SerializeToStructuredData() {
99 StructuredData::ObjectSP result_sp;
100
101 return result_sp;
102}
Greg Claytonbff78252013-03-11 18:42:51 +0000103
104// The Target is the one that knows how to create breakpoints, so this function
Kate Stoneb9c1b512016-09-06 20:57:50 +0000105// is meant to be used either by the target or internally in
106// Set/ClearExceptionBreakpoints.
107class ExceptionBreakpointResolver : public BreakpointResolver {
Greg Claytonbff78252013-03-11 18:42:51 +0000108public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109 ExceptionBreakpointResolver(lldb::LanguageType language, bool catch_bp,
110 bool throw_bp)
111 : BreakpointResolver(nullptr, BreakpointResolver::ExceptionResolver),
112 m_language(language), m_language_runtime(nullptr), m_catch_bp(catch_bp),
113 m_throw_bp(throw_bp) {}
Greg Claytonbff78252013-03-11 18:42:51 +0000114
Kate Stoneb9c1b512016-09-06 20:57:50 +0000115 ~ExceptionBreakpointResolver() override = default;
Eugene Zelenko8f30a652015-10-23 18:39:37 +0000116
Kate Stoneb9c1b512016-09-06 20:57:50 +0000117 Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
118 SymbolContext &context, Address *addr,
119 bool containing) override {
Greg Claytonbff78252013-03-11 18:42:51 +0000120
Kate Stoneb9c1b512016-09-06 20:57:50 +0000121 if (SetActualResolver())
122 return m_actual_resolver_sp->SearchCallback(filter, context, addr,
123 containing);
124 else
125 return eCallbackReturnStop;
126 }
127
Jim Ingham4911d362018-09-07 18:43:04 +0000128 lldb::SearchDepth GetDepth() override {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000129 if (SetActualResolver())
130 return m_actual_resolver_sp->GetDepth();
131 else
Jim Ingham4911d362018-09-07 18:43:04 +0000132 return lldb::eSearchDepthTarget;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000133 }
134
135 void GetDescription(Stream *s) override {
136 Language *language_plugin = Language::FindPlugin(m_language);
137 if (language_plugin)
138 language_plugin->GetExceptionResolverDescription(m_catch_bp, m_throw_bp,
139 *s);
140 else
141 Language::GetDefaultExceptionResolverDescription(m_catch_bp, m_throw_bp,
142 *s);
143
144 SetActualResolver();
145 if (m_actual_resolver_sp) {
146 s->Printf(" using: ");
147 m_actual_resolver_sp->GetDescription(s);
148 } else
149 s->Printf(" the correct runtime exception handler will be determined "
150 "when you run");
151 }
152
153 void Dump(Stream *s) const override {}
154
155 /// Methods for support type inquiry through isa, cast, and dyn_cast:
156 static inline bool classof(const BreakpointResolverName *) { return true; }
157 static inline bool classof(const BreakpointResolver *V) {
158 return V->getResolverID() == BreakpointResolver::ExceptionResolver;
159 }
Eugene Zelenko8f30a652015-10-23 18:39:37 +0000160
Greg Claytonbff78252013-03-11 18:42:51 +0000161protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000162 BreakpointResolverSP CopyForBreakpoint(Breakpoint &breakpoint) override {
163 return BreakpointResolverSP(
164 new ExceptionBreakpointResolver(m_language, m_catch_bp, m_throw_bp));
165 }
Jim Ingham33df7cd2014-12-06 01:28:03 +0000166
Kate Stoneb9c1b512016-09-06 20:57:50 +0000167 bool SetActualResolver() {
168 ProcessSP process_sp;
169 if (m_breakpoint) {
170 process_sp = m_breakpoint->GetTarget().GetProcessSP();
171 if (process_sp) {
172 bool refreash_resolver = !m_actual_resolver_sp;
173 if (m_language_runtime == nullptr) {
174 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
175 refreash_resolver = true;
176 } else {
177 LanguageRuntime *language_runtime =
178 process_sp->GetLanguageRuntime(m_language);
179 if (m_language_runtime != language_runtime) {
180 m_language_runtime = language_runtime;
181 refreash_resolver = true;
182 }
Greg Claytonbff78252013-03-11 18:42:51 +0000183 }
Eugene Zelenko9394d7722016-02-18 00:10:17 +0000184
Kate Stoneb9c1b512016-09-06 20:57:50 +0000185 if (refreash_resolver && m_language_runtime) {
186 m_actual_resolver_sp = m_language_runtime->CreateExceptionResolver(
187 m_breakpoint, m_catch_bp, m_throw_bp);
188 }
189 } else {
190 m_actual_resolver_sp.reset();
191 m_language_runtime = nullptr;
192 }
193 } else {
194 m_actual_resolver_sp.reset();
195 m_language_runtime = nullptr;
196 }
197 return (bool)m_actual_resolver_sp;
198 }
199
200 lldb::BreakpointResolverSP m_actual_resolver_sp;
201 lldb::LanguageType m_language;
202 LanguageRuntime *m_language_runtime;
203 bool m_catch_bp;
204 bool m_throw_bp;
Greg Claytonbff78252013-03-11 18:42:51 +0000205};
206
Kate Stoneb9c1b512016-09-06 20:57:50 +0000207LanguageRuntime *LanguageRuntime::FindPlugin(Process *process,
208 lldb::LanguageType language) {
209 std::unique_ptr<LanguageRuntime> language_runtime_ap;
210 LanguageRuntimeCreateInstance create_callback;
Jim Ingham22777012010-09-23 02:01:19 +0000211
Kate Stoneb9c1b512016-09-06 20:57:50 +0000212 for (uint32_t idx = 0;
213 (create_callback =
214 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) !=
215 nullptr;
216 ++idx) {
217 language_runtime_ap.reset(create_callback(process, language));
Jim Ingham22777012010-09-23 02:01:19 +0000218
Kate Stoneb9c1b512016-09-06 20:57:50 +0000219 if (language_runtime_ap)
220 return language_runtime_ap.release();
221 }
Jim Ingham22777012010-09-23 02:01:19 +0000222
Kate Stoneb9c1b512016-09-06 20:57:50 +0000223 return nullptr;
Jim Ingham22777012010-09-23 02:01:19 +0000224}
225
Kate Stoneb9c1b512016-09-06 20:57:50 +0000226LanguageRuntime::LanguageRuntime(Process *process) : m_process(process) {}
Jim Ingham22777012010-09-23 02:01:19 +0000227
Eugene Zelenko8f30a652015-10-23 18:39:37 +0000228LanguageRuntime::~LanguageRuntime() = default;
Jim Ingham219ba192012-03-05 04:47:34 +0000229
Jim Inghama72b31c2015-04-22 19:42:18 +0000230Breakpoint::BreakpointPreconditionSP
Kate Stoneb9c1b512016-09-06 20:57:50 +0000231LanguageRuntime::CreateExceptionPrecondition(lldb::LanguageType language,
232 bool catch_bp, bool throw_bp) {
233 switch (language) {
234 case eLanguageTypeObjC:
235 if (throw_bp)
236 return Breakpoint::BreakpointPreconditionSP(
237 new ObjCLanguageRuntime::ObjCExceptionPrecondition());
238 break;
239 default:
240 break;
241 }
242 return Breakpoint::BreakpointPreconditionSP();
Jim Inghama72b31c2015-04-22 19:42:18 +0000243}
244
Kate Stoneb9c1b512016-09-06 20:57:50 +0000245BreakpointSP LanguageRuntime::CreateExceptionBreakpoint(
246 Target &target, lldb::LanguageType language, bool catch_bp, bool throw_bp,
247 bool is_internal) {
248 BreakpointResolverSP resolver_sp(
249 new ExceptionBreakpointResolver(language, catch_bp, throw_bp));
250 SearchFilterSP filter_sp(
251 new ExceptionSearchFilter(target.shared_from_this(), language));
252 bool hardware = false;
253 bool resolve_indirect_functions = false;
254 BreakpointSP exc_breakpt_sp(
255 target.CreateBreakpoint(filter_sp, resolver_sp, is_internal, hardware,
256 resolve_indirect_functions));
257 if (exc_breakpt_sp) {
258 Breakpoint::BreakpointPreconditionSP precondition_sp =
259 CreateExceptionPrecondition(language, catch_bp, throw_bp);
260 if (precondition_sp)
261 exc_breakpt_sp->SetPrecondition(precondition_sp);
Jim Inghama72b31c2015-04-22 19:42:18 +0000262
Kate Stoneb9c1b512016-09-06 20:57:50 +0000263 if (is_internal)
264 exc_breakpt_sp->SetBreakpointKind("exception");
265 }
266
267 return exc_breakpt_sp;
Jim Ingham219ba192012-03-05 04:47:34 +0000268}
269
Kate Stoneb9c1b512016-09-06 20:57:50 +0000270void LanguageRuntime::InitializeCommands(CommandObject *parent) {
271 if (!parent)
272 return;
Colin Rileyc9c55a22015-05-04 18:39:38 +0000273
Kate Stoneb9c1b512016-09-06 20:57:50 +0000274 if (!parent->IsMultiwordObject())
275 return;
Colin Rileyc9c55a22015-05-04 18:39:38 +0000276
Kate Stoneb9c1b512016-09-06 20:57:50 +0000277 LanguageRuntimeCreateInstance create_callback;
Colin Rileyc9c55a22015-05-04 18:39:38 +0000278
Kate Stoneb9c1b512016-09-06 20:57:50 +0000279 for (uint32_t idx = 0;
280 (create_callback =
281 PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) !=
282 nullptr;
283 ++idx) {
284 if (LanguageRuntimeGetCommandObject command_callback =
285 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(idx)) {
286 CommandObjectSP command =
287 command_callback(parent->GetCommandInterpreter());
288 if (command) {
289 // the CommandObject vended by a Language plugin cannot be created once
Zachary Turnera4496982016-10-05 21:14:38 +0000290 // and cached because we may create multiple debuggers and need one
291 // instance of the command each - the implementing function is meant to
292 // create a new instance of the command each time it is invoked.
293 parent->LoadSubCommand(command->GetCommandName().str().c_str(), command);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000294 }
Colin Rileyc9c55a22015-05-04 18:39:38 +0000295 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000296 }
Colin Rileyc9c55a22015-05-04 18:39:38 +0000297}
298
Kate Stoneb9c1b512016-09-06 20:57:50 +0000299lldb::SearchFilterSP LanguageRuntime::CreateExceptionSearchFilter() {
300 return m_process->GetTarget().GetSearchFilterForModule(nullptr);
Greg Claytonbff78252013-03-11 18:42:51 +0000301}