blob: f930f40ace65f0d2f2b4e7e0574db30d6d444f26 [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 Inghama72b31c2015-04-22 19:42:18 +000015#include "lldb/Target/ObjCLanguageRuntime.h"
Jim Ingham219ba192012-03-05 04:47:34 +000016#include "lldb/Target/Target.h"
Jim Ingham22777012010-09-23 02:01:19 +000017#include "lldb/Core/PluginManager.h"
Jim Ingham33df7cd2014-12-06 01:28:03 +000018#include "lldb/Core/SearchFilter.h"
Colin Rileyc9c55a22015-05-04 18:39:38 +000019#include "lldb/Interpreter/CommandInterpreter.h"
Jim Ingham22777012010-09-23 02:01:19 +000020
21using namespace lldb;
22using namespace lldb_private;
23
Greg Claytonbff78252013-03-11 18:42:51 +000024class ExceptionSearchFilter : public SearchFilter
25{
26public:
27 ExceptionSearchFilter (const lldb::TargetSP &target_sp,
Jim Ingham33df7cd2014-12-06 01:28:03 +000028 lldb::LanguageType language,
29 bool update_module_list = true) :
Greg Claytonbff78252013-03-11 18:42:51 +000030 SearchFilter (target_sp),
31 m_language (language),
32 m_language_runtime (NULL),
33 m_filter_sp ()
34 {
Jim Ingham33df7cd2014-12-06 01:28:03 +000035 if (update_module_list)
36 UpdateModuleListIfNeeded ();
Greg Claytonbff78252013-03-11 18:42:51 +000037 }
Jim Ingham33df7cd2014-12-06 01:28:03 +000038
Eugene Zelenko8f30a652015-10-23 18:39:37 +000039 ~ExceptionSearchFilter() override = default;
Jim Ingham33df7cd2014-12-06 01:28:03 +000040
Eric Christopher2325e382014-12-10 22:29:58 +000041 bool
42 ModulePasses (const lldb::ModuleSP &module_sp) override
Greg Claytonbff78252013-03-11 18:42:51 +000043 {
44 UpdateModuleListIfNeeded ();
45 if (m_filter_sp)
46 return m_filter_sp->ModulePasses (module_sp);
47 return false;
48 }
49
Eric Christopher2325e382014-12-10 22:29:58 +000050 bool
51 ModulePasses (const FileSpec &spec) override
Greg Claytonbff78252013-03-11 18:42:51 +000052 {
53 UpdateModuleListIfNeeded ();
54 if (m_filter_sp)
55 return m_filter_sp->ModulePasses (spec);
56 return false;
Greg Claytonbff78252013-03-11 18:42:51 +000057 }
58
Eric Christopher2325e382014-12-10 22:29:58 +000059 void
60 Search (Searcher &searcher) override
Greg Claytonbff78252013-03-11 18:42:51 +000061 {
62 UpdateModuleListIfNeeded ();
63 if (m_filter_sp)
64 m_filter_sp->Search (searcher);
65 }
66
Eric Christopher2325e382014-12-10 22:29:58 +000067 void
68 GetDescription (Stream *s) override
Greg Claytonbff78252013-03-11 18:42:51 +000069 {
70 UpdateModuleListIfNeeded ();
71 if (m_filter_sp)
72 m_filter_sp->GetDescription (s);
73 }
74
75protected:
76 LanguageType m_language;
77 LanguageRuntime *m_language_runtime;
78 SearchFilterSP m_filter_sp;
79
Jim Ingham33df7cd2014-12-06 01:28:03 +000080 SearchFilterSP
81 DoCopyForBreakpoint(Breakpoint &breakpoint) override
82 {
83 return SearchFilterSP(new ExceptionSearchFilter(TargetSP(), m_language, false));
84 }
85
Greg Claytonbff78252013-03-11 18:42:51 +000086 void
87 UpdateModuleListIfNeeded ()
88 {
89 ProcessSP process_sp (m_target_sp->GetProcessSP());
90 if (process_sp)
91 {
92 bool refreash_filter = !m_filter_sp;
93 if (m_language_runtime == NULL)
94 {
95 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
96 refreash_filter = true;
97 }
98 else
99 {
100 LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
101 if (m_language_runtime != language_runtime)
102 {
103 m_language_runtime = language_runtime;
104 refreash_filter = true;
105 }
106 }
107
108 if (refreash_filter && m_language_runtime)
109 {
110 m_filter_sp = m_language_runtime->CreateExceptionSearchFilter ();
111 }
112 }
113 else
114 {
115 m_filter_sp.reset();
116 m_language_runtime = NULL;
117 }
118 }
119};
120
121// The Target is the one that knows how to create breakpoints, so this function
122// is meant to be used either by the target or internally in Set/ClearExceptionBreakpoints.
123class ExceptionBreakpointResolver : public BreakpointResolver
124{
125public:
126 ExceptionBreakpointResolver (lldb::LanguageType language,
127 bool catch_bp,
128 bool throw_bp) :
129 BreakpointResolver (NULL, BreakpointResolver::ExceptionResolver),
130 m_language (language),
131 m_language_runtime (NULL),
132 m_catch_bp (catch_bp),
133 m_throw_bp (throw_bp)
134 {
135 }
136
Eugene Zelenko8f30a652015-10-23 18:39:37 +0000137 ~ExceptionBreakpointResolver() override = default;
138
Eric Christopher2325e382014-12-10 22:29:58 +0000139 Searcher::CallbackReturn
Greg Claytonbff78252013-03-11 18:42:51 +0000140 SearchCallback (SearchFilter &filter,
141 SymbolContext &context,
142 Address *addr,
Eric Christopher2325e382014-12-10 22:29:58 +0000143 bool containing) override
Greg Claytonbff78252013-03-11 18:42:51 +0000144 {
145
146 if (SetActualResolver())
147 return m_actual_resolver_sp->SearchCallback (filter, context, addr, containing);
148 else
149 return eCallbackReturnStop;
150 }
151
Eric Christopher2325e382014-12-10 22:29:58 +0000152 Searcher::Depth
153 GetDepth () override
Greg Claytonbff78252013-03-11 18:42:51 +0000154 {
155 if (SetActualResolver())
156 return m_actual_resolver_sp->GetDepth();
157 else
158 return eDepthTarget;
159 }
160
Eric Christopher2325e382014-12-10 22:29:58 +0000161 void
162 GetDescription (Stream *s) override
Greg Claytonbff78252013-03-11 18:42:51 +0000163 {
164 s->Printf ("Exception breakpoint (catch: %s throw: %s)",
165 m_catch_bp ? "on" : "off",
166 m_throw_bp ? "on" : "off");
167
168 SetActualResolver();
169 if (m_actual_resolver_sp)
170 {
171 s->Printf (" using: ");
172 m_actual_resolver_sp->GetDescription (s);
173 }
174 else
175 s->Printf (" the correct runtime exception handler will be determined when you run");
176 }
177
Eric Christopher2325e382014-12-10 22:29:58 +0000178 void
179 Dump (Stream *s) const override
Greg Claytonbff78252013-03-11 18:42:51 +0000180 {
181 }
182
183 /// Methods for support type inquiry through isa, cast, and dyn_cast:
184 static inline bool classof(const BreakpointResolverName *) { return true; }
185 static inline bool classof(const BreakpointResolver *V) {
186 return V->getResolverID() == BreakpointResolver::ExceptionResolver;
187 }
Eugene Zelenko8f30a652015-10-23 18:39:37 +0000188
Greg Claytonbff78252013-03-11 18:42:51 +0000189protected:
Jim Ingham33df7cd2014-12-06 01:28:03 +0000190 BreakpointResolverSP
191 CopyForBreakpoint (Breakpoint &breakpoint) override
192 {
193 return BreakpointResolverSP(new ExceptionBreakpointResolver(m_language, m_catch_bp, m_throw_bp));
194 }
195
Greg Claytonbff78252013-03-11 18:42:51 +0000196 bool
197 SetActualResolver()
198 {
199 ProcessSP process_sp;
200 if (m_breakpoint)
201 {
202 process_sp = m_breakpoint->GetTarget().GetProcessSP();
203 if (process_sp)
204 {
205 bool refreash_resolver = !m_actual_resolver_sp;
206 if (m_language_runtime == NULL)
207 {
208 m_language_runtime = process_sp->GetLanguageRuntime(m_language);
209 refreash_resolver = true;
210 }
211 else
212 {
213 LanguageRuntime *language_runtime = process_sp->GetLanguageRuntime(m_language);
214 if (m_language_runtime != language_runtime)
215 {
216 m_language_runtime = language_runtime;
217 refreash_resolver = true;
218 }
219 }
220
221 if (refreash_resolver && m_language_runtime)
222 {
223 m_actual_resolver_sp = m_language_runtime->CreateExceptionResolver (m_breakpoint, m_catch_bp, m_throw_bp);
224 }
225 }
226 else
227 {
228 m_actual_resolver_sp.reset();
229 m_language_runtime = NULL;
230 }
231 }
232 else
233 {
234 m_actual_resolver_sp.reset();
235 m_language_runtime = NULL;
236 }
237 return (bool)m_actual_resolver_sp;
238 }
239 lldb::BreakpointResolverSP m_actual_resolver_sp;
240 lldb::LanguageType m_language;
241 LanguageRuntime *m_language_runtime;
242 bool m_catch_bp;
243 bool m_throw_bp;
244};
245
Jim Ingham22777012010-09-23 02:01:19 +0000246LanguageRuntime*
247LanguageRuntime::FindPlugin (Process *process, lldb::LanguageType language)
248{
Greg Clayton7b0992d2013-04-18 22:45:39 +0000249 std::unique_ptr<LanguageRuntime> language_runtime_ap;
Jim Ingham22777012010-09-23 02:01:19 +0000250 LanguageRuntimeCreateInstance create_callback;
251
252 for (uint32_t idx = 0;
253 (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != NULL;
254 ++idx)
255 {
256 language_runtime_ap.reset (create_callback(process, language));
257
258 if (language_runtime_ap.get())
259 return language_runtime_ap.release();
260 }
261
262 return NULL;
263}
264
Jim Ingham5a369122010-09-28 01:25:32 +0000265LanguageRuntime::LanguageRuntime(Process *process) :
266 m_process (process)
Jim Ingham22777012010-09-23 02:01:19 +0000267{
268}
269
Eugene Zelenko8f30a652015-10-23 18:39:37 +0000270LanguageRuntime::~LanguageRuntime() = default;
Jim Ingham219ba192012-03-05 04:47:34 +0000271
Jim Inghama72b31c2015-04-22 19:42:18 +0000272Breakpoint::BreakpointPreconditionSP
273LanguageRuntime::CreateExceptionPrecondition (lldb::LanguageType language,
274 bool catch_bp,
275 bool throw_bp)
276{
277 switch (language)
278 {
279 case eLanguageTypeObjC:
280 if (throw_bp)
281 return Breakpoint::BreakpointPreconditionSP(new ObjCLanguageRuntime::ObjCExceptionPrecondition ());
282 break;
283 default:
284 break;
285 }
286 return Breakpoint::BreakpointPreconditionSP();
287}
288
Jim Ingham219ba192012-03-05 04:47:34 +0000289BreakpointSP
Greg Claytonbff78252013-03-11 18:42:51 +0000290LanguageRuntime::CreateExceptionBreakpoint (Target &target,
291 lldb::LanguageType language,
292 bool catch_bp,
293 bool throw_bp,
294 bool is_internal)
Jim Ingham219ba192012-03-05 04:47:34 +0000295{
Greg Claytonbff78252013-03-11 18:42:51 +0000296 BreakpointResolverSP resolver_sp(new ExceptionBreakpointResolver(language, catch_bp, throw_bp));
297 SearchFilterSP filter_sp(new ExceptionSearchFilter(target.shared_from_this(), language));
Greg Claytoneb023e72013-10-11 19:48:25 +0000298 bool hardware = false;
Jim Ingham1460e4b2014-01-10 23:46:59 +0000299 bool resolve_indirect_functions = false;
300 BreakpointSP exc_breakpt_sp (target.CreateBreakpoint (filter_sp, resolver_sp, is_internal, hardware, resolve_indirect_functions));
Jim Inghama72b31c2015-04-22 19:42:18 +0000301 if (exc_breakpt_sp)
302 {
303 Breakpoint::BreakpointPreconditionSP precondition_sp = CreateExceptionPrecondition(language, catch_bp, throw_bp);
304 if (precondition_sp)
305 exc_breakpt_sp->SetPrecondition(precondition_sp);
306
307 if (is_internal)
308 exc_breakpt_sp->SetBreakpointKind("exception");
309 }
Jim Ingham219ba192012-03-05 04:47:34 +0000310
311 return exc_breakpt_sp;
312}
313
Colin Rileyc9c55a22015-05-04 18:39:38 +0000314void
315LanguageRuntime::InitializeCommands (CommandObject* parent)
316{
317 if (!parent)
318 return;
319
320 if (!parent->IsMultiwordObject())
321 return;
322
323 LanguageRuntimeCreateInstance create_callback;
324
325 for (uint32_t idx = 0;
326 (create_callback = PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(idx)) != nullptr;
327 ++idx)
328 {
329 if (LanguageRuntimeGetCommandObject command_callback =
330 PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(idx))
331 {
332 CommandObjectSP command = command_callback(parent->GetCommandInterpreter());
333 if (command)
334 {
335 parent->LoadSubCommand(command->GetCommandName(), command);
336 }
337 }
338 }
339}
340
Greg Claytonbff78252013-03-11 18:42:51 +0000341lldb::SearchFilterSP
342LanguageRuntime::CreateExceptionSearchFilter ()
343{
344 return m_process->GetTarget().GetSearchFilterForModule(NULL);
345}