blob: a638a2c4480c0d3bae87c7067c8358ffb9ef8798 [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/CPlusPlus/CPlusPlusLanguage.h"
16#include "Plugins/Language/ObjC/ObjCLanguage.h"
Jim Inghama72b31c2015-04-22 19:42:18 +000017#include "lldb/Target/ObjCLanguageRuntime.h"
Jim Ingham219ba192012-03-05 04:47:34 +000018#include "lldb/Target/Target.h"
Jim Ingham22777012010-09-23 02:01:19 +000019#include "lldb/Core/PluginManager.h"
Jim Ingham33df7cd2014-12-06 01:28:03 +000020#include "lldb/Core/SearchFilter.h"
Colin Rileyc9c55a22015-05-04 18:39:38 +000021#include "lldb/Interpreter/CommandInterpreter.h"
Jim Ingham22777012010-09-23 02:01:19 +000022
23using namespace lldb;
24using namespace lldb_private;
25
Greg Claytonbff78252013-03-11 18:42:51 +000026class ExceptionSearchFilter : public SearchFilter
27{
28public:
29 ExceptionSearchFilter (const lldb::TargetSP &target_sp,
Jim Ingham33df7cd2014-12-06 01:28:03 +000030 lldb::LanguageType language,
31 bool update_module_list = true) :
Greg Claytonbff78252013-03-11 18:42:51 +000032 SearchFilter (target_sp),
33 m_language (language),
34 m_language_runtime (NULL),
35 m_filter_sp ()
36 {
Jim Ingham33df7cd2014-12-06 01:28:03 +000037 if (update_module_list)
38 UpdateModuleListIfNeeded ();
Greg Claytonbff78252013-03-11 18:42:51 +000039 }
Jim Ingham33df7cd2014-12-06 01:28:03 +000040
Eugene Zelenko8f30a652015-10-23 18:39:37 +000041 ~ExceptionSearchFilter() override = default;
Jim Ingham33df7cd2014-12-06 01:28:03 +000042
Eric Christopher2325e382014-12-10 22:29:58 +000043 bool
44 ModulePasses (const lldb::ModuleSP &module_sp) override
Greg Claytonbff78252013-03-11 18:42:51 +000045 {
46 UpdateModuleListIfNeeded ();
47 if (m_filter_sp)
48 return m_filter_sp->ModulePasses (module_sp);
49 return false;
50 }
51
Eric Christopher2325e382014-12-10 22:29:58 +000052 bool
53 ModulePasses (const FileSpec &spec) override
Greg Claytonbff78252013-03-11 18:42:51 +000054 {
55 UpdateModuleListIfNeeded ();
56 if (m_filter_sp)
57 return m_filter_sp->ModulePasses (spec);
58 return false;
Greg Claytonbff78252013-03-11 18:42:51 +000059 }
60
Eric Christopher2325e382014-12-10 22:29:58 +000061 void
62 Search (Searcher &searcher) override
Greg Claytonbff78252013-03-11 18:42:51 +000063 {
64 UpdateModuleListIfNeeded ();
65 if (m_filter_sp)
66 m_filter_sp->Search (searcher);
67 }
68
Eric Christopher2325e382014-12-10 22:29:58 +000069 void
70 GetDescription (Stream *s) override
Greg Claytonbff78252013-03-11 18:42:51 +000071 {
72 UpdateModuleListIfNeeded ();
73 if (m_filter_sp)
74 m_filter_sp->GetDescription (s);
75 }
76
77protected:
78 LanguageType m_language;
79 LanguageRuntime *m_language_runtime;
80 SearchFilterSP m_filter_sp;
81
Jim Ingham33df7cd2014-12-06 01:28:03 +000082 SearchFilterSP
83 DoCopyForBreakpoint(Breakpoint &breakpoint) override
84 {
85 return SearchFilterSP(new ExceptionSearchFilter(TargetSP(), m_language, false));
86 }
87
Greg Claytonbff78252013-03-11 18:42:51 +000088 void
89 UpdateModuleListIfNeeded ()
90 {
91 ProcessSP process_sp (m_target_sp->GetProcessSP());
92 if (process_sp)
93 {
94 bool refreash_filter = !m_filter_sp;
95 if (m_language_runtime == NULL)
96 {
97 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
98 refreash_filter = true;
99 }
100 else
101 {
102 LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
103 if (m_language_runtime != language_runtime)
104 {
105 m_language_runtime = language_runtime;
106 refreash_filter = true;
107 }
108 }
109
110 if (refreash_filter && m_language_runtime)
111 {
112 m_filter_sp = m_language_runtime->CreateExceptionSearchFilter ();
113 }
114 }
115 else
116 {
117 m_filter_sp.reset();
118 m_language_runtime = NULL;
119 }
120 }
121};
122
123// The Target is the one that knows how to create breakpoints, so this function
124// is meant to be used either by the target or internally in Set/ClearExceptionBreakpoints.
125class ExceptionBreakpointResolver : public BreakpointResolver
126{
127public:
128 ExceptionBreakpointResolver (lldb::LanguageType language,
129 bool catch_bp,
130 bool throw_bp) :
131 BreakpointResolver (NULL, BreakpointResolver::ExceptionResolver),
132 m_language (language),
133 m_language_runtime (NULL),
134 m_catch_bp (catch_bp),
135 m_throw_bp (throw_bp)
136 {
137 }
138
Eugene Zelenko8f30a652015-10-23 18:39:37 +0000139 ~ExceptionBreakpointResolver() override = default;
140
Eric Christopher2325e382014-12-10 22:29:58 +0000141 Searcher::CallbackReturn
Greg Claytonbff78252013-03-11 18:42:51 +0000142 SearchCallback (SearchFilter &filter,
143 SymbolContext &context,
144 Address *addr,
Eric Christopher2325e382014-12-10 22:29:58 +0000145 bool containing) override
Greg Claytonbff78252013-03-11 18:42:51 +0000146 {
147
148 if (SetActualResolver())
149 return m_actual_resolver_sp->SearchCallback (filter, context, addr, containing);
150 else
151 return eCallbackReturnStop;
152 }
153
Eric Christopher2325e382014-12-10 22:29:58 +0000154 Searcher::Depth
155 GetDepth () override
Greg Claytonbff78252013-03-11 18:42:51 +0000156 {
157 if (SetActualResolver())
158 return m_actual_resolver_sp->GetDepth();
159 else
160 return eDepthTarget;
161 }
162
Eric Christopher2325e382014-12-10 22:29:58 +0000163 void
164 GetDescription (Stream *s) override
Greg Claytonbff78252013-03-11 18:42:51 +0000165 {
166 s->Printf ("Exception breakpoint (catch: %s throw: %s)",
167 m_catch_bp ? "on" : "off",
168 m_throw_bp ? "on" : "off");
169
170 SetActualResolver();
171 if (m_actual_resolver_sp)
172 {
173 s->Printf (" using: ");
174 m_actual_resolver_sp->GetDescription (s);
175 }
176 else
177 s->Printf (" the correct runtime exception handler will be determined when you run");
178 }
179
Eric Christopher2325e382014-12-10 22:29:58 +0000180 void
181 Dump (Stream *s) const override
Greg Claytonbff78252013-03-11 18:42:51 +0000182 {
183 }
184
185 /// Methods for support type inquiry through isa, cast, and dyn_cast:
186 static inline bool classof(const BreakpointResolverName *) { return true; }
187 static inline bool classof(const BreakpointResolver *V) {
188 return V->getResolverID() == BreakpointResolver::ExceptionResolver;
189 }
Eugene Zelenko8f30a652015-10-23 18:39:37 +0000190
Greg Claytonbff78252013-03-11 18:42:51 +0000191protected:
Jim Ingham33df7cd2014-12-06 01:28:03 +0000192 BreakpointResolverSP
193 CopyForBreakpoint (Breakpoint &breakpoint) override
194 {
195 return BreakpointResolverSP(new ExceptionBreakpointResolver(m_language, m_catch_bp, m_throw_bp));
196 }
197
Greg Claytonbff78252013-03-11 18:42:51 +0000198 bool
199 SetActualResolver()
200 {
201 ProcessSP process_sp;
202 if (m_breakpoint)
203 {
204 process_sp = m_breakpoint->GetTarget().GetProcessSP();
205 if (process_sp)
206 {
207 bool refreash_resolver = !m_actual_resolver_sp;
208 if (m_language_runtime == NULL)
209 {
210 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
211 refreash_resolver = true;
212 }
213 else
214 {
215 LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
216 if (m_language_runtime != language_runtime)
217 {
218 m_language_runtime = language_runtime;
219 refreash_resolver = true;
220 }
221 }
222
223 if (refreash_resolver && m_language_runtime)
224 {
225 m_actual_resolver_sp = m_language_runtime->CreateExceptionResolver (m_breakpoint, m_catch_bp, m_throw_bp);
226 }
227 }
228 else
229 {
230 m_actual_resolver_sp.reset();
231 m_language_runtime = NULL;
232 }
233 }
234 else
235 {
236 m_actual_resolver_sp.reset();
237 m_language_runtime = NULL;
238 }
239 return (bool)m_actual_resolver_sp;
240 }
241 lldb::BreakpointResolverSP m_actual_resolver_sp;
242 lldb::LanguageType m_language;
243 LanguageRuntime *m_language_runtime;
244 bool m_catch_bp;
245 bool m_throw_bp;
246};
247
Jim Ingham22777012010-09-23 02:01:19 +0000248LanguageRuntime*
249LanguageRuntime::FindPlugin (Process *process, lldb::LanguageType language)
250{
Greg Clayton7b0992d2013-04-18 22:45:39 +0000251 std::unique_ptr<LanguageRuntime> language_runtime_ap;
Jim Ingham22777012010-09-23 02:01:19 +0000252 LanguageRuntimeCreateInstance create_callback;
253
254 for (uint32_t idx = 0;
255 (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != NULL;
256 ++idx)
257 {
258 language_runtime_ap.reset (create_callback(process, language));
259
260 if (language_runtime_ap.get())
261 return language_runtime_ap.release();
262 }
263
264 return NULL;
265}
266
Jim Ingham5a369122010-09-28 01:25:32 +0000267LanguageRuntime::LanguageRuntime(Process *process) :
268 m_process (process)
Jim Ingham22777012010-09-23 02:01:19 +0000269{
270}
271
Eugene Zelenko8f30a652015-10-23 18:39:37 +0000272LanguageRuntime::~LanguageRuntime() = default;
Jim Ingham219ba192012-03-05 04:47:34 +0000273
Jim Inghama72b31c2015-04-22 19:42:18 +0000274Breakpoint::BreakpointPreconditionSP
275LanguageRuntime::CreateExceptionPrecondition (lldb::LanguageType language,
276 bool catch_bp,
277 bool throw_bp)
278{
279 switch (language)
280 {
281 case eLanguageTypeObjC:
282 if (throw_bp)
283 return Breakpoint::BreakpointPreconditionSP(new ObjCLanguageRuntime::ObjCExceptionPrecondition ());
284 break;
285 default:
286 break;
287 }
288 return Breakpoint::BreakpointPreconditionSP();
289}
290
Jim Ingham219ba192012-03-05 04:47:34 +0000291BreakpointSP
Greg Claytonbff78252013-03-11 18:42:51 +0000292LanguageRuntime::CreateExceptionBreakpoint (Target &target,
293 lldb::LanguageType language,
294 bool catch_bp,
295 bool throw_bp,
296 bool is_internal)
Jim Ingham219ba192012-03-05 04:47:34 +0000297{
Greg Claytonbff78252013-03-11 18:42:51 +0000298 BreakpointResolverSP resolver_sp(new ExceptionBreakpointResolver(language, catch_bp, throw_bp));
299 SearchFilterSP filter_sp(new ExceptionSearchFilter(target.shared_from_this(), language));
Greg Claytoneb023e72013-10-11 19:48:25 +0000300 bool hardware = false;
Jim Ingham1460e4b2014-01-10 23:46:59 +0000301 bool resolve_indirect_functions = false;
302 BreakpointSP exc_breakpt_sp (target.CreateBreakpoint (filter_sp, resolver_sp, is_internal, hardware, resolve_indirect_functions));
Jim Inghama72b31c2015-04-22 19:42:18 +0000303 if (exc_breakpt_sp)
304 {
305 Breakpoint::BreakpointPreconditionSP precondition_sp = CreateExceptionPrecondition(language, catch_bp, throw_bp);
306 if (precondition_sp)
307 exc_breakpt_sp->SetPrecondition(precondition_sp);
308
309 if (is_internal)
310 exc_breakpt_sp->SetBreakpointKind("exception");
311 }
Jim Ingham219ba192012-03-05 04:47:34 +0000312
313 return exc_breakpt_sp;
314}
315
Colin Rileyc9c55a22015-05-04 18:39:38 +0000316void
317LanguageRuntime::InitializeCommands (CommandObject* parent)
318{
319 if (!parent)
320 return;
321
322 if (!parent->IsMultiwordObject())
323 return;
324
325 LanguageRuntimeCreateInstance create_callback;
326
327 for (uint32_t idx = 0;
328 (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != nullptr;
329 ++idx)
330 {
331 if (LanguageRuntimeGetCommandObject command_callback =
332 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(idx))
333 {
334 CommandObjectSP command = command_callback(parent->GetCommandInterpreter());
335 if (command)
336 {
337 parent->LoadSubCommand(command->GetCommandName(), command);
338 }
339 }
340 }
341}
342
Greg Claytonbff78252013-03-11 18:42:51 +0000343lldb::SearchFilterSP
344LanguageRuntime::CreateExceptionSearchFilter ()
345{
346 return m_process->GetTarget().GetSearchFilterForModule(NULL);
347}