blob: f2ad815214ac835cf43a2cf32d53421d8333875b [file] [log] [blame]
Jim Ingham22777012010-09-23 02:01:19 +00001//===-- LanguageRuntime.cpp -------------------------------------------------*- C++ -*-===//
2//
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
10#include "lldb/Target/LanguageRuntime.h"
Jim Inghama72b31c2015-04-22 19:42:18 +000011#include "lldb/Target/ObjCLanguageRuntime.h"
Jim Ingham219ba192012-03-05 04:47:34 +000012#include "lldb/Target/Target.h"
Jim Ingham22777012010-09-23 02:01:19 +000013#include "lldb/Core/PluginManager.h"
Jim Ingham33df7cd2014-12-06 01:28:03 +000014#include "lldb/Core/SearchFilter.h"
Colin Rileyc9c55a22015-05-04 18:39:38 +000015#include "lldb/Interpreter/CommandInterpreter.h"
Jim Ingham22777012010-09-23 02:01:19 +000016
17using namespace lldb;
18using namespace lldb_private;
19
Greg Claytonbff78252013-03-11 18:42:51 +000020
21class ExceptionSearchFilter : public SearchFilter
22{
23public:
24 ExceptionSearchFilter (const lldb::TargetSP &target_sp,
Jim Ingham33df7cd2014-12-06 01:28:03 +000025 lldb::LanguageType language,
26 bool update_module_list = true) :
Greg Claytonbff78252013-03-11 18:42:51 +000027 SearchFilter (target_sp),
28 m_language (language),
29 m_language_runtime (NULL),
30 m_filter_sp ()
31 {
Jim Ingham33df7cd2014-12-06 01:28:03 +000032 if (update_module_list)
33 UpdateModuleListIfNeeded ();
Greg Claytonbff78252013-03-11 18:42:51 +000034 }
Jim Ingham33df7cd2014-12-06 01:28:03 +000035
36 virtual
Pavel Labathcb213b32015-07-22 08:12:01 +000037 ~ExceptionSearchFilter() {}
Jim Ingham33df7cd2014-12-06 01:28:03 +000038
Eric Christopher2325e382014-12-10 22:29:58 +000039 bool
40 ModulePasses (const lldb::ModuleSP &module_sp) override
Greg Claytonbff78252013-03-11 18:42:51 +000041 {
42 UpdateModuleListIfNeeded ();
43 if (m_filter_sp)
44 return m_filter_sp->ModulePasses (module_sp);
45 return false;
46 }
47
Eric Christopher2325e382014-12-10 22:29:58 +000048 bool
49 ModulePasses (const FileSpec &spec) override
Greg Claytonbff78252013-03-11 18:42:51 +000050 {
51 UpdateModuleListIfNeeded ();
52 if (m_filter_sp)
53 return m_filter_sp->ModulePasses (spec);
54 return false;
55
56 }
57
Eric Christopher2325e382014-12-10 22:29:58 +000058 void
59 Search (Searcher &searcher) override
Greg Claytonbff78252013-03-11 18:42:51 +000060 {
61 UpdateModuleListIfNeeded ();
62 if (m_filter_sp)
63 m_filter_sp->Search (searcher);
64 }
65
Eric Christopher2325e382014-12-10 22:29:58 +000066 void
67 GetDescription (Stream *s) override
Greg Claytonbff78252013-03-11 18:42:51 +000068 {
69 UpdateModuleListIfNeeded ();
70 if (m_filter_sp)
71 m_filter_sp->GetDescription (s);
72 }
73
74protected:
75 LanguageType m_language;
76 LanguageRuntime *m_language_runtime;
77 SearchFilterSP m_filter_sp;
78
Jim Ingham33df7cd2014-12-06 01:28:03 +000079 SearchFilterSP
80 DoCopyForBreakpoint(Breakpoint &breakpoint) override
81 {
82 return SearchFilterSP(new ExceptionSearchFilter(TargetSP(), m_language, false));
83 }
84
Greg Claytonbff78252013-03-11 18:42:51 +000085 void
86 UpdateModuleListIfNeeded ()
87 {
88 ProcessSP process_sp (m_target_sp->GetProcessSP());
89 if (process_sp)
90 {
91 bool refreash_filter = !m_filter_sp;
92 if (m_language_runtime == NULL)
93 {
94 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
95 refreash_filter = true;
96 }
97 else
98 {
99 LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
100 if (m_language_runtime != language_runtime)
101 {
102 m_language_runtime = language_runtime;
103 refreash_filter = true;
104 }
105 }
106
107 if (refreash_filter && m_language_runtime)
108 {
109 m_filter_sp = m_language_runtime->CreateExceptionSearchFilter ();
110 }
111 }
112 else
113 {
114 m_filter_sp.reset();
115 m_language_runtime = NULL;
116 }
117 }
118};
119
120// The Target is the one that knows how to create breakpoints, so this function
121// is meant to be used either by the target or internally in Set/ClearExceptionBreakpoints.
122class ExceptionBreakpointResolver : public BreakpointResolver
123{
124public:
125 ExceptionBreakpointResolver (lldb::LanguageType language,
126 bool catch_bp,
127 bool throw_bp) :
128 BreakpointResolver (NULL, BreakpointResolver::ExceptionResolver),
129 m_language (language),
130 m_language_runtime (NULL),
131 m_catch_bp (catch_bp),
132 m_throw_bp (throw_bp)
133 {
134 }
135
136 virtual
137 ~ExceptionBreakpointResolver()
138 {
139 }
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 }
190protected:
Jim Ingham33df7cd2014-12-06 01:28:03 +0000191 BreakpointResolverSP
192 CopyForBreakpoint (Breakpoint &breakpoint) override
193 {
194 return BreakpointResolverSP(new ExceptionBreakpointResolver(m_language, m_catch_bp, m_throw_bp));
195 }
196
Greg Claytonbff78252013-03-11 18:42:51 +0000197 bool
198 SetActualResolver()
199 {
200 ProcessSP process_sp;
201 if (m_breakpoint)
202 {
203 process_sp = m_breakpoint->GetTarget().GetProcessSP();
204 if (process_sp)
205 {
206 bool refreash_resolver = !m_actual_resolver_sp;
207 if (m_language_runtime == NULL)
208 {
209 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
210 refreash_resolver = true;
211 }
212 else
213 {
214 LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
215 if (m_language_runtime != language_runtime)
216 {
217 m_language_runtime = language_runtime;
218 refreash_resolver = true;
219 }
220 }
221
222 if (refreash_resolver && m_language_runtime)
223 {
224 m_actual_resolver_sp = m_language_runtime->CreateExceptionResolver (m_breakpoint, m_catch_bp, m_throw_bp);
225 }
226 }
227 else
228 {
229 m_actual_resolver_sp.reset();
230 m_language_runtime = NULL;
231 }
232 }
233 else
234 {
235 m_actual_resolver_sp.reset();
236 m_language_runtime = NULL;
237 }
238 return (bool)m_actual_resolver_sp;
239 }
240 lldb::BreakpointResolverSP m_actual_resolver_sp;
241 lldb::LanguageType m_language;
242 LanguageRuntime *m_language_runtime;
243 bool m_catch_bp;
244 bool m_throw_bp;
245};
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
267//----------------------------------------------------------------------
268// Constructor
269//----------------------------------------------------------------------
Jim Ingham5a369122010-09-28 01:25:32 +0000270LanguageRuntime::LanguageRuntime(Process *process) :
271 m_process (process)
Jim Ingham22777012010-09-23 02:01:19 +0000272{
273}
274
275//----------------------------------------------------------------------
276// Destructor
277//----------------------------------------------------------------------
278LanguageRuntime::~LanguageRuntime()
279{
280}
Jim Ingham219ba192012-03-05 04:47:34 +0000281
Jim Inghama72b31c2015-04-22 19:42:18 +0000282Breakpoint::BreakpointPreconditionSP
283LanguageRuntime::CreateExceptionPrecondition (lldb::LanguageType language,
284 bool catch_bp,
285 bool throw_bp)
286{
287 switch (language)
288 {
289 case eLanguageTypeObjC:
290 if (throw_bp)
291 return Breakpoint::BreakpointPreconditionSP(new ObjCLanguageRuntime::ObjCExceptionPrecondition ());
292 break;
293 default:
294 break;
295 }
296 return Breakpoint::BreakpointPreconditionSP();
297}
298
Jim Ingham219ba192012-03-05 04:47:34 +0000299BreakpointSP
Greg Claytonbff78252013-03-11 18:42:51 +0000300LanguageRuntime::CreateExceptionBreakpoint (Target &target,
301 lldb::LanguageType language,
302 bool catch_bp,
303 bool throw_bp,
304 bool is_internal)
Jim Ingham219ba192012-03-05 04:47:34 +0000305{
Greg Claytonbff78252013-03-11 18:42:51 +0000306 BreakpointResolverSP resolver_sp(new ExceptionBreakpointResolver(language, catch_bp, throw_bp));
307 SearchFilterSP filter_sp(new ExceptionSearchFilter(target.shared_from_this(), language));
Greg Claytoneb023e72013-10-11 19:48:25 +0000308 bool hardware = false;
Jim Ingham1460e4b2014-01-10 23:46:59 +0000309 bool resolve_indirect_functions = false;
310 BreakpointSP exc_breakpt_sp (target.CreateBreakpoint (filter_sp, resolver_sp, is_internal, hardware, resolve_indirect_functions));
Jim Inghama72b31c2015-04-22 19:42:18 +0000311 if (exc_breakpt_sp)
312 {
313 Breakpoint::BreakpointPreconditionSP precondition_sp = CreateExceptionPrecondition(language, catch_bp, throw_bp);
314 if (precondition_sp)
315 exc_breakpt_sp->SetPrecondition(precondition_sp);
316
317 if (is_internal)
318 exc_breakpt_sp->SetBreakpointKind("exception");
319 }
Jim Ingham219ba192012-03-05 04:47:34 +0000320
321 return exc_breakpt_sp;
322}
323
Colin Rileyc9c55a22015-05-04 18:39:38 +0000324void
325LanguageRuntime::InitializeCommands (CommandObject* parent)
326{
327 if (!parent)
328 return;
329
330 if (!parent->IsMultiwordObject())
331 return;
332
333 LanguageRuntimeCreateInstance create_callback;
334
335 for (uint32_t idx = 0;
336 (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != nullptr;
337 ++idx)
338 {
339 if (LanguageRuntimeGetCommandObject command_callback =
340 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(idx))
341 {
342 CommandObjectSP command = command_callback(parent->GetCommandInterpreter());
343 if (command)
344 {
345 parent->LoadSubCommand(command->GetCommandName(), command);
346 }
347 }
348 }
349}
350
Greg Claytonbff78252013-03-11 18:42:51 +0000351lldb::SearchFilterSP
352LanguageRuntime::CreateExceptionSearchFilter ()
353{
354 return m_process->GetTarget().GetSearchFilterForModule(NULL);
355}