blob: 1959712274d4a361bf27dcd5d12c5e5997d015b7 [file] [log] [blame]
Colin Riley5ec532a2015-04-09 16:49:25 +00001//===-- RenderScriptRuntime.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 "RenderScriptRuntime.h"
11
12#include "lldb/Core/ConstString.h"
13#include "lldb/Core/Debugger.h"
14#include "lldb/Core/Error.h"
15#include "lldb/Core/Log.h"
16#include "lldb/Core/PluginManager.h"
17#include "lldb/Symbol/Symbol.h"
Colin Riley4640cde2015-06-01 18:23:41 +000018#include "lldb/Symbol/Type.h"
Colin Riley5ec532a2015-04-09 16:49:25 +000019#include "lldb/Target/Process.h"
20#include "lldb/Target/Target.h"
21#include "lldb/Interpreter/Args.h"
22#include "lldb/Interpreter/Options.h"
23#include "lldb/Interpreter/CommandInterpreter.h"
24#include "lldb/Interpreter/CommandReturnObject.h"
25#include "lldb/Interpreter/CommandObjectMultiword.h"
Colin Riley4640cde2015-06-01 18:23:41 +000026#include "lldb/Breakpoint/StoppointCallbackContext.h"
27#include "lldb/Target/RegisterContext.h"
28
29#include "lldb/Symbol/VariableList.h"
Colin Riley5ec532a2015-04-09 16:49:25 +000030
31using namespace lldb;
32using namespace lldb_private;
Ewan Crawford98156582015-09-04 08:56:52 +000033using namespace lldb_renderscript;
Colin Riley5ec532a2015-04-09 16:49:25 +000034
35//------------------------------------------------------------------
36// Static Functions
37//------------------------------------------------------------------
38LanguageRuntime *
39RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType language)
40{
41
42 if (language == eLanguageTypeExtRenderScript)
43 return new RenderScriptRuntime(process);
44 else
45 return NULL;
46}
47
Ewan Crawford98156582015-09-04 08:56:52 +000048// Callback with a module to search for matching symbols.
49// We first check that the module contains RS kernels.
50// Then look for a symbol which matches our kernel name.
51// The breakpoint address is finally set using the address of this symbol.
52Searcher::CallbackReturn
53RSBreakpointResolver::SearchCallback(SearchFilter &filter,
54 SymbolContext &context,
55 Address*,
56 bool)
57{
58 ModuleSP module = context.module_sp;
59
60 if (!module)
61 return Searcher::eCallbackReturnContinue;
62
63 // Is this a module containing renderscript kernels?
64 if (nullptr == module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData))
65 return Searcher::eCallbackReturnContinue;
66
67 // Attempt to set a breakpoint on the kernel name symbol within the module library.
68 // If it's not found, it's likely debug info is unavailable - try to set a
69 // breakpoint on <name>.expand.
70
71 const Symbol* kernel_sym = module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode);
72 if (!kernel_sym)
73 {
74 std::string kernel_name_expanded(m_kernel_name.AsCString());
75 kernel_name_expanded.append(".expand");
76 kernel_sym = module->FindFirstSymbolWithNameAndType(ConstString(kernel_name_expanded.c_str()), eSymbolTypeCode);
77 }
78
79 if (kernel_sym)
80 {
81 Address bp_addr = kernel_sym->GetAddress();
82 if (filter.AddressPasses(bp_addr))
83 m_breakpoint->AddLocation(bp_addr);
84 }
85
86 return Searcher::eCallbackReturnContinue;
87}
88
Colin Riley5ec532a2015-04-09 16:49:25 +000089void
90RenderScriptRuntime::Initialize()
91{
Colin Riley4640cde2015-06-01 18:23:41 +000092 PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance, GetCommandObject);
Colin Riley5ec532a2015-04-09 16:49:25 +000093}
94
95void
96RenderScriptRuntime::Terminate()
97{
98 PluginManager::UnregisterPlugin(CreateInstance);
99}
100
101lldb_private::ConstString
102RenderScriptRuntime::GetPluginNameStatic()
103{
104 static ConstString g_name("renderscript");
105 return g_name;
106}
107
Colin Rileyef20b082015-04-14 07:39:24 +0000108RenderScriptRuntime::ModuleKind
109RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp)
110{
111 if (module_sp)
112 {
113 // Is this a module containing renderscript kernels?
114 const Symbol *info_sym = module_sp->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
115 if (info_sym)
116 {
117 return eModuleKindKernelObj;
118 }
Colin Riley4640cde2015-06-01 18:23:41 +0000119
120 // Is this the main RS runtime library
121 const ConstString rs_lib("libRS.so");
122 if (module_sp->GetFileSpec().GetFilename() == rs_lib)
123 {
124 return eModuleKindLibRS;
125 }
126
127 const ConstString rs_driverlib("libRSDriver.so");
128 if (module_sp->GetFileSpec().GetFilename() == rs_driverlib)
129 {
130 return eModuleKindDriver;
131 }
132
133 const ConstString rs_cpureflib("libRSCPURef.so");
134 if (module_sp->GetFileSpec().GetFilename() == rs_cpureflib)
135 {
136 return eModuleKindImpl;
137 }
138
Colin Rileyef20b082015-04-14 07:39:24 +0000139 }
140 return eModuleKindIgnored;
141}
142
143bool
144RenderScriptRuntime::IsRenderScriptModule(const lldb::ModuleSP &module_sp)
145{
146 return GetModuleKind(module_sp) != eModuleKindIgnored;
147}
148
149
150void
151RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list )
152{
153 Mutex::Locker locker (module_list.GetMutex ());
154
155 size_t num_modules = module_list.GetSize();
156 for (size_t i = 0; i < num_modules; i++)
157 {
158 auto mod = module_list.GetModuleAtIndex (i);
159 if (IsRenderScriptModule (mod))
160 {
161 LoadModule(mod);
162 }
163 }
164}
165
166
Colin Riley5ec532a2015-04-09 16:49:25 +0000167//------------------------------------------------------------------
168// PluginInterface protocol
169//------------------------------------------------------------------
170lldb_private::ConstString
171RenderScriptRuntime::GetPluginName()
172{
173 return GetPluginNameStatic();
174}
175
176uint32_t
177RenderScriptRuntime::GetPluginVersion()
178{
179 return 1;
180}
181
182bool
183RenderScriptRuntime::IsVTableName(const char *name)
184{
185 return false;
186}
187
188bool
189RenderScriptRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
190 TypeAndOrName &class_type_or_name, Address &address)
191{
192 return false;
193}
194
195bool
196RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value)
197{
198 return false;
199}
200
201lldb::BreakpointResolverSP
202RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp)
203{
204 BreakpointResolverSP resolver_sp;
205 return resolver_sp;
206}
207
Colin Riley4640cde2015-06-01 18:23:41 +0000208
209const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] =
210{
211 //rsdScript
212 {"rsdScriptInit", "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhjj", 0, RenderScriptRuntime::eModuleKindDriver, &lldb_private::RenderScriptRuntime::CaptureScriptInit1},
213 {"rsdScriptInvokeForEach", "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvjPK12RsScriptCall", 0, RenderScriptRuntime::eModuleKindDriver, nullptr},
214 {"rsdScriptInvokeForEachMulti", "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall", 0, RenderScriptRuntime::eModuleKindDriver, nullptr},
215 {"rsdScriptInvokeFunction", "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvj", 0, RenderScriptRuntime::eModuleKindDriver, nullptr},
216 {"rsdScriptSetGlobalVar", "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvj", 0, RenderScriptRuntime::eModuleKindDriver, &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar1},
217
218 //rsdAllocation
219 {"rsdAllocationInit", "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", 0, RenderScriptRuntime::eModuleKindDriver, &lldb_private::RenderScriptRuntime::CaptureAllocationInit1},
220 {"rsdAllocationRead2D", "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvjj", 0, RenderScriptRuntime::eModuleKindDriver, nullptr},
221};
222const size_t RenderScriptRuntime::s_runtimeHookCount = sizeof(s_runtimeHookDefns)/sizeof(s_runtimeHookDefns[0]);
223
224
225bool
226RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
227{
228 RuntimeHook* hook_info = (RuntimeHook*)baton;
229 ExecutionContext context(ctx->exe_ctx_ref);
230
231 RenderScriptRuntime *lang_rt = (RenderScriptRuntime *)context.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
232
233 lang_rt->HookCallback(hook_info, context);
234
235 return false;
236}
237
238
239void
240RenderScriptRuntime::HookCallback(RuntimeHook* hook_info, ExecutionContext& context)
241{
242 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
243
244 if(log)
245 log->Printf ("RenderScriptRuntime::HookCallback - '%s' .", hook_info->defn->name);
246
247 if (hook_info->defn->grabber)
248 {
249 (this->*(hook_info->defn->grabber))(hook_info, context);
250 }
251}
252
253
254bool
255RenderScriptRuntime::GetArg32Simple(ExecutionContext& context, uint32_t arg, uint32_t *data)
256{
257 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
258
259 if (!data)
260 return false;
261
262 Error error;
263 RegisterContext* reg_ctx = context.GetRegisterContext();
264 Process* process = context.GetProcessPtr();
265
266 if (context.GetTargetPtr()->GetArchitecture().GetMachine() == llvm::Triple::ArchType::x86)
267 {
268 uint64_t sp = reg_ctx->GetSP();
269 {
270 uint32_t offset = (1 + arg) * sizeof(uint32_t);
271 process->ReadMemory(sp + offset, data, sizeof(uint32_t), error);
272 if(error.Fail())
273 {
274 if(log)
275 log->Printf ("RenderScriptRuntime:: GetArg32Simple - error reading X86 stack: %s.", error.AsCString());
276 }
277 }
278 }
279 else if (context.GetTargetPtr()->GetArchitecture().GetMachine() == llvm::Triple::ArchType::arm)
280 {
281 if (arg < 4)
282 {
283 const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg);
284 RegisterValue rVal;
285 reg_ctx->ReadRegister(rArg, rVal);
286 (*data) = rVal.GetAsUInt32();
287 }
288 else
289 {
290 uint64_t sp = reg_ctx->GetSP();
291 {
292 uint32_t offset = (arg-4) * sizeof(uint32_t);
293 process->ReadMemory(sp + offset, &data, sizeof(uint32_t), error);
294 if(error.Fail())
295 {
296 if(log)
297 log->Printf ("RenderScriptRuntime:: GetArg32Simple - error reading ARM stack: %s.", error.AsCString());
298 }
299 }
300 }
301 }
302 return true;
303}
304
305void
306RenderScriptRuntime::CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context)
307{
308 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
309
310 //Context, Script, int, data, length
311
312 Error error;
313
314 uint32_t rs_context_u32 = 0U;
315 uint32_t rs_script_u32 = 0U;
316 uint32_t rs_id_u32 = 0U;
317 uint32_t rs_data_u32 = 0U;
318 uint32_t rs_length_u32 = 0U;
319
320 std::string resname;
321 std::string cachedir;
322
323 GetArg32Simple(context, 0, &rs_context_u32);
324 GetArg32Simple(context, 1, &rs_script_u32);
325 GetArg32Simple(context, 2, &rs_id_u32);
326 GetArg32Simple(context, 3, &rs_data_u32);
327 GetArg32Simple(context, 4, &rs_length_u32);
328
329 if(log)
330 {
331 log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 ":%" PRIu64 "bytes.",
332 (uint64_t)rs_context_u32, (uint64_t)rs_script_u32, (uint64_t)rs_id_u32, (uint64_t)rs_data_u32, (uint64_t)rs_length_u32);
333
334 addr_t script_addr = (addr_t)rs_script_u32;
335 if (m_scriptMappings.find( script_addr ) != m_scriptMappings.end())
336 {
337 auto rsm = m_scriptMappings[script_addr];
338 if (rs_id_u32 < rsm->m_globals.size())
339 {
340 auto rsg = rsm->m_globals[rs_id_u32];
341 log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - Setting of '%s' within '%s' inferred", rsg.m_name.AsCString(),
342 rsm->m_module->GetFileSpec().GetFilename().AsCString());
343 }
344 }
345 }
346}
347
348void
349RenderScriptRuntime::CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context)
350{
351 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
352
353 //Context, Alloc, bool
354
355 Error error;
356
357 uint32_t rs_context_u32 = 0U;
358 uint32_t rs_alloc_u32 = 0U;
359 uint32_t rs_forceZero_u32 = 0U;
360
361 GetArg32Simple(context, 0, &rs_context_u32);
362 GetArg32Simple(context, 1, &rs_alloc_u32);
363 GetArg32Simple(context, 2, &rs_forceZero_u32);
364
365 if(log)
366 log->Printf ("RenderScriptRuntime::CaptureAllocationInit1 - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .",
367 (uint64_t)rs_context_u32, (uint64_t)rs_alloc_u32, (uint64_t)rs_forceZero_u32);
368}
369
370void
371RenderScriptRuntime::CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context)
372{
373 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
374
375 //Context, Script, resname Str, cachedir Str
376 Error error;
377 Process* process = context.GetProcessPtr();
378
379 uint32_t rs_context_u32 = 0U;
380 uint32_t rs_script_u32 = 0U;
381 uint32_t rs_resnameptr_u32 = 0U;
382 uint32_t rs_cachedirptr_u32 = 0U;
383
384 std::string resname;
385 std::string cachedir;
386
387 GetArg32Simple(context, 0, &rs_context_u32);
388 GetArg32Simple(context, 1, &rs_script_u32);
389 GetArg32Simple(context, 2, &rs_resnameptr_u32);
390 GetArg32Simple(context, 3, &rs_cachedirptr_u32);
391
392 process->ReadCStringFromMemory((lldb::addr_t)rs_resnameptr_u32, resname, error);
393 if (error.Fail())
394 {
395 if(log)
396 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading resname: %s.", error.AsCString());
397
398 }
399
400 process->ReadCStringFromMemory((lldb::addr_t)rs_cachedirptr_u32, cachedir, error);
401 if (error.Fail())
402 {
403 if(log)
404 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading cachedir: %s.", error.AsCString());
405 }
406
407 if (log)
408 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .",
409 (uint64_t)rs_context_u32, (uint64_t)rs_script_u32, resname.c_str(), cachedir.c_str());
410
411 if (resname.size() > 0)
412 {
413 StreamString strm;
414 strm.Printf("librs.%s.so", resname.c_str());
415
416 ScriptDetails script;
417 script.cachedir = cachedir;
418 script.resname = resname;
419 script.scriptDyLib.assign(strm.GetData());
420 script.script = rs_script_u32;
421 script.context = rs_context_u32;
422
423 m_scripts.push_back(script);
424
425 if (log)
426 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - '%s' tagged with context 0x%" PRIx64 " and script 0x%" PRIx64 ".",
427 strm.GetData(), (uint64_t)rs_context_u32, (uint64_t)rs_script_u32);
428 }
429 else if (log)
430 {
431 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - resource name invalid, Script not tagged");
432 }
433
434}
435
436
437void
438RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
439{
440 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
441
442 if (!module)
443 {
444 return;
445 }
446
447 if ((GetProcess()->GetTarget().GetArchitecture().GetMachine() != llvm::Triple::ArchType::x86)
448 && (GetProcess()->GetTarget().GetArchitecture().GetMachine() != llvm::Triple::ArchType::arm))
449 {
450 if (log)
451 log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to hook runtime. Only X86, ARM supported currently.");
452
453 return;
454 }
455
456 Target &target = GetProcess()->GetTarget();
457
458 for (size_t idx = 0; idx < s_runtimeHookCount; idx++)
459 {
460 const HookDefn* hook_defn = &s_runtimeHookDefns[idx];
461 if (hook_defn->kind != kind) {
462 continue;
463 }
464
465 const Symbol *sym = module->FindFirstSymbolWithNameAndType(ConstString(hook_defn->symbol_name), eSymbolTypeCode);
466
Greg Clayton358cf1e2015-06-25 21:46:34 +0000467 addr_t addr = sym->GetLoadAddress(&target);
Colin Riley4640cde2015-06-01 18:23:41 +0000468 if (addr == LLDB_INVALID_ADDRESS)
469 {
470 if(log)
471 log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to resolve the address of hook function '%s' with symbol '%s'.",
472 hook_defn->name, hook_defn->symbol_name);
473 continue;
474 }
475
476 RuntimeHookSP hook(new RuntimeHook());
477 hook->address = addr;
478 hook->defn = hook_defn;
479 hook->bp_sp = target.CreateBreakpoint(addr, true, false);
480 hook->bp_sp->SetCallback(HookCallback, hook.get(), true);
481 m_runtimeHooks[addr] = hook;
482 if (log)
483 {
484 log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Successfully hooked '%s' in '%s' version %" PRIu64 " at 0x%" PRIx64 ".",
485 hook_defn->name, module->GetFileSpec().GetFilename().AsCString(), (uint64_t)hook_defn->version, (uint64_t)addr);
486 }
487 }
488}
489
490void
491RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp)
492{
493 if (!rsmodule_sp)
494 return;
495
496 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
497
498 const ModuleSP module = rsmodule_sp->m_module;
499 const FileSpec& file = module->GetPlatformFileSpec();
500
501 for (const auto &rs_script : m_scripts)
502 {
503 if (file.GetFilename() == ConstString(rs_script.scriptDyLib.c_str()))
504 {
505 if (m_scriptMappings.find( rs_script.script ) != m_scriptMappings.end())
506 {
507 if (m_scriptMappings[rs_script.script] != rsmodule_sp)
508 {
509 if (log)
510 {
511 log->Printf ("RenderScriptRuntime::FixupScriptDetails - Error: script %" PRIx64 " wants reassigned to new rsmodule '%s'.",
512 (uint64_t)rs_script.script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
513 }
514 }
515 }
516 else
517 {
518 m_scriptMappings[rs_script.script] = rsmodule_sp;
519 rsmodule_sp->m_resname = rs_script.resname;
520 if (log)
521 {
522 log->Printf ("RenderScriptRuntime::FixupScriptDetails - script %" PRIx64 " associated with rsmodule '%s'.",
523 (uint64_t)rs_script.script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
524 }
525 }
526 }
527 }
528
529}
530
Colin Riley5ec532a2015-04-09 16:49:25 +0000531bool
532RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
533{
Colin Riley4640cde2015-06-01 18:23:41 +0000534 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
535
Colin Riley5ec532a2015-04-09 16:49:25 +0000536 if (module_sp)
537 {
538 for (const auto &rs_module : m_rsmodules)
539 {
Colin Riley4640cde2015-06-01 18:23:41 +0000540 if (rs_module->m_module == module_sp)
Colin Riley5ec532a2015-04-09 16:49:25 +0000541 return false;
542 }
Colin Rileyef20b082015-04-14 07:39:24 +0000543 bool module_loaded = false;
544 switch (GetModuleKind(module_sp))
Colin Riley5ec532a2015-04-09 16:49:25 +0000545 {
Colin Rileyef20b082015-04-14 07:39:24 +0000546 case eModuleKindKernelObj:
547 {
Colin Riley4640cde2015-06-01 18:23:41 +0000548 RSModuleDescriptorSP module_desc;
549 module_desc.reset(new RSModuleDescriptor(module_sp));
550 if (module_desc->ParseRSInfo())
Colin Rileyef20b082015-04-14 07:39:24 +0000551 {
552 m_rsmodules.push_back(module_desc);
553 module_loaded = true;
554 }
Colin Riley4640cde2015-06-01 18:23:41 +0000555 if (module_loaded)
556 {
557 FixupScriptDetails(module_desc);
558 }
Colin Rileyef20b082015-04-14 07:39:24 +0000559 break;
560 }
561 case eModuleKindDriver:
Colin Riley4640cde2015-06-01 18:23:41 +0000562 {
563 if (!m_libRSDriver)
564 {
565 m_libRSDriver = module_sp;
566 LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver);
567 }
568 break;
569 }
Colin Rileyef20b082015-04-14 07:39:24 +0000570 case eModuleKindImpl:
Colin Riley4640cde2015-06-01 18:23:41 +0000571 {
572 m_libRSCpuRef = module_sp;
573 break;
574 }
Colin Rileyef20b082015-04-14 07:39:24 +0000575 case eModuleKindLibRS:
Colin Riley4640cde2015-06-01 18:23:41 +0000576 {
577 if (!m_libRS)
578 {
579 m_libRS = module_sp;
580 static ConstString gDbgPresentStr("gDebuggerPresent");
581 const Symbol* debug_present = m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData);
582 if (debug_present)
583 {
584 Error error;
585 uint32_t flag = 0x00000001U;
586 Target &target = GetProcess()->GetTarget();
Greg Clayton358cf1e2015-06-25 21:46:34 +0000587 addr_t addr = debug_present->GetLoadAddress(&target);
Colin Riley4640cde2015-06-01 18:23:41 +0000588 GetProcess()->WriteMemory(addr, &flag, sizeof(flag), error);
589 if(error.Success())
590 {
591 if (log)
592 log->Printf ("RenderScriptRuntime::LoadModule - Debugger present flag set on debugee");
593
594 m_debuggerPresentFlagged = true;
595 }
596 else if (log)
597 {
598 log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags '%s' ", error.AsCString());
599 }
600 }
601 else if (log)
602 {
603 log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags - symbol not found");
604 }
605 }
606 break;
607 }
Colin Rileyef20b082015-04-14 07:39:24 +0000608 default:
609 break;
Colin Riley5ec532a2015-04-09 16:49:25 +0000610 }
Colin Rileyef20b082015-04-14 07:39:24 +0000611 if (module_loaded)
612 Update();
613 return module_loaded;
Colin Riley5ec532a2015-04-09 16:49:25 +0000614 }
615 return false;
616}
617
Colin Rileyef20b082015-04-14 07:39:24 +0000618void
619RenderScriptRuntime::Update()
620{
621 if (m_rsmodules.size() > 0)
622 {
623 if (!m_initiated)
624 {
625 Initiate();
626 }
627 }
628}
629
630
Colin Riley5ec532a2015-04-09 16:49:25 +0000631// The maximum line length of an .rs.info packet
632#define MAXLINE 500
633
634// The .rs.info symbol in renderscript modules contains a string which needs to be parsed.
635// The string is basic and is parsed on a line by line basis.
636bool
637RSModuleDescriptor::ParseRSInfo()
638{
639 const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
640 if (info_sym)
641 {
Greg Clayton358cf1e2015-06-25 21:46:34 +0000642 const addr_t addr = info_sym->GetAddressRef().GetFileAddress();
Colin Riley5ec532a2015-04-09 16:49:25 +0000643 const addr_t size = info_sym->GetByteSize();
644 const FileSpec fs = m_module->GetFileSpec();
645
646 DataBufferSP buffer = fs.ReadFileContents(addr, size);
647
648 if (!buffer)
649 return false;
650
651 std::string info((const char *)buffer->GetBytes());
652
653 std::vector<std::string> info_lines;
Bruce Mitchenere8433cc2015-09-01 23:57:17 +0000654 size_t lpos = info.find('\n');
Colin Riley5ec532a2015-04-09 16:49:25 +0000655 while (lpos != std::string::npos)
656 {
657 info_lines.push_back(info.substr(0, lpos));
658 info = info.substr(lpos + 1);
Bruce Mitchenere8433cc2015-09-01 23:57:17 +0000659 lpos = info.find('\n');
Colin Riley5ec532a2015-04-09 16:49:25 +0000660 }
661 size_t offset = 0;
662 while (offset < info_lines.size())
663 {
664 std::string line = info_lines[offset];
665 // Parse directives
666 uint32_t numDefns = 0;
667 if (sscanf(line.c_str(), "exportVarCount: %u", &numDefns) == 1)
668 {
669 while (numDefns--)
Colin Riley4640cde2015-06-01 18:23:41 +0000670 m_globals.push_back(RSGlobalDescriptor(this, info_lines[++offset].c_str()));
Colin Riley5ec532a2015-04-09 16:49:25 +0000671 }
672 else if (sscanf(line.c_str(), "exportFuncCount: %u", &numDefns) == 1)
673 {
674 }
675 else if (sscanf(line.c_str(), "exportForEachCount: %u", &numDefns) == 1)
676 {
677 char name[MAXLINE];
678 while (numDefns--)
679 {
680 uint32_t slot = 0;
681 name[0] = '\0';
682 if (sscanf(info_lines[++offset].c_str(), "%u - %s", &slot, &name[0]) == 2)
683 {
Colin Riley4640cde2015-06-01 18:23:41 +0000684 m_kernels.push_back(RSKernelDescriptor(this, name, slot));
685 }
686 }
687 }
688 else if (sscanf(line.c_str(), "pragmaCount: %u", &numDefns) == 1)
689 {
690 char name[MAXLINE];
691 char value[MAXLINE];
692 while (numDefns--)
693 {
694 name[0] = '\0';
695 value[0] = '\0';
696 if (sscanf(info_lines[++offset].c_str(), "%s - %s", &name[0], &value[0]) != 0
697 && (name[0] != '\0'))
698 {
699 m_pragmas[std::string(name)] = value;
Colin Riley5ec532a2015-04-09 16:49:25 +0000700 }
701 }
702 }
703 else if (sscanf(line.c_str(), "objectSlotCount: %u", &numDefns) == 1)
704 {
705 }
706
707 offset++;
708 }
709 return m_kernels.size() > 0;
710 }
711 return false;
712}
713
714bool
715RenderScriptRuntime::ProbeModules(const ModuleList module_list)
716{
717 bool rs_found = false;
718 size_t num_modules = module_list.GetSize();
719 for (size_t i = 0; i < num_modules; i++)
720 {
721 auto module = module_list.GetModuleAtIndex(i);
722 rs_found |= LoadModule(module);
723 }
724 return rs_found;
725}
726
727void
Colin Riley4640cde2015-06-01 18:23:41 +0000728RenderScriptRuntime::Status(Stream &strm) const
729{
730 if (m_libRS)
731 {
732 strm.Printf("Runtime Library discovered.");
733 strm.EOL();
734 }
735 if (m_libRSDriver)
736 {
737 strm.Printf("Runtime Driver discovered.");
738 strm.EOL();
739 }
740 if (m_libRSCpuRef)
741 {
742 strm.Printf("CPU Reference Implementation discovered.");
743 strm.EOL();
744 }
745
746 if (m_runtimeHooks.size())
747 {
748 strm.Printf("Runtime functions hooked:");
749 strm.EOL();
750 for (auto b : m_runtimeHooks)
751 {
752 strm.Indent(b.second->defn->name);
753 strm.EOL();
754 }
755 strm.EOL();
756 }
757 else
758 {
759 strm.Printf("Runtime is not hooked.");
760 strm.EOL();
761 }
762}
763
764void
765RenderScriptRuntime::DumpContexts(Stream &strm) const
766{
767 strm.Printf("Inferred RenderScript Contexts:");
768 strm.EOL();
769 strm.IndentMore();
770
771 std::map<addr_t, uint64_t> contextReferences;
772
773 for (const auto &script : m_scripts)
774 {
775 if (contextReferences.find(script.context) != contextReferences.end())
776 {
777 contextReferences[script.context]++;
778 }
779 else
780 {
781 contextReferences[script.context] = 1;
782 }
783 }
784
785 for (const auto& cRef : contextReferences)
786 {
787 strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances", cRef.first, cRef.second);
788 strm.EOL();
789 }
790 strm.IndentLess();
791}
792
793void
794RenderScriptRuntime::DumpKernels(Stream &strm) const
795{
796 strm.Printf("RenderScript Kernels:");
797 strm.EOL();
798 strm.IndentMore();
799 for (const auto &module : m_rsmodules)
800 {
801 strm.Printf("Resource '%s':",module->m_resname.c_str());
802 strm.EOL();
803 for (const auto &kernel : module->m_kernels)
804 {
805 strm.Indent(kernel.m_name.AsCString());
806 strm.EOL();
807 }
808 }
809 strm.IndentLess();
810}
811
Ewan Crawford98156582015-09-04 08:56:52 +0000812void
813RenderScriptRuntime::AttemptBreakpointAtKernelName(Stream &strm, const char* name, Error& error, TargetSP target)
Colin Riley4640cde2015-06-01 18:23:41 +0000814{
Ewan Crawford98156582015-09-04 08:56:52 +0000815 if (!name)
Colin Riley4640cde2015-06-01 18:23:41 +0000816 {
817 error.SetErrorString("invalid kernel name");
818 return;
819 }
820
Ewan Crawford98156582015-09-04 08:56:52 +0000821 SearchFilterSP filter_sp(new SearchFilterForUnconstrainedSearches(target));
822
Colin Riley4640cde2015-06-01 18:23:41 +0000823 ConstString kernel_name(name);
Ewan Crawford98156582015-09-04 08:56:52 +0000824 BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, kernel_name));
Colin Riley4640cde2015-06-01 18:23:41 +0000825
Ewan Crawford98156582015-09-04 08:56:52 +0000826 BreakpointSP bp = target->CreateBreakpoint(filter_sp, resolver_sp, false, false, false);
827 if (bp)
828 bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false);
Colin Riley4640cde2015-06-01 18:23:41 +0000829
Colin Riley4640cde2015-06-01 18:23:41 +0000830 return;
831}
832
833void
Colin Riley5ec532a2015-04-09 16:49:25 +0000834RenderScriptRuntime::DumpModules(Stream &strm) const
835{
836 strm.Printf("RenderScript Modules:");
837 strm.EOL();
838 strm.IndentMore();
839 for (const auto &module : m_rsmodules)
840 {
Colin Riley4640cde2015-06-01 18:23:41 +0000841 module->Dump(strm);
Colin Riley5ec532a2015-04-09 16:49:25 +0000842 }
843 strm.IndentLess();
844}
845
846void
847RSModuleDescriptor::Dump(Stream &strm) const
848{
849 strm.Indent();
850 m_module->GetFileSpec().Dump(&strm);
Colin Riley4640cde2015-06-01 18:23:41 +0000851 m_module->ParseAllDebugSymbols();
852 if(m_module->GetNumCompileUnits())
853 {
854 strm.Indent("Debug info loaded.");
855 }
856 else
857 {
858 strm.Indent("Debug info does not exist.");
859 }
Colin Riley5ec532a2015-04-09 16:49:25 +0000860 strm.EOL();
861 strm.IndentMore();
862 strm.Indent();
Colin Riley189598e2015-04-12 22:05:58 +0000863 strm.Printf("Globals: %" PRIu64, static_cast<uint64_t>(m_globals.size()));
Colin Riley5ec532a2015-04-09 16:49:25 +0000864 strm.EOL();
865 strm.IndentMore();
866 for (const auto &global : m_globals)
867 {
868 global.Dump(strm);
869 }
870 strm.IndentLess();
871 strm.Indent();
Colin Riley189598e2015-04-12 22:05:58 +0000872 strm.Printf("Kernels: %" PRIu64, static_cast<uint64_t>(m_kernels.size()));
Colin Riley5ec532a2015-04-09 16:49:25 +0000873 strm.EOL();
874 strm.IndentMore();
875 for (const auto &kernel : m_kernels)
876 {
877 kernel.Dump(strm);
878 }
Colin Riley4640cde2015-06-01 18:23:41 +0000879 strm.Printf("Pragmas: %" PRIu64 , static_cast<uint64_t>(m_pragmas.size()));
880 strm.EOL();
881 strm.IndentMore();
882 for (const auto &key_val : m_pragmas)
883 {
884 strm.Printf("%s: %s", key_val.first.c_str(), key_val.second.c_str());
885 strm.EOL();
886 }
Colin Riley5ec532a2015-04-09 16:49:25 +0000887 strm.IndentLess(4);
888}
889
890void
891RSGlobalDescriptor::Dump(Stream &strm) const
892{
893 strm.Indent(m_name.AsCString());
Colin Riley4640cde2015-06-01 18:23:41 +0000894 VariableList var_list;
895 m_module->m_module->FindGlobalVariables(m_name, nullptr, true, 1U, var_list);
896 if (var_list.GetSize() == 1)
897 {
898 auto var = var_list.GetVariableAtIndex(0);
899 auto type = var->GetType();
900 if(type)
901 {
902 strm.Printf(" - ");
903 type->DumpTypeName(&strm);
904 }
905 else
906 {
907 strm.Printf(" - Unknown Type");
908 }
909 }
910 else
911 {
912 strm.Printf(" - variable identified, but not found in binary");
913 const Symbol* s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData);
914 if (s)
915 {
916 strm.Printf(" (symbol exists) ");
917 }
918 }
919
Colin Riley5ec532a2015-04-09 16:49:25 +0000920 strm.EOL();
921}
922
923void
924RSKernelDescriptor::Dump(Stream &strm) const
925{
926 strm.Indent(m_name.AsCString());
927 strm.EOL();
928}
929
930class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed
931{
932 private:
933 public:
934 CommandObjectRenderScriptRuntimeModuleProbe(CommandInterpreter &interpreter)
935 : CommandObjectParsed(interpreter, "renderscript module probe",
936 "Initiates a Probe of all loaded modules for kernels and other renderscript objects.",
937 "renderscript module probe",
Enrico Granatae87764f2015-05-27 05:04:35 +0000938 eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBeLaunched)
Colin Riley5ec532a2015-04-09 16:49:25 +0000939 {
940 }
941
942 ~CommandObjectRenderScriptRuntimeModuleProbe() {}
943
944 bool
945 DoExecute(Args &command, CommandReturnObject &result)
946 {
947 const size_t argc = command.GetArgumentCount();
948 if (argc == 0)
949 {
950 Target *target = m_exe_ctx.GetTargetPtr();
951 RenderScriptRuntime *runtime =
952 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
953 auto module_list = target->GetImages();
954 bool new_rs_details = runtime->ProbeModules(module_list);
955 if (new_rs_details)
956 {
957 result.AppendMessage("New renderscript modules added to runtime model.");
958 }
959 result.SetStatus(eReturnStatusSuccessFinishResult);
960 return true;
961 }
962
963 result.AppendErrorWithFormat("'%s' takes no arguments", m_cmd_name.c_str());
964 result.SetStatus(eReturnStatusFailed);
965 return false;
966 }
967};
968
969class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed
970{
971 private:
972 public:
973 CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter)
974 : CommandObjectParsed(interpreter, "renderscript module dump",
975 "Dumps renderscript specific information for all modules.", "renderscript module dump",
Enrico Granatae87764f2015-05-27 05:04:35 +0000976 eCommandRequiresProcess | eCommandProcessMustBeLaunched)
Colin Riley5ec532a2015-04-09 16:49:25 +0000977 {
978 }
979
980 ~CommandObjectRenderScriptRuntimeModuleDump() {}
981
982 bool
983 DoExecute(Args &command, CommandReturnObject &result)
984 {
985 RenderScriptRuntime *runtime =
986 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
987 runtime->DumpModules(result.GetOutputStream());
988 result.SetStatus(eReturnStatusSuccessFinishResult);
989 return true;
990 }
991};
992
993class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword
994{
995 private:
996 public:
997 CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter)
998 : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with renderscript modules.",
999 NULL)
1000 {
1001 LoadSubCommand("probe", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleProbe(interpreter)));
1002 LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter)));
1003 }
1004
1005 ~CommandObjectRenderScriptRuntimeModule() {}
1006};
1007
Colin Riley4640cde2015-06-01 18:23:41 +00001008class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed
1009{
1010 private:
1011 public:
1012 CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter)
1013 : CommandObjectParsed(interpreter, "renderscript kernel list",
1014 "Lists renderscript kernel names and associated script resources.", "renderscript kernel list",
1015 eCommandRequiresProcess | eCommandProcessMustBeLaunched)
1016 {
1017 }
1018
1019 ~CommandObjectRenderScriptRuntimeKernelList() {}
1020
1021 bool
1022 DoExecute(Args &command, CommandReturnObject &result)
1023 {
1024 RenderScriptRuntime *runtime =
1025 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
1026 runtime->DumpKernels(result.GetOutputStream());
1027 result.SetStatus(eReturnStatusSuccessFinishResult);
1028 return true;
1029 }
1030};
1031
1032class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectParsed
1033{
1034 private:
1035 public:
1036 CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter)
1037 : CommandObjectParsed(interpreter, "renderscript kernel breakpoint",
Ewan Crawford98156582015-09-04 08:56:52 +00001038 "Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint <kernel_name>",
Colin Riley4640cde2015-06-01 18:23:41 +00001039 eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
1040 {
1041 }
1042
1043 ~CommandObjectRenderScriptRuntimeKernelBreakpoint() {}
1044
1045 bool
1046 DoExecute(Args &command, CommandReturnObject &result)
1047 {
1048 const size_t argc = command.GetArgumentCount();
1049 if (argc == 1)
1050 {
1051 RenderScriptRuntime *runtime =
1052 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
1053
1054 Error error;
Ewan Crawford98156582015-09-04 08:56:52 +00001055 runtime->AttemptBreakpointAtKernelName(result.GetOutputStream(), command.GetArgumentAtIndex(0),
1056 error, m_exe_ctx.GetTargetSP());
Colin Riley4640cde2015-06-01 18:23:41 +00001057
1058 if (error.Success())
1059 {
1060 result.AppendMessage("Breakpoint(s) created");
1061 result.SetStatus(eReturnStatusSuccessFinishResult);
1062 return true;
1063 }
1064 result.SetStatus(eReturnStatusFailed);
1065 result.AppendErrorWithFormat("Error: %s", error.AsCString());
1066 return false;
1067 }
1068
1069 result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name", m_cmd_name.c_str());
1070 result.SetStatus(eReturnStatusFailed);
1071 return false;
1072 }
1073};
1074
1075class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword
1076{
1077 private:
1078 public:
1079 CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter)
1080 : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with renderscript kernels.",
1081 NULL)
1082 {
1083 LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(interpreter)));
1084 LoadSubCommand("breakpoint", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter)));
1085 }
1086
1087 ~CommandObjectRenderScriptRuntimeKernel() {}
1088};
1089
1090class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed
1091{
1092 private:
1093 public:
1094 CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter)
1095 : CommandObjectParsed(interpreter, "renderscript context dump",
1096 "Dumps renderscript context information.", "renderscript context dump",
1097 eCommandRequiresProcess | eCommandProcessMustBeLaunched)
1098 {
1099 }
1100
1101 ~CommandObjectRenderScriptRuntimeContextDump() {}
1102
1103 bool
1104 DoExecute(Args &command, CommandReturnObject &result)
1105 {
1106 RenderScriptRuntime *runtime =
1107 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
1108 runtime->DumpContexts(result.GetOutputStream());
1109 result.SetStatus(eReturnStatusSuccessFinishResult);
1110 return true;
1111 }
1112};
1113
1114class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword
1115{
1116 private:
1117 public:
1118 CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter)
1119 : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with renderscript contexts.",
1120 NULL)
1121 {
1122 LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(interpreter)));
1123 }
1124
1125 ~CommandObjectRenderScriptRuntimeContext() {}
1126};
1127
1128class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed
1129{
1130 private:
1131 public:
1132 CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter)
1133 : CommandObjectParsed(interpreter, "renderscript status",
1134 "Displays current renderscript runtime status.", "renderscript status",
1135 eCommandRequiresProcess | eCommandProcessMustBeLaunched)
1136 {
1137 }
1138
1139 ~CommandObjectRenderScriptRuntimeStatus() {}
1140
1141 bool
1142 DoExecute(Args &command, CommandReturnObject &result)
1143 {
1144 RenderScriptRuntime *runtime =
1145 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
1146 runtime->Status(result.GetOutputStream());
1147 result.SetStatus(eReturnStatusSuccessFinishResult);
1148 return true;
1149 }
1150};
1151
Colin Riley5ec532a2015-04-09 16:49:25 +00001152class CommandObjectRenderScriptRuntime : public CommandObjectMultiword
1153{
1154 public:
1155 CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter)
1156 : CommandObjectMultiword(interpreter, "renderscript", "A set of commands for operating on renderscript.",
1157 "renderscript <subcommand> [<subcommand-options>]")
1158 {
1159 LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter)));
Colin Riley4640cde2015-06-01 18:23:41 +00001160 LoadSubCommand("status", CommandObjectSP(new CommandObjectRenderScriptRuntimeStatus(interpreter)));
1161 LoadSubCommand("kernel", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernel(interpreter)));
1162 LoadSubCommand("context", CommandObjectSP(new CommandObjectRenderScriptRuntimeContext(interpreter)));
Colin Riley5ec532a2015-04-09 16:49:25 +00001163 }
1164
1165 ~CommandObjectRenderScriptRuntime() {}
1166};
Colin Rileyef20b082015-04-14 07:39:24 +00001167
1168void
1169RenderScriptRuntime::Initiate()
Colin Riley5ec532a2015-04-09 16:49:25 +00001170{
Colin Rileyef20b082015-04-14 07:39:24 +00001171 assert(!m_initiated);
Colin Riley5ec532a2015-04-09 16:49:25 +00001172}
Colin Rileyef20b082015-04-14 07:39:24 +00001173
1174RenderScriptRuntime::RenderScriptRuntime(Process *process)
Colin Riley4640cde2015-06-01 18:23:41 +00001175 : lldb_private::CPPLanguageRuntime(process), m_initiated(false), m_debuggerPresentFlagged(false)
Colin Rileyef20b082015-04-14 07:39:24 +00001176{
Colin Riley4640cde2015-06-01 18:23:41 +00001177 ModulesDidLoad(process->GetTarget().GetImages());
Colin Rileyef20b082015-04-14 07:39:24 +00001178}
Colin Riley4640cde2015-06-01 18:23:41 +00001179
1180lldb::CommandObjectSP
1181RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter& interpreter)
1182{
1183 static CommandObjectSP command_object;
1184 if(!command_object)
1185 {
1186 command_object.reset(new CommandObjectRenderScriptRuntime(interpreter));
1187 }
1188 return command_object;
1189}
1190