1 //===-- 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"
18 #include "lldb/Symbol/Type.h"
19 #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"
26 #include "lldb/Breakpoint/StoppointCallbackContext.h"
27 #include "lldb/Target/RegisterContext.h"
28 
29 #include "lldb/Symbol/VariableList.h"
30 
31 using namespace lldb;
32 using namespace lldb_private;
33 using namespace lldb_renderscript;
34 
35 //------------------------------------------------------------------
36 // Static Functions
37 //------------------------------------------------------------------
38 LanguageRuntime *
39 RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType language)
40 {
41 
42     if (language == eLanguageTypeExtRenderScript)
43         return new RenderScriptRuntime(process);
44     else
45         return NULL;
46 }
47 
48 // 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.
52 Searcher::CallbackReturn
53 RSBreakpointResolver::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 
89 void
90 RenderScriptRuntime::Initialize()
91 {
92     PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance, GetCommandObject);
93 }
94 
95 void
96 RenderScriptRuntime::Terminate()
97 {
98     PluginManager::UnregisterPlugin(CreateInstance);
99 }
100 
101 lldb_private::ConstString
102 RenderScriptRuntime::GetPluginNameStatic()
103 {
104     static ConstString g_name("renderscript");
105     return g_name;
106 }
107 
108 RenderScriptRuntime::ModuleKind
109 RenderScriptRuntime::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         }
119 
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 
139     }
140     return eModuleKindIgnored;
141 }
142 
143 bool
144 RenderScriptRuntime::IsRenderScriptModule(const lldb::ModuleSP &module_sp)
145 {
146     return GetModuleKind(module_sp) != eModuleKindIgnored;
147 }
148 
149 
150 void
151 RenderScriptRuntime::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 
167 //------------------------------------------------------------------
168 // PluginInterface protocol
169 //------------------------------------------------------------------
170 lldb_private::ConstString
171 RenderScriptRuntime::GetPluginName()
172 {
173     return GetPluginNameStatic();
174 }
175 
176 uint32_t
177 RenderScriptRuntime::GetPluginVersion()
178 {
179     return 1;
180 }
181 
182 bool
183 RenderScriptRuntime::IsVTableName(const char *name)
184 {
185     return false;
186 }
187 
188 bool
189 RenderScriptRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
190                                               TypeAndOrName &class_type_or_name, Address &address)
191 {
192     return false;
193 }
194 
195 bool
196 RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value)
197 {
198     return false;
199 }
200 
201 lldb::BreakpointResolverSP
202 RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp)
203 {
204     BreakpointResolverSP resolver_sp;
205     return resolver_sp;
206 }
207 
208 
209 const 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 };
222 const size_t RenderScriptRuntime::s_runtimeHookCount = sizeof(s_runtimeHookDefns)/sizeof(s_runtimeHookDefns[0]);
223 
224 
225 bool
226 RenderScriptRuntime::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 
239 void
240 RenderScriptRuntime::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 
254 bool
255 RenderScriptRuntime::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 
305 void
306 RenderScriptRuntime::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 
348 void
349 RenderScriptRuntime::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 
370 void
371 RenderScriptRuntime::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 
437 void
438 RenderScriptRuntime::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 
467         addr_t addr = sym->GetLoadAddress(&target);
468         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 
490 void
491 RenderScriptRuntime::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 
531 bool
532 RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
533 {
534     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
535 
536     if (module_sp)
537     {
538         for (const auto &rs_module : m_rsmodules)
539         {
540             if (rs_module->m_module == module_sp)
541             {
542                 // Check if the user has enabled automatically breaking on
543                 // all RS kernels.
544                 if (m_breakAllKernels)
545                     BreakOnModuleKernels(rs_module);
546 
547                 return false;
548             }
549         }
550         bool module_loaded = false;
551         switch (GetModuleKind(module_sp))
552         {
553             case eModuleKindKernelObj:
554             {
555                 RSModuleDescriptorSP module_desc;
556                 module_desc.reset(new RSModuleDescriptor(module_sp));
557                 if (module_desc->ParseRSInfo())
558                 {
559                     m_rsmodules.push_back(module_desc);
560                     module_loaded = true;
561                 }
562                 if (module_loaded)
563                 {
564                     FixupScriptDetails(module_desc);
565                 }
566                 break;
567             }
568             case eModuleKindDriver:
569             {
570                 if (!m_libRSDriver)
571                 {
572                     m_libRSDriver = module_sp;
573                     LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver);
574                 }
575                 break;
576             }
577             case eModuleKindImpl:
578             {
579                 m_libRSCpuRef = module_sp;
580                 break;
581             }
582             case eModuleKindLibRS:
583             {
584                 if (!m_libRS)
585                 {
586                     m_libRS = module_sp;
587                     static ConstString gDbgPresentStr("gDebuggerPresent");
588                     const Symbol* debug_present = m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData);
589                     if (debug_present)
590                     {
591                         Error error;
592                         uint32_t flag = 0x00000001U;
593                         Target &target = GetProcess()->GetTarget();
594                         addr_t addr = debug_present->GetLoadAddress(&target);
595                         GetProcess()->WriteMemory(addr, &flag, sizeof(flag), error);
596                         if(error.Success())
597                         {
598                             if (log)
599                                 log->Printf ("RenderScriptRuntime::LoadModule - Debugger present flag set on debugee");
600 
601                             m_debuggerPresentFlagged = true;
602                         }
603                         else if (log)
604                         {
605                             log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags '%s' ", error.AsCString());
606                         }
607                     }
608                     else if (log)
609                     {
610                         log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags - symbol not found");
611                     }
612                 }
613                 break;
614             }
615             default:
616                 break;
617         }
618         if (module_loaded)
619             Update();
620         return module_loaded;
621     }
622     return false;
623 }
624 
625 void
626 RenderScriptRuntime::Update()
627 {
628     if (m_rsmodules.size() > 0)
629     {
630         if (!m_initiated)
631         {
632             Initiate();
633         }
634     }
635 }
636 
637 
638 // The maximum line length of an .rs.info packet
639 #define MAXLINE 500
640 
641 // The .rs.info symbol in renderscript modules contains a string which needs to be parsed.
642 // The string is basic and is parsed on a line by line basis.
643 bool
644 RSModuleDescriptor::ParseRSInfo()
645 {
646     const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
647     if (info_sym)
648     {
649         const addr_t addr = info_sym->GetAddressRef().GetFileAddress();
650         const addr_t size = info_sym->GetByteSize();
651         const FileSpec fs = m_module->GetFileSpec();
652 
653         DataBufferSP buffer = fs.ReadFileContents(addr, size);
654 
655         if (!buffer)
656             return false;
657 
658         std::string info((const char *)buffer->GetBytes());
659 
660         std::vector<std::string> info_lines;
661         size_t lpos = info.find('\n');
662         while (lpos != std::string::npos)
663         {
664             info_lines.push_back(info.substr(0, lpos));
665             info = info.substr(lpos + 1);
666             lpos = info.find('\n');
667         }
668         size_t offset = 0;
669         while (offset < info_lines.size())
670         {
671             std::string line = info_lines[offset];
672             // Parse directives
673             uint32_t numDefns = 0;
674             if (sscanf(line.c_str(), "exportVarCount: %u", &numDefns) == 1)
675             {
676                 while (numDefns--)
677                     m_globals.push_back(RSGlobalDescriptor(this, info_lines[++offset].c_str()));
678             }
679             else if (sscanf(line.c_str(), "exportFuncCount: %u", &numDefns) == 1)
680             {
681             }
682             else if (sscanf(line.c_str(), "exportForEachCount: %u", &numDefns) == 1)
683             {
684                 char name[MAXLINE];
685                 while (numDefns--)
686                 {
687                     uint32_t slot = 0;
688                     name[0] = '\0';
689                     if (sscanf(info_lines[++offset].c_str(), "%u - %s", &slot, &name[0]) == 2)
690                     {
691                         m_kernels.push_back(RSKernelDescriptor(this, name, slot));
692                     }
693                 }
694             }
695             else if (sscanf(line.c_str(), "pragmaCount: %u", &numDefns) == 1)
696             {
697                 char name[MAXLINE];
698                 char value[MAXLINE];
699                 while (numDefns--)
700                 {
701                     name[0] = '\0';
702                     value[0] = '\0';
703                     if (sscanf(info_lines[++offset].c_str(), "%s - %s", &name[0], &value[0]) != 0
704                         && (name[0] != '\0'))
705                     {
706                         m_pragmas[std::string(name)] = value;
707                     }
708                 }
709             }
710             else if (sscanf(line.c_str(), "objectSlotCount: %u", &numDefns) == 1)
711             {
712             }
713 
714             offset++;
715         }
716         return m_kernels.size() > 0;
717     }
718     return false;
719 }
720 
721 bool
722 RenderScriptRuntime::ProbeModules(const ModuleList module_list)
723 {
724     bool rs_found = false;
725     size_t num_modules = module_list.GetSize();
726     for (size_t i = 0; i < num_modules; i++)
727     {
728         auto module = module_list.GetModuleAtIndex(i);
729         rs_found |= LoadModule(module);
730     }
731     return rs_found;
732 }
733 
734 void
735 RenderScriptRuntime::Status(Stream &strm) const
736 {
737     if (m_libRS)
738     {
739         strm.Printf("Runtime Library discovered.");
740         strm.EOL();
741     }
742     if (m_libRSDriver)
743     {
744         strm.Printf("Runtime Driver discovered.");
745         strm.EOL();
746     }
747     if (m_libRSCpuRef)
748     {
749         strm.Printf("CPU Reference Implementation discovered.");
750         strm.EOL();
751     }
752 
753     if (m_runtimeHooks.size())
754     {
755         strm.Printf("Runtime functions hooked:");
756         strm.EOL();
757         for (auto b : m_runtimeHooks)
758         {
759             strm.Indent(b.second->defn->name);
760             strm.EOL();
761         }
762         strm.EOL();
763     }
764     else
765     {
766         strm.Printf("Runtime is not hooked.");
767         strm.EOL();
768     }
769 }
770 
771 void
772 RenderScriptRuntime::DumpContexts(Stream &strm) const
773 {
774     strm.Printf("Inferred RenderScript Contexts:");
775     strm.EOL();
776     strm.IndentMore();
777 
778     std::map<addr_t, uint64_t> contextReferences;
779 
780     for (const auto &script : m_scripts)
781     {
782         if (contextReferences.find(script.context) != contextReferences.end())
783         {
784             contextReferences[script.context]++;
785         }
786         else
787         {
788             contextReferences[script.context] = 1;
789         }
790     }
791 
792     for (const auto& cRef : contextReferences)
793     {
794         strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances", cRef.first, cRef.second);
795         strm.EOL();
796     }
797     strm.IndentLess();
798 }
799 
800 void
801 RenderScriptRuntime::DumpKernels(Stream &strm) const
802 {
803     strm.Printf("RenderScript Kernels:");
804     strm.EOL();
805     strm.IndentMore();
806     for (const auto &module : m_rsmodules)
807     {
808         strm.Printf("Resource '%s':",module->m_resname.c_str());
809         strm.EOL();
810         for (const auto &kernel : module->m_kernels)
811         {
812             strm.Indent(kernel.m_name.AsCString());
813             strm.EOL();
814         }
815     }
816     strm.IndentLess();
817 }
818 
819 // Set breakpoints on every kernel found in RS module
820 void
821 RenderScriptRuntime::BreakOnModuleKernels(const RSModuleDescriptorSP rsmodule_sp)
822 {
823     for (const auto &kernel : rsmodule_sp->m_kernels)
824     {
825         // Don't set breakpoint on 'root' kernel
826         if (strcmp(kernel.m_name.AsCString(), "root") == 0)
827             continue;
828 
829         CreateKernelBreakpoint(kernel.m_name);
830     }
831 }
832 
833 // Method is internally called by the 'kernel breakpoint all' command to
834 // enable or disable breaking on all kernels.
835 //
836 // When do_break is true we want to enable this functionality.
837 // When do_break is false we want to disable it.
838 void
839 RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target)
840 {
841     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
842 
843     InitSearchFilter(target);
844 
845     // Set breakpoints on all the kernels
846     if (do_break && !m_breakAllKernels)
847     {
848         m_breakAllKernels = true;
849 
850         for (const auto &module : m_rsmodules)
851             BreakOnModuleKernels(module);
852 
853         if (log)
854             log->Printf("RenderScriptRuntime::SetBreakAllKernels(True)"
855                         "- breakpoints set on all currently loaded kernels");
856     }
857     else if (!do_break && m_breakAllKernels) // Breakpoints won't be set on any new kernels.
858     {
859         m_breakAllKernels = false;
860 
861         if (log)
862             log->Printf("RenderScriptRuntime::SetBreakAllKernels(False) - breakpoints no longer automatically set");
863     }
864 }
865 
866 // Given the name of a kernel this function creates a breakpoint using our
867 // own breakpoint resolver, and returns the Breakpoint shared pointer.
868 BreakpointSP
869 RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name)
870 {
871     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
872 
873     if (!m_filtersp)
874     {
875         if (log)
876             log->Printf("RenderScriptRuntime::CreateKernelBreakpoint - Error: No breakpoint search filter set");
877         return nullptr;
878     }
879 
880     BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name));
881     BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(m_filtersp, resolver_sp, false, false, false);
882 
883     return bp;
884 }
885 
886 void
887 RenderScriptRuntime::AttemptBreakpointAtKernelName(Stream &strm, const char* name, Error& error, TargetSP target)
888 {
889     if (!name)
890     {
891         error.SetErrorString("invalid kernel name");
892         return;
893     }
894 
895     InitSearchFilter(target);
896 
897     ConstString kernel_name(name);
898     BreakpointSP bp = CreateKernelBreakpoint(kernel_name);
899     if (bp)
900         bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false);
901 
902     return;
903 }
904 
905 void
906 RenderScriptRuntime::DumpModules(Stream &strm) const
907 {
908     strm.Printf("RenderScript Modules:");
909     strm.EOL();
910     strm.IndentMore();
911     for (const auto &module : m_rsmodules)
912     {
913         module->Dump(strm);
914     }
915     strm.IndentLess();
916 }
917 
918 void
919 RSModuleDescriptor::Dump(Stream &strm) const
920 {
921     strm.Indent();
922     m_module->GetFileSpec().Dump(&strm);
923     m_module->ParseAllDebugSymbols();
924     if(m_module->GetNumCompileUnits())
925     {
926         strm.Indent("Debug info loaded.");
927     }
928     else
929     {
930         strm.Indent("Debug info does not exist.");
931     }
932     strm.EOL();
933     strm.IndentMore();
934     strm.Indent();
935     strm.Printf("Globals: %" PRIu64, static_cast<uint64_t>(m_globals.size()));
936     strm.EOL();
937     strm.IndentMore();
938     for (const auto &global : m_globals)
939     {
940         global.Dump(strm);
941     }
942     strm.IndentLess();
943     strm.Indent();
944     strm.Printf("Kernels: %" PRIu64, static_cast<uint64_t>(m_kernels.size()));
945     strm.EOL();
946     strm.IndentMore();
947     for (const auto &kernel : m_kernels)
948     {
949         kernel.Dump(strm);
950     }
951     strm.Printf("Pragmas: %"  PRIu64 , static_cast<uint64_t>(m_pragmas.size()));
952     strm.EOL();
953     strm.IndentMore();
954     for (const auto &key_val : m_pragmas)
955     {
956         strm.Printf("%s: %s", key_val.first.c_str(), key_val.second.c_str());
957         strm.EOL();
958     }
959     strm.IndentLess(4);
960 }
961 
962 void
963 RSGlobalDescriptor::Dump(Stream &strm) const
964 {
965     strm.Indent(m_name.AsCString());
966     VariableList var_list;
967     m_module->m_module->FindGlobalVariables(m_name, nullptr, true, 1U, var_list);
968     if (var_list.GetSize() == 1)
969     {
970         auto var = var_list.GetVariableAtIndex(0);
971         auto type = var->GetType();
972         if(type)
973         {
974             strm.Printf(" - ");
975             type->DumpTypeName(&strm);
976         }
977         else
978         {
979             strm.Printf(" - Unknown Type");
980         }
981     }
982     else
983     {
984         strm.Printf(" - variable identified, but not found in binary");
985         const Symbol* s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData);
986         if (s)
987         {
988             strm.Printf(" (symbol exists) ");
989         }
990     }
991 
992     strm.EOL();
993 }
994 
995 void
996 RSKernelDescriptor::Dump(Stream &strm) const
997 {
998     strm.Indent(m_name.AsCString());
999     strm.EOL();
1000 }
1001 
1002 class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed
1003 {
1004   private:
1005   public:
1006     CommandObjectRenderScriptRuntimeModuleProbe(CommandInterpreter &interpreter)
1007         : CommandObjectParsed(interpreter, "renderscript module probe",
1008                               "Initiates a Probe of all loaded modules for kernels and other renderscript objects.",
1009                               "renderscript module probe",
1010                               eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBeLaunched)
1011     {
1012     }
1013 
1014     ~CommandObjectRenderScriptRuntimeModuleProbe() {}
1015 
1016     bool
1017     DoExecute(Args &command, CommandReturnObject &result)
1018     {
1019         const size_t argc = command.GetArgumentCount();
1020         if (argc == 0)
1021         {
1022             Target *target = m_exe_ctx.GetTargetPtr();
1023             RenderScriptRuntime *runtime =
1024                 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
1025             auto module_list = target->GetImages();
1026             bool new_rs_details = runtime->ProbeModules(module_list);
1027             if (new_rs_details)
1028             {
1029                 result.AppendMessage("New renderscript modules added to runtime model.");
1030             }
1031             result.SetStatus(eReturnStatusSuccessFinishResult);
1032             return true;
1033         }
1034 
1035         result.AppendErrorWithFormat("'%s' takes no arguments", m_cmd_name.c_str());
1036         result.SetStatus(eReturnStatusFailed);
1037         return false;
1038     }
1039 };
1040 
1041 class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed
1042 {
1043   private:
1044   public:
1045     CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter)
1046         : CommandObjectParsed(interpreter, "renderscript module dump",
1047                               "Dumps renderscript specific information for all modules.", "renderscript module dump",
1048                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
1049     {
1050     }
1051 
1052     ~CommandObjectRenderScriptRuntimeModuleDump() {}
1053 
1054     bool
1055     DoExecute(Args &command, CommandReturnObject &result)
1056     {
1057         RenderScriptRuntime *runtime =
1058             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
1059         runtime->DumpModules(result.GetOutputStream());
1060         result.SetStatus(eReturnStatusSuccessFinishResult);
1061         return true;
1062     }
1063 };
1064 
1065 class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword
1066 {
1067   private:
1068   public:
1069     CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter)
1070         : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with renderscript modules.",
1071                                  NULL)
1072     {
1073         LoadSubCommand("probe", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleProbe(interpreter)));
1074         LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter)));
1075     }
1076 
1077     ~CommandObjectRenderScriptRuntimeModule() {}
1078 };
1079 
1080 class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed
1081 {
1082   private:
1083   public:
1084     CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter)
1085         : CommandObjectParsed(interpreter, "renderscript kernel list",
1086                               "Lists renderscript kernel names and associated script resources.", "renderscript kernel list",
1087                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
1088     {
1089     }
1090 
1091     ~CommandObjectRenderScriptRuntimeKernelList() {}
1092 
1093     bool
1094     DoExecute(Args &command, CommandReturnObject &result)
1095     {
1096         RenderScriptRuntime *runtime =
1097             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
1098         runtime->DumpKernels(result.GetOutputStream());
1099         result.SetStatus(eReturnStatusSuccessFinishResult);
1100         return true;
1101     }
1102 };
1103 
1104 class CommandObjectRenderScriptRuntimeKernelBreakpointSet : public CommandObjectParsed
1105 {
1106   private:
1107   public:
1108     CommandObjectRenderScriptRuntimeKernelBreakpointSet(CommandInterpreter &interpreter)
1109         : CommandObjectParsed(interpreter, "renderscript kernel breakpoint set",
1110                               "Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint set <kernel_name>",
1111                               eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
1112     {
1113     }
1114 
1115     ~CommandObjectRenderScriptRuntimeKernelBreakpointSet() {}
1116 
1117     bool
1118     DoExecute(Args &command, CommandReturnObject &result)
1119     {
1120         const size_t argc = command.GetArgumentCount();
1121         if (argc == 1)
1122         {
1123             RenderScriptRuntime *runtime =
1124                 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
1125 
1126             Error error;
1127             runtime->AttemptBreakpointAtKernelName(result.GetOutputStream(), command.GetArgumentAtIndex(0),
1128                                                    error, m_exe_ctx.GetTargetSP());
1129 
1130             if (error.Success())
1131             {
1132                 result.AppendMessage("Breakpoint(s) created");
1133                 result.SetStatus(eReturnStatusSuccessFinishResult);
1134                 return true;
1135             }
1136             result.SetStatus(eReturnStatusFailed);
1137             result.AppendErrorWithFormat("Error: %s", error.AsCString());
1138             return false;
1139         }
1140 
1141         result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name", m_cmd_name.c_str());
1142         result.SetStatus(eReturnStatusFailed);
1143         return false;
1144     }
1145 };
1146 
1147 class CommandObjectRenderScriptRuntimeKernelBreakpointAll : public CommandObjectParsed
1148 {
1149   private:
1150   public:
1151     CommandObjectRenderScriptRuntimeKernelBreakpointAll(CommandInterpreter &interpreter)
1152         : CommandObjectParsed(interpreter, "renderscript kernel breakpoint all",
1153                               "Automatically sets a breakpoint on all renderscript kernels that are or will be loaded.\n"
1154                               "Disabling option means breakpoints will no longer be set on any kernels loaded in the future, "
1155                               "but does not remove currently set breakpoints.",
1156                               "renderscript kernel breakpoint all <enable/disable>",
1157                               eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
1158     {
1159     }
1160 
1161     ~CommandObjectRenderScriptRuntimeKernelBreakpointAll() {}
1162 
1163     bool
1164     DoExecute(Args &command, CommandReturnObject &result)
1165     {
1166         const size_t argc = command.GetArgumentCount();
1167         if (argc != 1)
1168         {
1169             result.AppendErrorWithFormat("'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str());
1170             result.SetStatus(eReturnStatusFailed);
1171             return false;
1172         }
1173 
1174         RenderScriptRuntime *runtime =
1175           static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
1176 
1177         bool do_break = false;
1178         const char* argument = command.GetArgumentAtIndex(0);
1179         if (strcmp(argument, "enable") == 0)
1180         {
1181             do_break = true;
1182             result.AppendMessage("Breakpoints will be set on all kernels.");
1183         }
1184         else if (strcmp(argument, "disable") == 0)
1185         {
1186             do_break = false;
1187             result.AppendMessage("Breakpoints will not be set on any new kernels.");
1188         }
1189         else
1190         {
1191             result.AppendErrorWithFormat("Argument must be either 'enable' or 'disable'");
1192             result.SetStatus(eReturnStatusFailed);
1193             return false;
1194         }
1195 
1196         runtime->SetBreakAllKernels(do_break, m_exe_ctx.GetTargetSP());
1197 
1198         result.SetStatus(eReturnStatusSuccessFinishResult);
1199         return true;
1200     }
1201 };
1202 
1203 class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectMultiword
1204 {
1205   private:
1206   public:
1207     CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter)
1208         : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that generate breakpoints on renderscript kernels.",
1209                                  nullptr)
1210     {
1211         LoadSubCommand("set", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointSet(interpreter)));
1212         LoadSubCommand("all", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointAll(interpreter)));
1213     }
1214 
1215     ~CommandObjectRenderScriptRuntimeKernelBreakpoint() {}
1216 };
1217 
1218 class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword
1219 {
1220   private:
1221   public:
1222     CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter)
1223         : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with renderscript kernels.",
1224                                  NULL)
1225     {
1226         LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(interpreter)));
1227         LoadSubCommand("breakpoint", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter)));
1228     }
1229 
1230     ~CommandObjectRenderScriptRuntimeKernel() {}
1231 };
1232 
1233 class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed
1234 {
1235   private:
1236   public:
1237     CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter)
1238         : CommandObjectParsed(interpreter, "renderscript context dump",
1239                               "Dumps renderscript context information.", "renderscript context dump",
1240                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
1241     {
1242     }
1243 
1244     ~CommandObjectRenderScriptRuntimeContextDump() {}
1245 
1246     bool
1247     DoExecute(Args &command, CommandReturnObject &result)
1248     {
1249         RenderScriptRuntime *runtime =
1250             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
1251         runtime->DumpContexts(result.GetOutputStream());
1252         result.SetStatus(eReturnStatusSuccessFinishResult);
1253         return true;
1254     }
1255 };
1256 
1257 class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword
1258 {
1259   private:
1260   public:
1261     CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter)
1262         : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with renderscript contexts.",
1263                                  NULL)
1264     {
1265         LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(interpreter)));
1266     }
1267 
1268     ~CommandObjectRenderScriptRuntimeContext() {}
1269 };
1270 
1271 class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed
1272 {
1273   private:
1274   public:
1275     CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter)
1276         : CommandObjectParsed(interpreter, "renderscript status",
1277                               "Displays current renderscript runtime status.", "renderscript status",
1278                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
1279     {
1280     }
1281 
1282     ~CommandObjectRenderScriptRuntimeStatus() {}
1283 
1284     bool
1285     DoExecute(Args &command, CommandReturnObject &result)
1286     {
1287         RenderScriptRuntime *runtime =
1288             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
1289         runtime->Status(result.GetOutputStream());
1290         result.SetStatus(eReturnStatusSuccessFinishResult);
1291         return true;
1292     }
1293 };
1294 
1295 class CommandObjectRenderScriptRuntime : public CommandObjectMultiword
1296 {
1297   public:
1298     CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter)
1299         : CommandObjectMultiword(interpreter, "renderscript", "A set of commands for operating on renderscript.",
1300                                  "renderscript <subcommand> [<subcommand-options>]")
1301     {
1302         LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter)));
1303         LoadSubCommand("status", CommandObjectSP(new CommandObjectRenderScriptRuntimeStatus(interpreter)));
1304         LoadSubCommand("kernel", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernel(interpreter)));
1305         LoadSubCommand("context", CommandObjectSP(new CommandObjectRenderScriptRuntimeContext(interpreter)));
1306     }
1307 
1308     ~CommandObjectRenderScriptRuntime() {}
1309 };
1310 
1311 void
1312 RenderScriptRuntime::Initiate()
1313 {
1314     assert(!m_initiated);
1315 }
1316 
1317 RenderScriptRuntime::RenderScriptRuntime(Process *process)
1318     : lldb_private::CPPLanguageRuntime(process), m_initiated(false), m_debuggerPresentFlagged(false),
1319       m_breakAllKernels(false)
1320 {
1321     ModulesDidLoad(process->GetTarget().GetImages());
1322 }
1323 
1324 lldb::CommandObjectSP
1325 RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter& interpreter)
1326 {
1327     static CommandObjectSP command_object;
1328     if(!command_object)
1329     {
1330         command_object.reset(new CommandObjectRenderScriptRuntime(interpreter));
1331     }
1332     return command_object;
1333 }
1334 
1335