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/Host/StringConvert.h"
18 #include "lldb/Symbol/Symbol.h"
19 #include "lldb/Symbol/Type.h"
20 #include "lldb/Target/Process.h"
21 #include "lldb/Target/Target.h"
22 #include "lldb/Interpreter/Args.h"
23 #include "lldb/Interpreter/Options.h"
24 #include "lldb/Interpreter/CommandInterpreter.h"
25 #include "lldb/Interpreter/CommandReturnObject.h"
26 #include "lldb/Interpreter/CommandObjectMultiword.h"
27 #include "lldb/Breakpoint/StoppointCallbackContext.h"
28 #include "lldb/Target/RegisterContext.h"
29 #include "lldb/Expression/UserExpression.h"
30 #include "lldb/Symbol/VariableList.h"
31 
32 using namespace lldb;
33 using namespace lldb_private;
34 using namespace lldb_renderscript;
35 
36 namespace {
37 
38 // The empirical_type adds a basic level of validation to arbitrary data
39 // allowing us to track if data has been discovered and stored or not.
40 // An empirical_type will be marked as valid only if it has been explicitly assigned to.
41 template <typename type_t>
42 class empirical_type
43 {
44   public:
45     // Ctor. Contents is invalid when constructed.
46     empirical_type()
47         : valid(false)
48     {}
49 
50     // Return true and copy contents to out if valid, else return false.
51     bool get(type_t& out) const
52     {
53         if (valid)
54             out = data;
55         return valid;
56     }
57 
58     // Return a pointer to the contents or nullptr if it was not valid.
59     const type_t* get() const
60     {
61         return valid ? &data : nullptr;
62     }
63 
64     // Assign data explicitly.
65     void set(const type_t in)
66     {
67         data = in;
68         valid = true;
69     }
70 
71     // Mark contents as invalid.
72     void invalidate()
73     {
74         valid = false;
75     }
76 
77     // Returns true if this type contains valid data.
78     bool isValid() const
79     {
80         return valid;
81     }
82 
83     // Assignment operator.
84     empirical_type<type_t>& operator = (const type_t in)
85     {
86         set(in);
87         return *this;
88     }
89 
90     // Dereference operator returns contents.
91     // Warning: Will assert if not valid so use only when you know data is valid.
92     const type_t& operator * () const
93     {
94         assert(valid);
95         return data;
96     }
97 
98   protected:
99     bool valid;
100     type_t data;
101 };
102 
103 } // namespace {}
104 
105 // The ScriptDetails class collects data associated with a single script instance.
106 struct RenderScriptRuntime::ScriptDetails
107 {
108     ~ScriptDetails() {};
109 
110     enum ScriptType
111     {
112         eScript,
113         eScriptC
114     };
115 
116     // The derived type of the script.
117     empirical_type<ScriptType> type;
118     // The name of the original source file.
119     empirical_type<std::string> resName;
120     // Path to script .so file on the device.
121     empirical_type<std::string> scriptDyLib;
122     // Directory where kernel objects are cached on device.
123     empirical_type<std::string> cacheDir;
124     // Pointer to the context which owns this script.
125     empirical_type<lldb::addr_t> context;
126     // Pointer to the script object itself.
127     empirical_type<lldb::addr_t> script;
128 };
129 
130 // This AllocationDetails class collects data associated with a single
131 // allocation instance.
132 struct RenderScriptRuntime::AllocationDetails
133 {
134    // Taken from rsDefines.h
135    enum DataKind
136    {
137        RS_KIND_USER,
138        RS_KIND_PIXEL_L = 7,
139        RS_KIND_PIXEL_A,
140        RS_KIND_PIXEL_LA,
141        RS_KIND_PIXEL_RGB,
142        RS_KIND_PIXEL_RGBA,
143        RS_KIND_PIXEL_DEPTH,
144        RS_KIND_PIXEL_YUV,
145        RS_KIND_INVALID = 100
146    };
147 
148    // Taken from rsDefines.h
149    enum DataType
150    {
151        RS_TYPE_NONE = 0,
152        RS_TYPE_FLOAT_16,
153        RS_TYPE_FLOAT_32,
154        RS_TYPE_FLOAT_64,
155        RS_TYPE_SIGNED_8,
156        RS_TYPE_SIGNED_16,
157        RS_TYPE_SIGNED_32,
158        RS_TYPE_SIGNED_64,
159        RS_TYPE_UNSIGNED_8,
160        RS_TYPE_UNSIGNED_16,
161        RS_TYPE_UNSIGNED_32,
162        RS_TYPE_UNSIGNED_64,
163        RS_TYPE_BOOLEAN
164     };
165 
166     struct Dimension
167     {
168         uint32_t dim_1;
169         uint32_t dim_2;
170         uint32_t dim_3;
171         uint32_t cubeMap;
172 
173         Dimension()
174         {
175              dim_1 = 0;
176              dim_2 = 0;
177              dim_3 = 0;
178              cubeMap = 0;
179         }
180     };
181 
182     // Header for reading and writing allocation contents
183     // to a binary file.
184     struct FileHeader
185     {
186         uint8_t ident[4];      // ASCII 'RSAD' identifying the file
187         uint16_t hdr_size;     // Header size in bytes, for backwards compatability
188         uint16_t type;         // DataType enum
189         uint32_t kind;         // DataKind enum
190         uint32_t dims[3];      // Dimensions
191         uint32_t element_size; // Size of a single element, including padding
192     };
193 
194     // Monotonically increasing from 1
195     static unsigned int ID;
196 
197     // Maps Allocation DataType enum and vector size to printable strings
198     // using mapping from RenderScript numerical types summary documentation
199     static const char* RsDataTypeToString[][4];
200 
201     // Maps Allocation DataKind enum to printable strings
202     static const char* RsDataKindToString[];
203 
204     // Maps allocation types to format sizes for printing.
205     static const unsigned int RSTypeToFormat[][3];
206 
207     // Give each allocation an ID as a way
208     // for commands to reference it.
209     const unsigned int id;
210 
211     empirical_type<DataType> type;            // Type of each data pointer stored by the allocation
212     empirical_type<DataKind> type_kind;       // Defines pixel type if Allocation is created from an image
213     empirical_type<uint32_t> type_vec_size;   // Vector size of each data point, e.g '4' for uchar4
214     empirical_type<Dimension> dimension;      // Dimensions of the Allocation
215     empirical_type<lldb::addr_t> address;     // Pointer to address of the RS Allocation
216     empirical_type<lldb::addr_t> data_ptr;    // Pointer to the data held by the Allocation
217     empirical_type<lldb::addr_t> type_ptr;    // Pointer to the RS Type of the Allocation
218     empirical_type<lldb::addr_t> element_ptr; // Pointer to the RS Element of the Type
219     empirical_type<lldb::addr_t> context;     // Pointer to the RS Context of the Allocation
220     empirical_type<uint32_t> size;            // Size of the allocation
221     empirical_type<uint32_t> stride;          // Stride between rows of the allocation
222 
223     // Give each allocation an id, so we can reference it in user commands.
224     AllocationDetails(): id(ID++)
225     {
226     }
227 
228 };
229 
230 unsigned int RenderScriptRuntime::AllocationDetails::ID = 1;
231 
232 const char* RenderScriptRuntime::AllocationDetails::RsDataKindToString[] =
233 {
234    "User",
235    "Undefined", "Undefined", "Undefined", // Enum jumps from 0 to 7
236    "Undefined", "Undefined", "Undefined",
237    "L Pixel",
238    "A Pixel",
239    "LA Pixel",
240    "RGB Pixel",
241    "RGBA Pixel",
242    "Pixel Depth",
243    "YUV Pixel"
244 };
245 
246 const char* RenderScriptRuntime::AllocationDetails::RsDataTypeToString[][4] =
247 {
248     {"None", "None", "None", "None"},
249     {"half", "half2", "half3", "half4"},
250     {"float", "float2", "float3", "float4"},
251     {"double", "double2", "double3", "double4"},
252     {"char", "char2", "char3", "char4"},
253     {"short", "short2", "short3", "short4"},
254     {"int", "int2", "int3", "int4"},
255     {"long", "long2", "long3", "long4"},
256     {"uchar", "uchar2", "uchar3", "uchar4"},
257     {"ushort", "ushort2", "ushort3", "ushort4"},
258     {"uint", "uint2", "uint3", "uint4"},
259     {"ulong", "ulong2", "ulong3", "ulong4"},
260     {"bool", "bool2", "bool3", "bool4"}
261 };
262 
263 // Used as an index into the RSTypeToFormat array elements
264 enum TypeToFormatIndex {
265    eFormatSingle = 0,
266    eFormatVector,
267    eElementSize
268 };
269 
270 // { format enum of single element, format enum of element vector, size of element}
271 const unsigned int RenderScriptRuntime::AllocationDetails::RSTypeToFormat[][3] =
272 {
273     {eFormatHex, eFormatHex, 1}, // RS_TYPE_NONE
274     {eFormatFloat, eFormatVectorOfFloat16, 2}, // RS_TYPE_FLOAT_16
275     {eFormatFloat, eFormatVectorOfFloat32, sizeof(float)}, // RS_TYPE_FLOAT_32
276     {eFormatFloat, eFormatVectorOfFloat64, sizeof(double)}, // RS_TYPE_FLOAT_64
277     {eFormatDecimal, eFormatVectorOfSInt8, sizeof(int8_t)}, // RS_TYPE_SIGNED_8
278     {eFormatDecimal, eFormatVectorOfSInt16, sizeof(int16_t)}, // RS_TYPE_SIGNED_16
279     {eFormatDecimal, eFormatVectorOfSInt32, sizeof(int32_t)}, // RS_TYPE_SIGNED_32
280     {eFormatDecimal, eFormatVectorOfSInt64, sizeof(int64_t)}, // RS_TYPE_SIGNED_64
281     {eFormatDecimal, eFormatVectorOfUInt8, sizeof(uint8_t)}, // RS_TYPE_UNSIGNED_8
282     {eFormatDecimal, eFormatVectorOfUInt16, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_16
283     {eFormatDecimal, eFormatVectorOfUInt32, sizeof(uint32_t)}, // RS_TYPE_UNSIGNED_32
284     {eFormatDecimal, eFormatVectorOfUInt64, sizeof(uint64_t)}, // RS_TYPE_UNSIGNED_64
285     {eFormatBoolean, eFormatBoolean, sizeof(bool)} // RS_TYPE_BOOL
286 };
287 
288 //------------------------------------------------------------------
289 // Static Functions
290 //------------------------------------------------------------------
291 LanguageRuntime *
292 RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType language)
293 {
294 
295     if (language == eLanguageTypeExtRenderScript)
296         return new RenderScriptRuntime(process);
297     else
298         return NULL;
299 }
300 
301 // Callback with a module to search for matching symbols.
302 // We first check that the module contains RS kernels.
303 // Then look for a symbol which matches our kernel name.
304 // The breakpoint address is finally set using the address of this symbol.
305 Searcher::CallbackReturn
306 RSBreakpointResolver::SearchCallback(SearchFilter &filter,
307                                      SymbolContext &context,
308                                      Address*,
309                                      bool)
310 {
311     ModuleSP module = context.module_sp;
312 
313     if (!module)
314         return Searcher::eCallbackReturnContinue;
315 
316     // Is this a module containing renderscript kernels?
317     if (nullptr == module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData))
318         return Searcher::eCallbackReturnContinue;
319 
320     // Attempt to set a breakpoint on the kernel name symbol within the module library.
321     // If it's not found, it's likely debug info is unavailable - try to set a
322     // breakpoint on <name>.expand.
323 
324     const Symbol* kernel_sym = module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode);
325     if (!kernel_sym)
326     {
327         std::string kernel_name_expanded(m_kernel_name.AsCString());
328         kernel_name_expanded.append(".expand");
329         kernel_sym = module->FindFirstSymbolWithNameAndType(ConstString(kernel_name_expanded.c_str()), eSymbolTypeCode);
330     }
331 
332     if (kernel_sym)
333     {
334         Address bp_addr = kernel_sym->GetAddress();
335         if (filter.AddressPasses(bp_addr))
336             m_breakpoint->AddLocation(bp_addr);
337     }
338 
339     return Searcher::eCallbackReturnContinue;
340 }
341 
342 void
343 RenderScriptRuntime::Initialize()
344 {
345     PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance, GetCommandObject);
346 }
347 
348 void
349 RenderScriptRuntime::Terminate()
350 {
351     PluginManager::UnregisterPlugin(CreateInstance);
352 }
353 
354 lldb_private::ConstString
355 RenderScriptRuntime::GetPluginNameStatic()
356 {
357     static ConstString g_name("renderscript");
358     return g_name;
359 }
360 
361 RenderScriptRuntime::ModuleKind
362 RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp)
363 {
364     if (module_sp)
365     {
366         // Is this a module containing renderscript kernels?
367         const Symbol *info_sym = module_sp->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
368         if (info_sym)
369         {
370             return eModuleKindKernelObj;
371         }
372 
373         // Is this the main RS runtime library
374         const ConstString rs_lib("libRS.so");
375         if (module_sp->GetFileSpec().GetFilename() == rs_lib)
376         {
377             return eModuleKindLibRS;
378         }
379 
380         const ConstString rs_driverlib("libRSDriver.so");
381         if (module_sp->GetFileSpec().GetFilename() == rs_driverlib)
382         {
383             return eModuleKindDriver;
384         }
385 
386         const ConstString rs_cpureflib("libRSCpuRef.so");
387         if (module_sp->GetFileSpec().GetFilename() == rs_cpureflib)
388         {
389             return eModuleKindImpl;
390         }
391 
392     }
393     return eModuleKindIgnored;
394 }
395 
396 bool
397 RenderScriptRuntime::IsRenderScriptModule(const lldb::ModuleSP &module_sp)
398 {
399     return GetModuleKind(module_sp) != eModuleKindIgnored;
400 }
401 
402 
403 void
404 RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list )
405 {
406     Mutex::Locker locker (module_list.GetMutex ());
407 
408     size_t num_modules = module_list.GetSize();
409     for (size_t i = 0; i < num_modules; i++)
410     {
411         auto mod = module_list.GetModuleAtIndex (i);
412         if (IsRenderScriptModule (mod))
413         {
414             LoadModule(mod);
415         }
416     }
417 }
418 
419 
420 //------------------------------------------------------------------
421 // PluginInterface protocol
422 //------------------------------------------------------------------
423 lldb_private::ConstString
424 RenderScriptRuntime::GetPluginName()
425 {
426     return GetPluginNameStatic();
427 }
428 
429 uint32_t
430 RenderScriptRuntime::GetPluginVersion()
431 {
432     return 1;
433 }
434 
435 bool
436 RenderScriptRuntime::IsVTableName(const char *name)
437 {
438     return false;
439 }
440 
441 bool
442 RenderScriptRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
443                                               TypeAndOrName &class_type_or_name, Address &address,
444                                               Value::ValueType &value_type)
445 {
446     return false;
447 }
448 
449 TypeAndOrName
450 RenderScriptRuntime::FixUpDynamicType (const TypeAndOrName& type_and_or_name,
451                                        ValueObject& static_value)
452 {
453     return type_and_or_name;
454 }
455 
456 bool
457 RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value)
458 {
459     return false;
460 }
461 
462 lldb::BreakpointResolverSP
463 RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp)
464 {
465     BreakpointResolverSP resolver_sp;
466     return resolver_sp;
467 }
468 
469 
470 const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] =
471 {
472     //rsdScript
473     {
474         "rsdScriptInit", //name
475         "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhjj", // symbol name 32 bit
476         "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhmj", // symbol name 64 bit
477         0, // version
478         RenderScriptRuntime::eModuleKindDriver, // type
479         &lldb_private::RenderScriptRuntime::CaptureScriptInit1 // handler
480     },
481     {
482         "rsdScriptInvokeForEach", // name
483         "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvjPK12RsScriptCall", // symbol name 32bit
484         "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvmPK12RsScriptCall", // symbol name 64bit
485         0, // version
486         RenderScriptRuntime::eModuleKindDriver, // type
487         nullptr // handler
488     },
489     {
490         "rsdScriptInvokeForEachMulti", // name
491         "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall", // symbol name 32bit
492         "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEmPS6_PKvmPK12RsScriptCall", // symbol name 64bit
493         0, // version
494         RenderScriptRuntime::eModuleKindDriver, // type
495         nullptr // handler
496     },
497     {
498         "rsdScriptInvokeFunction", // name
499         "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvj", // symbol name 32bit
500         "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvm", // symbol name 64bit
501         0, // version
502         RenderScriptRuntime::eModuleKindDriver, // type
503         nullptr // handler
504     },
505     {
506         "rsdScriptSetGlobalVar", // name
507         "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvj", // symbol name 32bit
508         "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvm", // symbol name 64bit
509         0, // version
510         RenderScriptRuntime::eModuleKindDriver, // type
511         &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar1 // handler
512     },
513 
514     //rsdAllocation
515     {
516         "rsdAllocationInit", // name
517         "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 32bit
518         "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 64bit
519         0, // version
520         RenderScriptRuntime::eModuleKindDriver, // type
521         &lldb_private::RenderScriptRuntime::CaptureAllocationInit1 // handler
522     },
523     {
524         "rsdAllocationRead2D", //name
525         "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvjj", // symbol name 32bit
526         "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvmm", // symbol name 64bit
527         0, // version
528         RenderScriptRuntime::eModuleKindDriver, // type
529         nullptr // handler
530     },
531 };
532 const size_t RenderScriptRuntime::s_runtimeHookCount = sizeof(s_runtimeHookDefns)/sizeof(s_runtimeHookDefns[0]);
533 
534 
535 bool
536 RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
537 {
538     RuntimeHook* hook_info = (RuntimeHook*)baton;
539     ExecutionContext context(ctx->exe_ctx_ref);
540 
541     RenderScriptRuntime *lang_rt = (RenderScriptRuntime *)context.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
542 
543     lang_rt->HookCallback(hook_info, context);
544 
545     return false;
546 }
547 
548 
549 void
550 RenderScriptRuntime::HookCallback(RuntimeHook* hook_info, ExecutionContext& context)
551 {
552     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
553 
554     if (log)
555         log->Printf ("RenderScriptRuntime::HookCallback - '%s' .", hook_info->defn->name);
556 
557     if (hook_info->defn->grabber)
558     {
559         (this->*(hook_info->defn->grabber))(hook_info, context);
560     }
561 }
562 
563 
564 bool
565 RenderScriptRuntime::GetArgSimple(ExecutionContext &context, uint32_t arg, uint64_t *data)
566 {
567     if (!data)
568         return false;
569 
570     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
571     Error error;
572     RegisterContext* reg_ctx = context.GetRegisterContext();
573     Process* process = context.GetProcessPtr();
574     bool success = false; // return value
575 
576     if (!context.GetTargetPtr())
577     {
578         if (log)
579             log->Printf("RenderScriptRuntime::GetArgSimple - Invalid target");
580 
581         return false;
582     }
583 
584     switch (context.GetTargetPtr()->GetArchitecture().GetMachine())
585     {
586         case llvm::Triple::ArchType::x86:
587         {
588             uint64_t sp = reg_ctx->GetSP();
589             uint32_t offset = (1 + arg) * sizeof(uint32_t);
590             uint32_t result = 0;
591             process->ReadMemory(sp + offset, &result, sizeof(uint32_t), error);
592             if (error.Fail())
593             {
594                 if (log)
595                     log->Printf ("RenderScriptRuntime:: GetArgSimple - error reading X86 stack: %s.", error.AsCString());
596             }
597             else
598             {
599                 *data = result;
600                 success = true;
601             }
602 
603             break;
604         }
605         case llvm::Triple::ArchType::arm:
606         {
607             // arm 32 bit
608             if (arg < 4)
609             {
610                 const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg);
611                 RegisterValue rVal;
612                 success = reg_ctx->ReadRegister(rArg, rVal);
613                 if (success)
614                 {
615                     (*data) = rVal.GetAsUInt32();
616                 }
617                 else
618                 {
619                     if (log)
620                         log->Printf ("RenderScriptRuntime:: GetArgSimple - error reading ARM register: %d.", arg);
621                 }
622             }
623             else
624             {
625                 uint64_t sp = reg_ctx->GetSP();
626                 uint32_t offset = (arg-4) * sizeof(uint32_t);
627                 process->ReadMemory(sp + offset, &data, sizeof(uint32_t), error);
628                 if (error.Fail())
629                 {
630                     if (log)
631                         log->Printf ("RenderScriptRuntime:: GetArgSimple - error reading ARM stack: %s.", error.AsCString());
632                 }
633                 else
634                 {
635                     success = true;
636                 }
637             }
638 
639             break;
640         }
641         case llvm::Triple::ArchType::aarch64:
642         {
643             // arm 64 bit
644             // first 8 arguments are in the registers
645             if (arg < 8)
646             {
647                 const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg);
648                 RegisterValue rVal;
649                 success = reg_ctx->ReadRegister(rArg, rVal);
650                 if (success)
651                 {
652                     *data = rVal.GetAsUInt64();
653                 }
654                 else
655                 {
656                     if (log)
657                         log->Printf("RenderScriptRuntime::GetArgSimple() - AARCH64 - Error while reading the argument #%d", arg);
658                 }
659             }
660             else
661             {
662                 // @TODO: need to find the argument in the stack
663                 if (log)
664                     log->Printf("RenderScriptRuntime::GetArgSimple - AARCH64 - FOR #ARG >= 8 NOT IMPLEMENTED YET. Argument number: %d", arg);
665             }
666             break;
667         }
668         case llvm::Triple::ArchType::mips64el:
669         {
670             // read from the registers
671             if (arg < 8)
672             {
673                 const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg + 4);
674                 RegisterValue rVal;
675                 success = reg_ctx->ReadRegister(rArg, rVal);
676                 if (success)
677                 {
678                     (*data) = rVal.GetAsUInt64();
679                 }
680                 else
681                 {
682                     if (log)
683                         log->Printf("RenderScriptRuntime::GetArgSimple - Mips64 - Error reading the argument #%d", arg);
684                 }
685             }
686 
687             // read from the stack
688             else
689             {
690                 uint64_t sp = reg_ctx->GetSP();
691                 uint32_t offset = (arg - 8) * sizeof(uint64_t);
692                 process->ReadMemory(sp + offset, &data, sizeof(uint64_t), error);
693                 if (error.Fail())
694                 {
695                     if (log)
696                         log->Printf ("RenderScriptRuntime::GetArgSimple - Mips64 - Error reading Mips64 stack: %s.", error.AsCString());
697                 }
698                 else
699                 {
700                     success = true;
701                 }
702             }
703 
704             break;
705         }
706         default:
707         {
708             // invalid architecture
709             if (log)
710                 log->Printf("RenderScriptRuntime::GetArgSimple - Architecture not supported");
711 
712         }
713     }
714 
715 
716     return success;
717 }
718 
719 void
720 RenderScriptRuntime::CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context)
721 {
722     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
723 
724     //Context, Script, int, data, length
725 
726     uint64_t rs_context_u64 = 0U;
727     uint64_t rs_script_u64 = 0U;
728     uint64_t rs_id_u64 = 0U;
729     uint64_t rs_data_u64 = 0U;
730     uint64_t rs_length_u64 = 0U;
731 
732     bool success =
733         GetArgSimple(context, 0, &rs_context_u64) &&
734         GetArgSimple(context, 1, &rs_script_u64) &&
735         GetArgSimple(context, 2, &rs_id_u64) &&
736         GetArgSimple(context, 3, &rs_data_u64) &&
737         GetArgSimple(context, 4, &rs_length_u64);
738 
739     if (!success)
740     {
741         if (log)
742             log->Printf("RenderScriptRuntime::CaptureSetGlobalVar1 - Error while reading the function parameters");
743         return;
744     }
745 
746     if (log)
747     {
748         log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 ":%" PRIu64 "bytes.",
749                         rs_context_u64, rs_script_u64, rs_id_u64, rs_data_u64, rs_length_u64);
750 
751         addr_t script_addr =  (addr_t)rs_script_u64;
752         if (m_scriptMappings.find( script_addr ) != m_scriptMappings.end())
753         {
754             auto rsm = m_scriptMappings[script_addr];
755             if (rs_id_u64 < rsm->m_globals.size())
756             {
757                 auto rsg = rsm->m_globals[rs_id_u64];
758                 log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - Setting of '%s' within '%s' inferred", rsg.m_name.AsCString(),
759                                 rsm->m_module->GetFileSpec().GetFilename().AsCString());
760             }
761         }
762     }
763 }
764 
765 void
766 RenderScriptRuntime::CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context)
767 {
768     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
769 
770     //Context, Alloc, bool
771 
772     uint64_t rs_context_u64 = 0U;
773     uint64_t rs_alloc_u64 = 0U;
774     uint64_t rs_forceZero_u64 = 0U;
775 
776     bool success =
777         GetArgSimple(context, 0, &rs_context_u64) &&
778         GetArgSimple(context, 1, &rs_alloc_u64) &&
779         GetArgSimple(context, 2, &rs_forceZero_u64);
780     if (!success) // error case
781     {
782         if (log)
783             log->Printf("RenderScriptRuntime::CaptureAllocationInit1 - Error while reading the function parameters");
784         return; // abort
785     }
786 
787     if (log)
788         log->Printf ("RenderScriptRuntime::CaptureAllocationInit1 - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .",
789                         rs_context_u64, rs_alloc_u64, rs_forceZero_u64);
790 
791     AllocationDetails* alloc = LookUpAllocation(rs_alloc_u64, true);
792     if (alloc)
793         alloc->context = rs_context_u64;
794 }
795 
796 void
797 RenderScriptRuntime::CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context)
798 {
799     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
800 
801     //Context, Script, resname Str, cachedir Str
802     Error error;
803     Process* process = context.GetProcessPtr();
804 
805     uint64_t rs_context_u64 = 0U;
806     uint64_t rs_script_u64 = 0U;
807     uint64_t rs_resnameptr_u64 = 0U;
808     uint64_t rs_cachedirptr_u64 = 0U;
809 
810     std::string resname;
811     std::string cachedir;
812 
813     // read the function parameters
814     bool success =
815         GetArgSimple(context, 0, &rs_context_u64) &&
816         GetArgSimple(context, 1, &rs_script_u64) &&
817         GetArgSimple(context, 2, &rs_resnameptr_u64) &&
818         GetArgSimple(context, 3, &rs_cachedirptr_u64);
819 
820     if (!success)
821     {
822         if (log)
823             log->Printf("RenderScriptRuntime::CaptureScriptInit1 - Error while reading the function parameters");
824         return;
825     }
826 
827     process->ReadCStringFromMemory((lldb::addr_t)rs_resnameptr_u64, resname, error);
828     if (error.Fail())
829     {
830         if (log)
831             log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading resname: %s.", error.AsCString());
832 
833     }
834 
835     process->ReadCStringFromMemory((lldb::addr_t)rs_cachedirptr_u64, cachedir, error);
836     if (error.Fail())
837     {
838         if (log)
839             log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading cachedir: %s.", error.AsCString());
840     }
841 
842     if (log)
843         log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .",
844                      rs_context_u64, rs_script_u64, resname.c_str(), cachedir.c_str());
845 
846     if (resname.size() > 0)
847     {
848         StreamString strm;
849         strm.Printf("librs.%s.so", resname.c_str());
850 
851         ScriptDetails* script = LookUpScript(rs_script_u64, true);
852         if (script)
853         {
854             script->type = ScriptDetails::eScriptC;
855             script->cacheDir = cachedir;
856             script->resName = resname;
857             script->scriptDyLib = strm.GetData();
858             script->context = addr_t(rs_context_u64);
859         }
860 
861         if (log)
862             log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - '%s' tagged with context 0x%" PRIx64 " and script 0x%" PRIx64 ".",
863                          strm.GetData(), rs_context_u64, rs_script_u64);
864     }
865     else if (log)
866     {
867         log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - resource name invalid, Script not tagged");
868     }
869 
870 }
871 
872 void
873 RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
874 {
875     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
876 
877     if (!module)
878     {
879         return;
880     }
881 
882     Target &target = GetProcess()->GetTarget();
883     llvm::Triple::ArchType targetArchType = target.GetArchitecture().GetMachine();
884 
885     if (targetArchType != llvm::Triple::ArchType::x86
886         && targetArchType != llvm::Triple::ArchType::arm
887         && targetArchType != llvm::Triple::ArchType::aarch64
888         && targetArchType != llvm::Triple::ArchType::mips64el
889     )
890     {
891         if (log)
892             log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to hook runtime. Only X86, ARM, Mips64 supported currently.");
893 
894         return;
895     }
896 
897     uint32_t archByteSize = target.GetArchitecture().GetAddressByteSize();
898 
899     for (size_t idx = 0; idx < s_runtimeHookCount; idx++)
900     {
901         const HookDefn* hook_defn = &s_runtimeHookDefns[idx];
902         if (hook_defn->kind != kind) {
903             continue;
904         }
905 
906         const char* symbol_name = (archByteSize == 4) ? hook_defn->symbol_name_m32 : hook_defn->symbol_name_m64;
907 
908         const Symbol *sym = module->FindFirstSymbolWithNameAndType(ConstString(symbol_name), eSymbolTypeCode);
909         if (!sym){
910             if (log){
911                 log->Printf("RenderScriptRuntime::LoadRuntimeHooks - ERROR: Symbol '%s' related to the function %s not found", symbol_name, hook_defn->name);
912             }
913             continue;
914         }
915 
916         addr_t addr = sym->GetLoadAddress(&target);
917         if (addr == LLDB_INVALID_ADDRESS)
918         {
919             if (log)
920                 log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to resolve the address of hook function '%s' with symbol '%s'.",
921                              hook_defn->name, symbol_name);
922             continue;
923         }
924         else
925         {
926             if (log)
927                 log->Printf("RenderScriptRuntime::LoadRuntimeHooks - Function %s, address resolved at 0x%" PRIx64, hook_defn->name, addr);
928         }
929 
930         RuntimeHookSP hook(new RuntimeHook());
931         hook->address = addr;
932         hook->defn = hook_defn;
933         hook->bp_sp = target.CreateBreakpoint(addr, true, false);
934         hook->bp_sp->SetCallback(HookCallback, hook.get(), true);
935         m_runtimeHooks[addr] = hook;
936         if (log)
937         {
938             log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Successfully hooked '%s' in '%s' version %" PRIu64 " at 0x%" PRIx64 ".",
939                 hook_defn->name, module->GetFileSpec().GetFilename().AsCString(), (uint64_t)hook_defn->version, (uint64_t)addr);
940         }
941     }
942 }
943 
944 void
945 RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp)
946 {
947     if (!rsmodule_sp)
948         return;
949 
950     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
951 
952     const ModuleSP module = rsmodule_sp->m_module;
953     const FileSpec& file = module->GetPlatformFileSpec();
954 
955     // Iterate over all of the scripts that we currently know of.
956     // Note: We cant push or pop to m_scripts here or it may invalidate rs_script.
957     for (const auto & rs_script : m_scripts)
958     {
959         // Extract the expected .so file path for this script.
960         std::string dylib;
961         if (!rs_script->scriptDyLib.get(dylib))
962             continue;
963 
964         // Only proceed if the module that has loaded corresponds to this script.
965         if (file.GetFilename() != ConstString(dylib.c_str()))
966             continue;
967 
968         // Obtain the script address which we use as a key.
969         lldb::addr_t script;
970         if (!rs_script->script.get(script))
971             continue;
972 
973         // If we have a script mapping for the current script.
974         if (m_scriptMappings.find(script) != m_scriptMappings.end())
975         {
976             // if the module we have stored is different to the one we just received.
977             if (m_scriptMappings[script] != rsmodule_sp)
978             {
979                 if (log)
980                     log->Printf ("RenderScriptRuntime::FixupScriptDetails - Error: script %" PRIx64 " wants reassigned to new rsmodule '%s'.",
981                                     (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
982             }
983         }
984         // We don't have a script mapping for the current script.
985         else
986         {
987             // Obtain the script resource name.
988             std::string resName;
989             if (rs_script->resName.get(resName))
990                 // Set the modules resource name.
991                 rsmodule_sp->m_resname = resName;
992             // Add Script/Module pair to map.
993             m_scriptMappings[script] = rsmodule_sp;
994             if (log)
995                 log->Printf ("RenderScriptRuntime::FixupScriptDetails - script %" PRIx64 " associated with rsmodule '%s'.",
996                                 (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
997         }
998     }
999 }
1000 
1001 // Uses the Target API to evaluate the expression passed as a parameter to the function
1002 // The result of that expression is returned an unsigned 64 bit int, via the result* paramter.
1003 // Function returns true on success, and false on failure
1004 bool
1005 RenderScriptRuntime::EvalRSExpression(const char* expression, StackFrame* frame_ptr, uint64_t* result)
1006 {
1007     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1008     if (log)
1009         log->Printf("RenderScriptRuntime::EvalRSExpression(%s)", expression);
1010 
1011     ValueObjectSP expr_result;
1012     // Perform the actual expression evaluation
1013     GetProcess()->GetTarget().EvaluateExpression(expression, frame_ptr, expr_result);
1014 
1015     if (!expr_result)
1016     {
1017        if (log)
1018            log->Printf("RenderScriptRuntime::EvalRSExpression -  Error: Couldn't evaluate expression");
1019        return false;
1020     }
1021 
1022     // The result of the expression is invalid
1023     if (!expr_result->GetError().Success())
1024     {
1025         Error err = expr_result->GetError();
1026         if (err.GetError() == UserExpression::kNoResult) // Expression returned void, so this is actually a success
1027         {
1028             if (log)
1029                 log->Printf("RenderScriptRuntime::EvalRSExpression - Expression returned void");
1030 
1031             result = nullptr;
1032             return true;
1033         }
1034 
1035         if (log)
1036             log->Printf("RenderScriptRuntime::EvalRSExpression - Error evaluating expression result: %s", err.AsCString());
1037         return false;
1038     }
1039 
1040     bool success = false;
1041     *result = expr_result->GetValueAsUnsigned(0, &success); // We only read the result as an unsigned int.
1042 
1043     if (!success)
1044     {
1045        if (log)
1046            log->Printf("RenderScriptRuntime::EvalRSExpression -  Error: Couldn't convert expression result to unsigned int");
1047        return false;
1048     }
1049 
1050     return true;
1051 }
1052 
1053 // Used to index expression format strings
1054 enum ExpressionStrings
1055 {
1056    eExprGetOffsetPtr = 0,
1057    eExprAllocGetType,
1058    eExprTypeDimX,
1059    eExprTypeDimY,
1060    eExprTypeDimZ,
1061    eExprTypeElemPtr,
1062    eExprElementType,
1063    eExprElementKind,
1064    eExprElementVec
1065 };
1066 
1067 // Format strings containing the expressions we may need to evaluate.
1068 const char runtimeExpressions[][256] =
1069 {
1070  // Mangled GetOffsetPointer(Allocation*, xoff, yoff, zoff, lod, cubemap)
1071  "(int*)_Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocationCubemapFace(0x%lx, %u, %u, %u, 0, 0)",
1072 
1073  // Type* rsaAllocationGetType(Context*, Allocation*)
1074  "(void*)rsaAllocationGetType(0x%lx, 0x%lx)",
1075 
1076  // rsaTypeGetNativeData(Context*, Type*, void* typeData, size)
1077  // Pack the data in the following way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ;
1078  // mHal.state.lodCount; mHal.state.faces; mElement; into typeData
1079  // Need to specify 32 or 64 bit for uint_t since this differs between devices
1080  "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[0]", // X dim
1081  "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[1]", // Y dim
1082  "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[2]", // Z dim
1083  "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[5]", // Element ptr
1084 
1085  // rsaElementGetNativeData(Context*, Element*, uint32_t* elemData,size)
1086  // Pack mType; mKind; mNormalized; mVectorSize; NumSubElements into elemData
1087  "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[0]", // Type
1088  "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[1]", // Kind
1089  "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[3]"  // Vector Size
1090 };
1091 
1092 // JITs the RS runtime for the internal data pointer of an allocation.
1093 // Is passed x,y,z coordinates for the pointer to a specific element.
1094 // Then sets the data_ptr member in Allocation with the result.
1095 // Returns true on success, false otherwise
1096 bool
1097 RenderScriptRuntime::JITDataPointer(AllocationDetails* allocation, StackFrame* frame_ptr,
1098                                     unsigned int x, unsigned int y, unsigned int z)
1099 {
1100     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1101 
1102     if (!allocation->address.isValid())
1103     {
1104         if (log)
1105             log->Printf("RenderScriptRuntime::JITDataPointer - Failed to find allocation details");
1106         return false;
1107     }
1108 
1109     const char* expr_cstr = runtimeExpressions[eExprGetOffsetPtr];
1110     const int max_expr_size = 512; // Max expression size
1111     char buffer[max_expr_size];
1112 
1113     int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->address.get(), x, y, z);
1114     if (chars_written < 0)
1115     {
1116         if (log)
1117             log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
1118         return false;
1119     }
1120     else if (chars_written >= max_expr_size)
1121     {
1122         if (log)
1123             log->Printf("RenderScriptRuntime::JITDataPointer - Expression too long");
1124         return false;
1125     }
1126 
1127     uint64_t result = 0;
1128     if (!EvalRSExpression(buffer, frame_ptr, &result))
1129         return false;
1130 
1131     addr_t mem_ptr = static_cast<lldb::addr_t>(result);
1132     allocation->data_ptr = mem_ptr;
1133 
1134     return true;
1135 }
1136 
1137 // JITs the RS runtime for the internal pointer to the RS Type of an allocation
1138 // Then sets the type_ptr member in Allocation with the result.
1139 // Returns true on success, false otherwise
1140 bool
1141 RenderScriptRuntime::JITTypePointer(AllocationDetails* allocation, StackFrame* frame_ptr)
1142 {
1143     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1144 
1145     if (!allocation->address.isValid() || !allocation->context.isValid())
1146     {
1147         if (log)
1148             log->Printf("RenderScriptRuntime::JITTypePointer - Failed to find allocation details");
1149         return false;
1150     }
1151 
1152     const char* expr_cstr = runtimeExpressions[eExprAllocGetType];
1153     const int max_expr_size = 512; // Max expression size
1154     char buffer[max_expr_size];
1155 
1156     int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->context.get(), *allocation->address.get());
1157     if (chars_written < 0)
1158     {
1159         if (log)
1160             log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
1161         return false;
1162     }
1163     else if (chars_written >= max_expr_size)
1164     {
1165         if (log)
1166             log->Printf("RenderScriptRuntime::JITTypePointer - Expression too long");
1167         return false;
1168     }
1169 
1170     uint64_t result = 0;
1171     if (!EvalRSExpression(buffer, frame_ptr, &result))
1172         return false;
1173 
1174     addr_t type_ptr = static_cast<lldb::addr_t>(result);
1175     allocation->type_ptr = type_ptr;
1176 
1177     return true;
1178 }
1179 
1180 // JITs the RS runtime for information about the dimensions and type of an allocation
1181 // Then sets dimension and element_ptr members in Allocation with the result.
1182 // Returns true on success, false otherwise
1183 bool
1184 RenderScriptRuntime::JITTypePacked(AllocationDetails* allocation, StackFrame* frame_ptr)
1185 {
1186     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1187 
1188     if (!allocation->type_ptr.isValid() || !allocation->context.isValid())
1189     {
1190         if (log)
1191             log->Printf("RenderScriptRuntime::JITTypePacked - Failed to find allocation details");
1192         return false;
1193     }
1194 
1195     // Expression is different depending on if device is 32 or 64 bit
1196     uint32_t archByteSize = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
1197     const unsigned int bits = archByteSize == 4 ? 32 : 64;
1198 
1199     // We want 4 elements from packed data
1200     const unsigned int num_exprs = 4;
1201     assert(num_exprs == (eExprTypeElemPtr - eExprTypeDimX + 1) && "Invalid number of expressions");
1202 
1203     const int max_expr_size = 512; // Max expression size
1204     char buffer[num_exprs][max_expr_size];
1205     uint64_t results[num_exprs];
1206 
1207     for (unsigned int i = 0; i < num_exprs; ++i)
1208     {
1209         int chars_written = snprintf(buffer[i], max_expr_size, runtimeExpressions[eExprTypeDimX + i], bits,
1210                                      *allocation->context.get(), *allocation->type_ptr.get());
1211         if (chars_written < 0)
1212         {
1213             if (log)
1214                 log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
1215             return false;
1216         }
1217         else if (chars_written >= max_expr_size)
1218         {
1219             if (log)
1220                 log->Printf("RenderScriptRuntime::JITTypePacked - Expression too long");
1221             return false;
1222         }
1223 
1224         // Perform expression evaluation
1225         if (!EvalRSExpression(buffer[i], frame_ptr, &results[i]))
1226             return false;
1227     }
1228 
1229     // Assign results to allocation members
1230     AllocationDetails::Dimension dims;
1231     dims.dim_1 = static_cast<uint32_t>(results[0]);
1232     dims.dim_2 = static_cast<uint32_t>(results[1]);
1233     dims.dim_3 = static_cast<uint32_t>(results[2]);
1234     allocation->dimension = dims;
1235 
1236     addr_t elem_ptr = static_cast<lldb::addr_t>(results[3]);
1237     allocation->element_ptr = elem_ptr;
1238 
1239     if (log)
1240         log->Printf("RenderScriptRuntime::JITTypePacked - dims (%u, %u, %u) Element*: 0x%" PRIx64,
1241                     dims.dim_1, dims.dim_2, dims.dim_3, elem_ptr);
1242 
1243     return true;
1244 }
1245 
1246 // JITs the RS runtime for information about the Element of an allocation
1247 // Then sets type, type_vec_size, and type_kind members in Allocation with the result.
1248 // Returns true on success, false otherwise
1249 bool
1250 RenderScriptRuntime::JITElementPacked(AllocationDetails* allocation, StackFrame* frame_ptr)
1251 {
1252     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1253 
1254     if (!allocation->element_ptr.isValid() || !allocation->context.isValid())
1255     {
1256         if (log)
1257             log->Printf("RenderScriptRuntime::JITElementPacked - Failed to find allocation details");
1258         return false;
1259     }
1260 
1261     // We want 3 elements from packed data
1262     const unsigned int num_exprs = 3;
1263     assert(num_exprs == (eExprElementVec - eExprElementType + 1) && "Invalid number of expressions");
1264 
1265     const int max_expr_size = 512; // Max expression size
1266     char buffer[num_exprs][max_expr_size];
1267     uint64_t results[num_exprs];
1268 
1269     for (unsigned int i = 0; i < num_exprs; i++)
1270     {
1271         int chars_written = snprintf(buffer[i], max_expr_size, runtimeExpressions[eExprElementType + i], *allocation->context.get(), *allocation->element_ptr.get());
1272         if (chars_written < 0)
1273         {
1274             if (log)
1275                 log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
1276             return false;
1277         }
1278         else if (chars_written >= max_expr_size)
1279         {
1280             if (log)
1281                 log->Printf("RenderScriptRuntime::JITElementPacked - Expression too long");
1282             return false;
1283         }
1284 
1285         // Perform expression evaluation
1286         if (!EvalRSExpression(buffer[i], frame_ptr, &results[i]))
1287             return false;
1288     }
1289 
1290     // Assign results to allocation members
1291     allocation->type = static_cast<RenderScriptRuntime::AllocationDetails::DataType>(results[0]);
1292     allocation->type_kind = static_cast<RenderScriptRuntime::AllocationDetails::DataKind>(results[1]);
1293     allocation->type_vec_size = static_cast<uint32_t>(results[2]);
1294 
1295     if (log)
1296         log->Printf("RenderScriptRuntime::JITElementPacked - data type %u, pixel type %u, vector size %u",
1297                     *allocation->type.get(), *allocation->type_kind.get(), *allocation->type_vec_size.get());
1298 
1299     return true;
1300 }
1301 
1302 // JITs the RS runtime for the address of the last element in the allocation.
1303 // The `elem_size` paramter represents the size of a single element, including padding.
1304 // Which is needed as an offset from the last element pointer.
1305 // Using this offset minus the starting address we can calculate the size of the allocation.
1306 // Returns true on success, false otherwise
1307 bool
1308 RenderScriptRuntime::JITAllocationSize(AllocationDetails* allocation, StackFrame* frame_ptr,
1309                                        const uint32_t elem_size)
1310 {
1311     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1312 
1313     if (!allocation->address.isValid() || !allocation->dimension.isValid()
1314         || !allocation->data_ptr.isValid())
1315     {
1316         if (log)
1317             log->Printf("RenderScriptRuntime::JITAllocationSize - Failed to find allocation details");
1318         return false;
1319     }
1320 
1321     const char* expr_cstr = runtimeExpressions[eExprGetOffsetPtr];
1322     const int max_expr_size = 512; // Max expression size
1323     char buffer[max_expr_size];
1324 
1325     // Find dimensions
1326     unsigned int dim_x = allocation->dimension.get()->dim_1;
1327     unsigned int dim_y = allocation->dimension.get()->dim_2;
1328     unsigned int dim_z = allocation->dimension.get()->dim_3;
1329 
1330     // Calculate last element
1331     dim_x = dim_x == 0 ? 0 : dim_x - 1;
1332     dim_y = dim_y == 0 ? 0 : dim_y - 1;
1333     dim_z = dim_z == 0 ? 0 : dim_z - 1;
1334 
1335     int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->address.get(),
1336                                  dim_x, dim_y, dim_z);
1337     if (chars_written < 0)
1338     {
1339         if (log)
1340             log->Printf("RenderScriptRuntime::JITAllocationSize - Encoding error in snprintf()");
1341         return false;
1342     }
1343     else if (chars_written >= max_expr_size)
1344     {
1345         if (log)
1346             log->Printf("RenderScriptRuntime::JITAllocationSize - Expression too long");
1347         return false;
1348     }
1349 
1350     uint64_t result = 0;
1351     if (!EvalRSExpression(buffer, frame_ptr, &result))
1352         return false;
1353 
1354     addr_t mem_ptr = static_cast<lldb::addr_t>(result);
1355     // Find pointer to last element and add on size of an element
1356     allocation->size = static_cast<uint32_t>(mem_ptr - *allocation->data_ptr.get()) + elem_size;
1357 
1358     return true;
1359 }
1360 
1361 // JITs the RS runtime for information about the stride between rows in the allocation.
1362 // This is done to detect padding, since allocated memory is 16-byte aligned.
1363 // Returns true on success, false otherwise
1364 bool
1365 RenderScriptRuntime::JITAllocationStride(AllocationDetails* allocation, StackFrame* frame_ptr)
1366 {
1367     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1368 
1369     if (!allocation->address.isValid() || !allocation->data_ptr.isValid())
1370     {
1371         if (log)
1372             log->Printf("RenderScriptRuntime::JITAllocationStride - Failed to find allocation details");
1373         return false;
1374     }
1375 
1376     const char* expr_cstr = runtimeExpressions[eExprGetOffsetPtr];
1377     const int max_expr_size = 512; // Max expression size
1378     char buffer[max_expr_size];
1379 
1380     int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->address.get(),
1381                                  0, 1, 0);
1382     if (chars_written < 0)
1383     {
1384         if (log)
1385             log->Printf("RenderScriptRuntime::JITAllocationStride - Encoding error in snprintf()");
1386         return false;
1387     }
1388     else if (chars_written >= max_expr_size)
1389     {
1390         if (log)
1391             log->Printf("RenderScriptRuntime::JITAllocationStride - Expression too long");
1392         return false;
1393     }
1394 
1395     uint64_t result = 0;
1396     if (!EvalRSExpression(buffer, frame_ptr, &result))
1397         return false;
1398 
1399     addr_t mem_ptr = static_cast<lldb::addr_t>(result);
1400     allocation->stride = static_cast<uint32_t>(mem_ptr - *allocation->data_ptr.get());
1401 
1402     return true;
1403 }
1404 
1405 // JIT all the current runtime info regarding an allocation
1406 bool
1407 RenderScriptRuntime::RefreshAllocation(AllocationDetails* allocation, StackFrame* frame_ptr)
1408 {
1409     // GetOffsetPointer()
1410     if (!JITDataPointer(allocation, frame_ptr))
1411         return false;
1412 
1413     // rsaAllocationGetType()
1414     if (!JITTypePointer(allocation, frame_ptr))
1415         return false;
1416 
1417     // rsaTypeGetNativeData()
1418     if (!JITTypePacked(allocation, frame_ptr))
1419         return false;
1420 
1421     // rsaElementGetNativeData()
1422     if (!JITElementPacked(allocation, frame_ptr))
1423         return false;
1424 
1425     // Use GetOffsetPointer() to infer size of the allocation
1426     const unsigned int element_size = GetElementSize(allocation);
1427     if (!JITAllocationSize(allocation, frame_ptr, element_size))
1428         return false;
1429 
1430     return true;
1431 }
1432 
1433 // Returns the size of a single allocation element including padding.
1434 // Assumes the relevant allocation information has already been jitted.
1435 unsigned int
1436 RenderScriptRuntime::GetElementSize(const AllocationDetails* allocation)
1437 {
1438     const AllocationDetails::DataType type = *allocation->type.get();
1439     assert(type >= AllocationDetails::RS_TYPE_NONE && type <= AllocationDetails::RS_TYPE_BOOLEAN
1440                                                    && "Invalid allocation type");
1441 
1442     const unsigned int vec_size = *allocation->type_vec_size.get();
1443     const unsigned int data_size = vec_size * AllocationDetails::RSTypeToFormat[type][eElementSize];
1444     const unsigned int padding = vec_size == 3 ? AllocationDetails::RSTypeToFormat[type][eElementSize] : 0;
1445 
1446     return data_size + padding;
1447 }
1448 
1449 // Given an allocation, this function copies the allocation contents from device into a buffer on the heap.
1450 // Returning a shared pointer to the buffer containing the data.
1451 std::shared_ptr<uint8_t>
1452 RenderScriptRuntime::GetAllocationData(AllocationDetails* allocation, StackFrame* frame_ptr)
1453 {
1454     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1455 
1456     // JIT all the allocation details
1457     if (!allocation->data_ptr.isValid() || !allocation->type.isValid() || !allocation->type_vec_size.isValid()
1458         || !allocation->size.isValid())
1459     {
1460         if (log)
1461             log->Printf("RenderScriptRuntime::GetAllocationData - Allocation details not calculated yet, jitting info");
1462 
1463         if (!RefreshAllocation(allocation, frame_ptr))
1464         {
1465             if (log)
1466                 log->Printf("RenderScriptRuntime::GetAllocationData - Couldn't JIT allocation details");
1467             return nullptr;
1468         }
1469     }
1470 
1471     assert(allocation->data_ptr.isValid() && allocation->type.isValid() && allocation->type_vec_size.isValid()
1472            && allocation->size.isValid() && "Allocation information not available");
1473 
1474     // Allocate a buffer to copy data into
1475     const unsigned int size = *allocation->size.get();
1476     std::shared_ptr<uint8_t> buffer(new uint8_t[size]);
1477     if (!buffer)
1478     {
1479         if (log)
1480             log->Printf("RenderScriptRuntime::GetAllocationData - Couldn't allocate a %u byte buffer", size);
1481         return nullptr;
1482     }
1483 
1484     // Read the inferior memory
1485     Error error;
1486     lldb::addr_t data_ptr = *allocation->data_ptr.get();
1487     GetProcess()->ReadMemory(data_ptr, buffer.get(), size, error);
1488     if (error.Fail())
1489     {
1490         if (log)
1491             log->Printf("RenderScriptRuntime::GetAllocationData - '%s' Couldn't read %u bytes of allocation data from 0x%" PRIx64,
1492                         error.AsCString(), size, data_ptr);
1493         return nullptr;
1494     }
1495 
1496     return buffer;
1497 }
1498 
1499 // Function copies data from a binary file into an allocation.
1500 // There is a header at the start of the file, FileHeader, before the data content itself.
1501 // Information from this header is used to display warnings to the user about incompatabilities
1502 bool
1503 RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr)
1504 {
1505     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1506 
1507     // Find allocation with the given id
1508     AllocationDetails* alloc = FindAllocByID(strm, alloc_id);
1509     if (!alloc)
1510         return false;
1511 
1512     if (log)
1513         log->Printf("RenderScriptRuntime::LoadAllocation - Found allocation 0x%" PRIx64, *alloc->address.get());
1514 
1515     // JIT all the allocation details
1516     if (!alloc->data_ptr.isValid() || !alloc->type.isValid() || !alloc->type_vec_size.isValid() || !alloc->size.isValid())
1517     {
1518         if (log)
1519             log->Printf("RenderScriptRuntime::LoadAllocation - Allocation details not calculated yet, jitting info");
1520 
1521         if (!RefreshAllocation(alloc, frame_ptr))
1522         {
1523             if (log)
1524                 log->Printf("RenderScriptRuntime::LoadAllocation - Couldn't JIT allocation details");
1525             return nullptr;
1526         }
1527     }
1528 
1529     assert(alloc->data_ptr.isValid() && alloc->type.isValid() && alloc->type_vec_size.isValid() && alloc->size.isValid()
1530            && "Allocation information not available");
1531 
1532     // Check we can read from file
1533     FileSpec file(filename, true);
1534     if (!file.Exists())
1535     {
1536         strm.Printf("Error: File %s does not exist", filename);
1537         strm.EOL();
1538         return false;
1539     }
1540 
1541     if (!file.Readable())
1542     {
1543         strm.Printf("Error: File %s does not have readable permissions", filename);
1544         strm.EOL();
1545         return false;
1546     }
1547 
1548     // Read file into data buffer
1549     DataBufferSP data_sp(file.ReadFileContents());
1550 
1551     // Cast start of buffer to FileHeader and use pointer to read metadata
1552     void* file_buffer = data_sp->GetBytes();
1553     const AllocationDetails::FileHeader* head = static_cast<AllocationDetails::FileHeader*>(file_buffer);
1554 
1555     // Advance buffer past header
1556     file_buffer = static_cast<uint8_t*>(file_buffer) + head->hdr_size;
1557 
1558     if (log)
1559         log->Printf("RenderScriptRuntime::LoadAllocation - header type %u, element size %u",
1560                     head->type, head->element_size);
1561 
1562     // Check if the target allocation and file both have the same number of bytes for an Element
1563     const unsigned int elem_size = GetElementSize(alloc);
1564     if (elem_size != head->element_size)
1565     {
1566         strm.Printf("Warning: Mismatched Element sizes - file %u bytes, allocation %u bytes",
1567                     head->element_size, elem_size);
1568         strm.EOL();
1569     }
1570 
1571     // Check if the target allocation and file both have the same integral type
1572     const unsigned int type = static_cast<unsigned int>(*alloc->type.get());
1573     if (type != head->type)
1574     {
1575         const char* file_type_cstr = AllocationDetails::RsDataTypeToString[head->type][0];
1576         const char* alloc_type_cstr = AllocationDetails::RsDataTypeToString[type][0];
1577 
1578         strm.Printf("Warning: Mismatched Types - file '%s' type, allocation '%s' type",
1579                     file_type_cstr, alloc_type_cstr);
1580         strm.EOL();
1581     }
1582 
1583     // Calculate size of allocation data in file
1584     size_t length = data_sp->GetByteSize() - head->hdr_size;
1585 
1586     // Check if the target allocation and file both have the same total data size.
1587     const unsigned int alloc_size = *alloc->size.get();
1588     if (alloc_size != length)
1589     {
1590         strm.Printf("Warning: Mismatched allocation sizes - file 0x%" PRIx64 " bytes, allocation 0x%x bytes",
1591                     length, alloc_size);
1592         strm.EOL();
1593         length = alloc_size < length ? alloc_size : length; // Set length to copy to minimum
1594     }
1595 
1596     // Copy file data from our buffer into the target allocation.
1597     lldb::addr_t alloc_data = *alloc->data_ptr.get();
1598     Error error;
1599     size_t bytes_written = GetProcess()->WriteMemory(alloc_data, file_buffer, length, error);
1600     if (!error.Success() || bytes_written != length)
1601     {
1602         strm.Printf("Error: Couldn't write data to allocation %s", error.AsCString());
1603         strm.EOL();
1604         return false;
1605     }
1606 
1607     strm.Printf("Contents of file '%s' read into allocation %u", filename, alloc->id);
1608     strm.EOL();
1609 
1610     return true;
1611 }
1612 
1613 // Function copies allocation contents into a binary file.
1614 // This file can then be loaded later into a different allocation.
1615 // There is a header, FileHeader, before the allocation data containing meta-data.
1616 bool
1617 RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr)
1618 {
1619     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1620 
1621     // Find allocation with the given id
1622     AllocationDetails* alloc = FindAllocByID(strm, alloc_id);
1623     if (!alloc)
1624         return false;
1625 
1626     if (log)
1627         log->Printf("RenderScriptRuntime::SaveAllocation - Found allocation 0x%" PRIx64, *alloc->address.get());
1628 
1629      // JIT all the allocation details
1630     if (!alloc->data_ptr.isValid() || !alloc->type.isValid() || !alloc->type_vec_size.isValid()
1631         || !alloc->type_kind.isValid() || !alloc->dimension.isValid())
1632     {
1633         if (log)
1634             log->Printf("RenderScriptRuntime::SaveAllocation - Allocation details not calculated yet, jitting info");
1635 
1636         if (!RefreshAllocation(alloc, frame_ptr))
1637         {
1638             if (log)
1639                 log->Printf("RenderScriptRuntime::SaveAllocation - Couldn't JIT allocation details");
1640             return nullptr;
1641         }
1642     }
1643 
1644     assert(alloc->data_ptr.isValid() && alloc->type.isValid() && alloc->type_vec_size.isValid() && alloc->type_kind.isValid()
1645            && alloc->dimension.isValid() && "Allocation information not available");
1646 
1647     // Check we can create writable file
1648     FileSpec file_spec(filename, true);
1649     File file(file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate | File::eOpenOptionTruncate);
1650     if (!file)
1651     {
1652         strm.Printf("Error: Failed to open '%s' for writing", filename);
1653         strm.EOL();
1654         return false;
1655     }
1656 
1657     // Read allocation into buffer of heap memory
1658     const std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr);
1659     if (!buffer)
1660     {
1661         strm.Printf("Error: Couldn't read allocation data into buffer");
1662         strm.EOL();
1663         return false;
1664     }
1665 
1666     // Create the file header
1667     AllocationDetails::FileHeader head;
1668     head.ident[0] = 'R'; head.ident[1] = 'S'; head.ident[2] = 'A'; head.ident[3] = 'D';
1669     head.hdr_size = static_cast<uint16_t>(sizeof(AllocationDetails::FileHeader));
1670     head.type = static_cast<uint16_t>(*alloc->type.get());
1671     head.kind = static_cast<uint32_t>(*alloc->type_kind.get());
1672     head.dims[0] = static_cast<uint32_t>(alloc->dimension.get()->dim_1);
1673     head.dims[1] = static_cast<uint32_t>(alloc->dimension.get()->dim_2);
1674     head.dims[2] = static_cast<uint32_t>(alloc->dimension.get()->dim_3);
1675     head.element_size = static_cast<uint32_t>(GetElementSize(alloc));
1676 
1677     // Write the file header
1678     size_t num_bytes = sizeof(AllocationDetails::FileHeader);
1679     Error err = file.Write(static_cast<const void*>(&head), num_bytes);
1680     if (!err.Success())
1681     {
1682         strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), filename);
1683         strm.EOL();
1684         return false;
1685     }
1686 
1687     // Write allocation data to file
1688     num_bytes = static_cast<size_t>(*alloc->size.get());
1689     if (log)
1690         log->Printf("RenderScriptRuntime::SaveAllocation - Writing %" PRIx64  "bytes from %p", num_bytes, buffer.get());
1691 
1692     err = file.Write(buffer.get(), num_bytes);
1693     if (!err.Success())
1694     {
1695         strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), filename);
1696         strm.EOL();
1697         return false;
1698     }
1699 
1700     strm.Printf("Allocation written to file '%s'", filename);
1701     strm.EOL();
1702     return true;
1703 }
1704 
1705 bool
1706 RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
1707 {
1708     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1709 
1710     if (module_sp)
1711     {
1712         for (const auto &rs_module : m_rsmodules)
1713         {
1714             if (rs_module->m_module == module_sp)
1715             {
1716                 // Check if the user has enabled automatically breaking on
1717                 // all RS kernels.
1718                 if (m_breakAllKernels)
1719                     BreakOnModuleKernels(rs_module);
1720 
1721                 return false;
1722             }
1723         }
1724         bool module_loaded = false;
1725         switch (GetModuleKind(module_sp))
1726         {
1727             case eModuleKindKernelObj:
1728             {
1729                 RSModuleDescriptorSP module_desc;
1730                 module_desc.reset(new RSModuleDescriptor(module_sp));
1731                 if (module_desc->ParseRSInfo())
1732                 {
1733                     m_rsmodules.push_back(module_desc);
1734                     module_loaded = true;
1735                 }
1736                 if (module_loaded)
1737                 {
1738                     FixupScriptDetails(module_desc);
1739                 }
1740                 break;
1741             }
1742             case eModuleKindDriver:
1743             {
1744                 if (!m_libRSDriver)
1745                 {
1746                     m_libRSDriver = module_sp;
1747                     LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver);
1748                 }
1749                 break;
1750             }
1751             case eModuleKindImpl:
1752             {
1753                 m_libRSCpuRef = module_sp;
1754                 break;
1755             }
1756             case eModuleKindLibRS:
1757             {
1758                 if (!m_libRS)
1759                 {
1760                     m_libRS = module_sp;
1761                     static ConstString gDbgPresentStr("gDebuggerPresent");
1762                     const Symbol* debug_present = m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData);
1763                     if (debug_present)
1764                     {
1765                         Error error;
1766                         uint32_t flag = 0x00000001U;
1767                         Target &target = GetProcess()->GetTarget();
1768                         addr_t addr = debug_present->GetLoadAddress(&target);
1769                         GetProcess()->WriteMemory(addr, &flag, sizeof(flag), error);
1770                         if(error.Success())
1771                         {
1772                             if (log)
1773                                 log->Printf ("RenderScriptRuntime::LoadModule - Debugger present flag set on debugee");
1774 
1775                             m_debuggerPresentFlagged = true;
1776                         }
1777                         else if (log)
1778                         {
1779                             log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags '%s' ", error.AsCString());
1780                         }
1781                     }
1782                     else if (log)
1783                     {
1784                         log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags - symbol not found");
1785                     }
1786                 }
1787                 break;
1788             }
1789             default:
1790                 break;
1791         }
1792         if (module_loaded)
1793             Update();
1794         return module_loaded;
1795     }
1796     return false;
1797 }
1798 
1799 void
1800 RenderScriptRuntime::Update()
1801 {
1802     if (m_rsmodules.size() > 0)
1803     {
1804         if (!m_initiated)
1805         {
1806             Initiate();
1807         }
1808     }
1809 }
1810 
1811 
1812 // The maximum line length of an .rs.info packet
1813 #define MAXLINE 500
1814 
1815 // The .rs.info symbol in renderscript modules contains a string which needs to be parsed.
1816 // The string is basic and is parsed on a line by line basis.
1817 bool
1818 RSModuleDescriptor::ParseRSInfo()
1819 {
1820     const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
1821     if (info_sym)
1822     {
1823         const addr_t addr = info_sym->GetAddressRef().GetFileAddress();
1824         const addr_t size = info_sym->GetByteSize();
1825         const FileSpec fs = m_module->GetFileSpec();
1826 
1827         DataBufferSP buffer = fs.ReadFileContents(addr, size);
1828 
1829         if (!buffer)
1830             return false;
1831 
1832         std::string info((const char *)buffer->GetBytes());
1833 
1834         std::vector<std::string> info_lines;
1835         size_t lpos = info.find('\n');
1836         while (lpos != std::string::npos)
1837         {
1838             info_lines.push_back(info.substr(0, lpos));
1839             info = info.substr(lpos + 1);
1840             lpos = info.find('\n');
1841         }
1842         size_t offset = 0;
1843         while (offset < info_lines.size())
1844         {
1845             std::string line = info_lines[offset];
1846             // Parse directives
1847             uint32_t numDefns = 0;
1848             if (sscanf(line.c_str(), "exportVarCount: %u", &numDefns) == 1)
1849             {
1850                 while (numDefns--)
1851                     m_globals.push_back(RSGlobalDescriptor(this, info_lines[++offset].c_str()));
1852             }
1853             else if (sscanf(line.c_str(), "exportFuncCount: %u", &numDefns) == 1)
1854             {
1855             }
1856             else if (sscanf(line.c_str(), "exportForEachCount: %u", &numDefns) == 1)
1857             {
1858                 char name[MAXLINE];
1859                 while (numDefns--)
1860                 {
1861                     uint32_t slot = 0;
1862                     name[0] = '\0';
1863                     if (sscanf(info_lines[++offset].c_str(), "%u - %s", &slot, &name[0]) == 2)
1864                     {
1865                         m_kernels.push_back(RSKernelDescriptor(this, name, slot));
1866                     }
1867                 }
1868             }
1869             else if (sscanf(line.c_str(), "pragmaCount: %u", &numDefns) == 1)
1870             {
1871                 char name[MAXLINE];
1872                 char value[MAXLINE];
1873                 while (numDefns--)
1874                 {
1875                     name[0] = '\0';
1876                     value[0] = '\0';
1877                     if (sscanf(info_lines[++offset].c_str(), "%s - %s", &name[0], &value[0]) != 0
1878                         && (name[0] != '\0'))
1879                     {
1880                         m_pragmas[std::string(name)] = value;
1881                     }
1882                 }
1883             }
1884             else if (sscanf(line.c_str(), "objectSlotCount: %u", &numDefns) == 1)
1885             {
1886             }
1887 
1888             offset++;
1889         }
1890         return m_kernels.size() > 0;
1891     }
1892     return false;
1893 }
1894 
1895 bool
1896 RenderScriptRuntime::ProbeModules(const ModuleList module_list)
1897 {
1898     bool rs_found = false;
1899     size_t num_modules = module_list.GetSize();
1900     for (size_t i = 0; i < num_modules; i++)
1901     {
1902         auto module = module_list.GetModuleAtIndex(i);
1903         rs_found |= LoadModule(module);
1904     }
1905     return rs_found;
1906 }
1907 
1908 void
1909 RenderScriptRuntime::Status(Stream &strm) const
1910 {
1911     if (m_libRS)
1912     {
1913         strm.Printf("Runtime Library discovered.");
1914         strm.EOL();
1915     }
1916     if (m_libRSDriver)
1917     {
1918         strm.Printf("Runtime Driver discovered.");
1919         strm.EOL();
1920     }
1921     if (m_libRSCpuRef)
1922     {
1923         strm.Printf("CPU Reference Implementation discovered.");
1924         strm.EOL();
1925     }
1926 
1927     if (m_runtimeHooks.size())
1928     {
1929         strm.Printf("Runtime functions hooked:");
1930         strm.EOL();
1931         for (auto b : m_runtimeHooks)
1932         {
1933             strm.Indent(b.second->defn->name);
1934             strm.EOL();
1935         }
1936         strm.EOL();
1937     }
1938     else
1939     {
1940         strm.Printf("Runtime is not hooked.");
1941         strm.EOL();
1942     }
1943 }
1944 
1945 void
1946 RenderScriptRuntime::DumpContexts(Stream &strm) const
1947 {
1948     strm.Printf("Inferred RenderScript Contexts:");
1949     strm.EOL();
1950     strm.IndentMore();
1951 
1952     std::map<addr_t, uint64_t> contextReferences;
1953 
1954     // Iterate over all of the currently discovered scripts.
1955     // Note: We cant push or pop from m_scripts inside this loop or it may invalidate script.
1956     for (const auto & script : m_scripts)
1957     {
1958         if (!script->context.isValid())
1959             continue;
1960         lldb::addr_t context = *script->context;
1961 
1962         if (contextReferences.find(context) != contextReferences.end())
1963         {
1964             contextReferences[context]++;
1965         }
1966         else
1967         {
1968             contextReferences[context] = 1;
1969         }
1970     }
1971 
1972     for (const auto& cRef : contextReferences)
1973     {
1974         strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances", cRef.first, cRef.second);
1975         strm.EOL();
1976     }
1977     strm.IndentLess();
1978 }
1979 
1980 void
1981 RenderScriptRuntime::DumpKernels(Stream &strm) const
1982 {
1983     strm.Printf("RenderScript Kernels:");
1984     strm.EOL();
1985     strm.IndentMore();
1986     for (const auto &module : m_rsmodules)
1987     {
1988         strm.Printf("Resource '%s':",module->m_resname.c_str());
1989         strm.EOL();
1990         for (const auto &kernel : module->m_kernels)
1991         {
1992             strm.Indent(kernel.m_name.AsCString());
1993             strm.EOL();
1994         }
1995     }
1996     strm.IndentLess();
1997 }
1998 
1999 RenderScriptRuntime::AllocationDetails*
2000 RenderScriptRuntime::FindAllocByID(Stream &strm, const uint32_t alloc_id)
2001 {
2002     AllocationDetails* alloc = nullptr;
2003 
2004     // See if we can find allocation using id as an index;
2005     if (alloc_id <= m_allocations.size() && alloc_id != 0
2006         && m_allocations[alloc_id-1]->id == alloc_id)
2007     {
2008         alloc = m_allocations[alloc_id-1].get();
2009         return alloc;
2010     }
2011 
2012     // Fallback to searching
2013     for (const auto & a : m_allocations)
2014     {
2015        if (a->id == alloc_id)
2016        {
2017            alloc = a.get();
2018            break;
2019        }
2020     }
2021 
2022     if (alloc == nullptr)
2023     {
2024         strm.Printf("Error: Couldn't find allocation with id matching %u", alloc_id);
2025         strm.EOL();
2026     }
2027 
2028     return alloc;
2029 }
2030 
2031 // Prints the contents of an allocation to the output stream, which may be a file
2032 bool
2033 RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame* frame_ptr, const uint32_t id)
2034 {
2035     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
2036 
2037     // Check we can find the desired allocation
2038     AllocationDetails* alloc = FindAllocByID(strm, id);
2039     if (!alloc)
2040         return false; // FindAllocByID() will print error message for us here
2041 
2042     if (log)
2043         log->Printf("RenderScriptRuntime::DumpAllocation - Found allocation 0x%" PRIx64, *alloc->address.get());
2044 
2045     // Check we have information about the allocation, if not calculate it
2046     if (!alloc->data_ptr.isValid() || !alloc->type.isValid() ||
2047         !alloc->type_vec_size.isValid() || !alloc->dimension.isValid())
2048     {
2049         if (log)
2050             log->Printf("RenderScriptRuntime::DumpAllocation - Allocation details not calculated yet, jitting info");
2051 
2052         // JIT all the allocation information
2053         if (!RefreshAllocation(alloc, frame_ptr))
2054         {
2055             strm.Printf("Error: Couldn't JIT allocation details");
2056             strm.EOL();
2057             return false;
2058         }
2059     }
2060 
2061     // Establish format and size of each data element
2062     const unsigned int vec_size = *alloc->type_vec_size.get();
2063     const AllocationDetails::DataType type = *alloc->type.get();
2064 
2065     assert(type >= AllocationDetails::RS_TYPE_NONE && type <= AllocationDetails::RS_TYPE_BOOLEAN
2066                                                    && "Invalid allocation type");
2067 
2068     lldb::Format format = vec_size == 1 ? static_cast<lldb::Format>(AllocationDetails::RSTypeToFormat[type][eFormatSingle])
2069                                         : static_cast<lldb::Format>(AllocationDetails::RSTypeToFormat[type][eFormatVector]);
2070 
2071     const unsigned int data_size = vec_size * AllocationDetails::RSTypeToFormat[type][eElementSize];
2072     // Renderscript pads vector 3 elements to vector 4
2073     const unsigned int elem_padding = vec_size == 3 ? AllocationDetails::RSTypeToFormat[type][eElementSize] : 0;
2074 
2075     if (log)
2076         log->Printf("RenderScriptRuntime::DumpAllocation - Element size %u bytes, element padding %u bytes",
2077                     data_size, elem_padding);
2078 
2079     // Allocate a buffer to copy data into
2080     std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr);
2081     if (!buffer)
2082     {
2083         strm.Printf("Error: Couldn't allocate a read allocation data into memory");
2084         strm.EOL();
2085         return false;
2086     }
2087 
2088     // Calculate stride between rows as there may be padding at end of rows since
2089     // allocated memory is 16-byte aligned
2090     if (!alloc->stride.isValid())
2091     {
2092         if (alloc->dimension.get()->dim_2 == 0) // We only have one dimension
2093             alloc->stride = 0;
2094         else if (!JITAllocationStride(alloc, frame_ptr))
2095         {
2096             strm.Printf("Error: Couldn't calculate allocation row stride");
2097             strm.EOL();
2098             return false;
2099         }
2100     }
2101     const unsigned int stride = *alloc->stride.get();
2102     const unsigned int size = *alloc->size.get(); //size of last element
2103 
2104     if (log)
2105         log->Printf("RenderScriptRuntime::DumpAllocation - stride %u bytes, size %u bytes", stride, size);
2106 
2107     // Find dimensions used to index loops, so need to be non-zero
2108     unsigned int dim_x = alloc->dimension.get()->dim_1;
2109     dim_x = dim_x == 0 ? 1 : dim_x;
2110 
2111     unsigned int dim_y = alloc->dimension.get()->dim_2;
2112     dim_y = dim_y == 0 ? 1 : dim_y;
2113 
2114     unsigned int dim_z = alloc->dimension.get()->dim_3;
2115     dim_z = dim_z == 0 ? 1 : dim_z;
2116 
2117     // Use data extractor to format output
2118     const uint32_t archByteSize = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
2119     DataExtractor alloc_data(buffer.get(), size, GetProcess()->GetByteOrder(), archByteSize);
2120 
2121     unsigned int offset = 0;   // Offset in buffer to next element to be printed
2122     unsigned int prev_row = 0; // Offset to the start of the previous row
2123 
2124     // Iterate over allocation dimensions, printing results to user
2125     strm.Printf("Data (X, Y, Z):");
2126     for (unsigned int z = 0; z < dim_z; ++z)
2127     {
2128         for (unsigned int y = 0; y < dim_y; ++y)
2129         {
2130             // Use stride to index start of next row.
2131             if (!(y==0 && z==0))
2132                 offset = prev_row + stride;
2133             prev_row = offset;
2134 
2135             // Print each element in the row individually
2136             for (unsigned int x = 0; x < dim_x; ++x)
2137             {
2138                 strm.Printf("\n(%u, %u, %u) = ", x, y, z);
2139                 alloc_data.Dump(&strm, offset, format, data_size, 1, 1, LLDB_INVALID_ADDRESS, 0, 0);
2140                 offset += data_size + elem_padding;
2141             }
2142         }
2143     }
2144     strm.EOL();
2145 
2146     return true;
2147 }
2148 
2149 // Prints infomation regarding all the currently loaded allocations.
2150 // These details are gathered by jitting the runtime, which has as latency.
2151 void
2152 RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame* frame_ptr, bool recompute)
2153 {
2154     strm.Printf("RenderScript Allocations:");
2155     strm.EOL();
2156     strm.IndentMore();
2157 
2158     for (auto &alloc : m_allocations)
2159     {
2160         // JIT the allocation info if we haven't done it, or the user forces us to.
2161         bool do_refresh = !alloc->data_ptr.isValid() || recompute;
2162 
2163         // JIT current allocation information
2164         if (do_refresh && !RefreshAllocation(alloc.get(), frame_ptr))
2165         {
2166             strm.Printf("Error: Couldn't evaluate details for allocation %u\n", alloc->id);
2167             continue;
2168         }
2169 
2170         strm.Printf("%u:\n",alloc->id);
2171         strm.IndentMore();
2172 
2173         strm.Indent("Context: ");
2174         if (!alloc->context.isValid())
2175             strm.Printf("unknown\n");
2176         else
2177             strm.Printf("0x%" PRIx64 "\n", *alloc->context.get());
2178 
2179         strm.Indent("Address: ");
2180         if (!alloc->address.isValid())
2181             strm.Printf("unknown\n");
2182         else
2183             strm.Printf("0x%" PRIx64 "\n", *alloc->address.get());
2184 
2185         strm.Indent("Data pointer: ");
2186         if (!alloc->data_ptr.isValid())
2187             strm.Printf("unknown\n");
2188         else
2189             strm.Printf("0x%" PRIx64 "\n", *alloc->data_ptr.get());
2190 
2191         strm.Indent("Dimensions: ");
2192         if (!alloc->dimension.isValid())
2193             strm.Printf("unknown\n");
2194         else
2195             strm.Printf("(%d, %d, %d)\n", alloc->dimension.get()->dim_1,
2196                                           alloc->dimension.get()->dim_2,
2197                                           alloc->dimension.get()->dim_3);
2198 
2199         strm.Indent("Data Type: ");
2200         if (!alloc->type.isValid() || !alloc->type_vec_size.isValid())
2201             strm.Printf("unknown\n");
2202         else
2203         {
2204             const int vector_size = *alloc->type_vec_size.get();
2205             const AllocationDetails::DataType type = *alloc->type.get();
2206 
2207             if (vector_size > 4 || vector_size < 1 ||
2208                 type < AllocationDetails::RS_TYPE_NONE || type > AllocationDetails::RS_TYPE_BOOLEAN)
2209                 strm.Printf("invalid type\n");
2210             else
2211                 strm.Printf("%s\n", AllocationDetails::RsDataTypeToString[static_cast<unsigned int>(type)][vector_size-1]);
2212         }
2213 
2214         strm.Indent("Data Kind: ");
2215         if (!alloc->type_kind.isValid())
2216             strm.Printf("unknown\n");
2217         else
2218         {
2219             const AllocationDetails::DataKind kind = *alloc->type_kind.get();
2220             if (kind < AllocationDetails::RS_KIND_USER || kind > AllocationDetails::RS_KIND_PIXEL_YUV)
2221                 strm.Printf("invalid kind\n");
2222             else
2223                 strm.Printf("%s\n", AllocationDetails::RsDataKindToString[static_cast<unsigned int>(kind)]);
2224         }
2225 
2226         strm.EOL();
2227         strm.IndentLess();
2228     }
2229     strm.IndentLess();
2230 }
2231 
2232 // Set breakpoints on every kernel found in RS module
2233 void
2234 RenderScriptRuntime::BreakOnModuleKernels(const RSModuleDescriptorSP rsmodule_sp)
2235 {
2236     for (const auto &kernel : rsmodule_sp->m_kernels)
2237     {
2238         // Don't set breakpoint on 'root' kernel
2239         if (strcmp(kernel.m_name.AsCString(), "root") == 0)
2240             continue;
2241 
2242         CreateKernelBreakpoint(kernel.m_name);
2243     }
2244 }
2245 
2246 // Method is internally called by the 'kernel breakpoint all' command to
2247 // enable or disable breaking on all kernels.
2248 //
2249 // When do_break is true we want to enable this functionality.
2250 // When do_break is false we want to disable it.
2251 void
2252 RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target)
2253 {
2254     Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
2255 
2256     InitSearchFilter(target);
2257 
2258     // Set breakpoints on all the kernels
2259     if (do_break && !m_breakAllKernels)
2260     {
2261         m_breakAllKernels = true;
2262 
2263         for (const auto &module : m_rsmodules)
2264             BreakOnModuleKernels(module);
2265 
2266         if (log)
2267             log->Printf("RenderScriptRuntime::SetBreakAllKernels(True)"
2268                         "- breakpoints set on all currently loaded kernels");
2269     }
2270     else if (!do_break && m_breakAllKernels) // Breakpoints won't be set on any new kernels.
2271     {
2272         m_breakAllKernels = false;
2273 
2274         if (log)
2275             log->Printf("RenderScriptRuntime::SetBreakAllKernels(False) - breakpoints no longer automatically set");
2276     }
2277 }
2278 
2279 // Given the name of a kernel this function creates a breakpoint using our
2280 // own breakpoint resolver, and returns the Breakpoint shared pointer.
2281 BreakpointSP
2282 RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name)
2283 {
2284     Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
2285 
2286     if (!m_filtersp)
2287     {
2288         if (log)
2289             log->Printf("RenderScriptRuntime::CreateKernelBreakpoint - Error: No breakpoint search filter set");
2290         return nullptr;
2291     }
2292 
2293     BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name));
2294     BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(m_filtersp, resolver_sp, false, false, false);
2295 
2296     // Give RS breakpoints a specific name, so the user can manipulate them as a group.
2297     Error err;
2298     if (!bp->AddName("RenderScriptKernel", err) && log)
2299         log->Printf("RenderScriptRuntime::CreateKernelBreakpoint: Error setting break name, %s", err.AsCString());
2300 
2301     return bp;
2302 }
2303 
2304 void
2305 RenderScriptRuntime::AttemptBreakpointAtKernelName(Stream &strm, const char* name, Error& error, TargetSP target)
2306 {
2307     if (!name)
2308     {
2309         error.SetErrorString("invalid kernel name");
2310         return;
2311     }
2312 
2313     InitSearchFilter(target);
2314 
2315     ConstString kernel_name(name);
2316     BreakpointSP bp = CreateKernelBreakpoint(kernel_name);
2317     if (bp)
2318         bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false);
2319 
2320     return;
2321 }
2322 
2323 void
2324 RenderScriptRuntime::DumpModules(Stream &strm) const
2325 {
2326     strm.Printf("RenderScript Modules:");
2327     strm.EOL();
2328     strm.IndentMore();
2329     for (const auto &module : m_rsmodules)
2330     {
2331         module->Dump(strm);
2332     }
2333     strm.IndentLess();
2334 }
2335 
2336 RenderScriptRuntime::ScriptDetails*
2337 RenderScriptRuntime::LookUpScript(addr_t address, bool create)
2338 {
2339     for (const auto & s : m_scripts)
2340     {
2341         if (s->script.isValid())
2342             if (*s->script == address)
2343                 return s.get();
2344     }
2345     if (create)
2346     {
2347         std::unique_ptr<ScriptDetails> s(new ScriptDetails);
2348         s->script = address;
2349         m_scripts.push_back(std::move(s));
2350         return m_scripts.back().get();
2351     }
2352     return nullptr;
2353 }
2354 
2355 RenderScriptRuntime::AllocationDetails*
2356 RenderScriptRuntime::LookUpAllocation(addr_t address, bool create)
2357 {
2358     for (const auto & a : m_allocations)
2359     {
2360         if (a->address.isValid())
2361             if (*a->address == address)
2362                 return a.get();
2363     }
2364     if (create)
2365     {
2366         std::unique_ptr<AllocationDetails> a(new AllocationDetails);
2367         a->address = address;
2368         m_allocations.push_back(std::move(a));
2369         return m_allocations.back().get();
2370     }
2371     return nullptr;
2372 }
2373 
2374 void
2375 RSModuleDescriptor::Dump(Stream &strm) const
2376 {
2377     strm.Indent();
2378     m_module->GetFileSpec().Dump(&strm);
2379     if(m_module->GetNumCompileUnits())
2380     {
2381         strm.Indent("Debug info loaded.");
2382     }
2383     else
2384     {
2385         strm.Indent("Debug info does not exist.");
2386     }
2387     strm.EOL();
2388     strm.IndentMore();
2389     strm.Indent();
2390     strm.Printf("Globals: %" PRIu64, static_cast<uint64_t>(m_globals.size()));
2391     strm.EOL();
2392     strm.IndentMore();
2393     for (const auto &global : m_globals)
2394     {
2395         global.Dump(strm);
2396     }
2397     strm.IndentLess();
2398     strm.Indent();
2399     strm.Printf("Kernels: %" PRIu64, static_cast<uint64_t>(m_kernels.size()));
2400     strm.EOL();
2401     strm.IndentMore();
2402     for (const auto &kernel : m_kernels)
2403     {
2404         kernel.Dump(strm);
2405     }
2406     strm.Printf("Pragmas: %"  PRIu64 , static_cast<uint64_t>(m_pragmas.size()));
2407     strm.EOL();
2408     strm.IndentMore();
2409     for (const auto &key_val : m_pragmas)
2410     {
2411         strm.Printf("%s: %s", key_val.first.c_str(), key_val.second.c_str());
2412         strm.EOL();
2413     }
2414     strm.IndentLess(4);
2415 }
2416 
2417 void
2418 RSGlobalDescriptor::Dump(Stream &strm) const
2419 {
2420     strm.Indent(m_name.AsCString());
2421     VariableList var_list;
2422     m_module->m_module->FindGlobalVariables(m_name, nullptr, true, 1U, var_list);
2423     if (var_list.GetSize() == 1)
2424     {
2425         auto var = var_list.GetVariableAtIndex(0);
2426         auto type = var->GetType();
2427         if(type)
2428         {
2429             strm.Printf(" - ");
2430             type->DumpTypeName(&strm);
2431         }
2432         else
2433         {
2434             strm.Printf(" - Unknown Type");
2435         }
2436     }
2437     else
2438     {
2439         strm.Printf(" - variable identified, but not found in binary");
2440         const Symbol* s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData);
2441         if (s)
2442         {
2443             strm.Printf(" (symbol exists) ");
2444         }
2445     }
2446 
2447     strm.EOL();
2448 }
2449 
2450 void
2451 RSKernelDescriptor::Dump(Stream &strm) const
2452 {
2453     strm.Indent(m_name.AsCString());
2454     strm.EOL();
2455 }
2456 
2457 class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed
2458 {
2459   private:
2460   public:
2461     CommandObjectRenderScriptRuntimeModuleProbe(CommandInterpreter &interpreter)
2462         : CommandObjectParsed(interpreter, "renderscript module probe",
2463                               "Initiates a Probe of all loaded modules for kernels and other renderscript objects.",
2464                               "renderscript module probe",
2465                               eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBeLaunched)
2466     {
2467     }
2468 
2469     ~CommandObjectRenderScriptRuntimeModuleProbe() {}
2470 
2471     bool
2472     DoExecute(Args &command, CommandReturnObject &result)
2473     {
2474         const size_t argc = command.GetArgumentCount();
2475         if (argc == 0)
2476         {
2477             Target *target = m_exe_ctx.GetTargetPtr();
2478             RenderScriptRuntime *runtime =
2479                 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
2480             auto module_list = target->GetImages();
2481             bool new_rs_details = runtime->ProbeModules(module_list);
2482             if (new_rs_details)
2483             {
2484                 result.AppendMessage("New renderscript modules added to runtime model.");
2485             }
2486             result.SetStatus(eReturnStatusSuccessFinishResult);
2487             return true;
2488         }
2489 
2490         result.AppendErrorWithFormat("'%s' takes no arguments", m_cmd_name.c_str());
2491         result.SetStatus(eReturnStatusFailed);
2492         return false;
2493     }
2494 };
2495 
2496 class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed
2497 {
2498   private:
2499   public:
2500     CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter)
2501         : CommandObjectParsed(interpreter, "renderscript module dump",
2502                               "Dumps renderscript specific information for all modules.", "renderscript module dump",
2503                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
2504     {
2505     }
2506 
2507     ~CommandObjectRenderScriptRuntimeModuleDump() {}
2508 
2509     bool
2510     DoExecute(Args &command, CommandReturnObject &result)
2511     {
2512         RenderScriptRuntime *runtime =
2513             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
2514         runtime->DumpModules(result.GetOutputStream());
2515         result.SetStatus(eReturnStatusSuccessFinishResult);
2516         return true;
2517     }
2518 };
2519 
2520 class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword
2521 {
2522   private:
2523   public:
2524     CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter)
2525         : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with renderscript modules.",
2526                                  NULL)
2527     {
2528         LoadSubCommand("probe", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleProbe(interpreter)));
2529         LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter)));
2530     }
2531 
2532     ~CommandObjectRenderScriptRuntimeModule() {}
2533 };
2534 
2535 class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed
2536 {
2537   private:
2538   public:
2539     CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter)
2540         : CommandObjectParsed(interpreter, "renderscript kernel list",
2541                               "Lists renderscript kernel names and associated script resources.", "renderscript kernel list",
2542                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
2543     {
2544     }
2545 
2546     ~CommandObjectRenderScriptRuntimeKernelList() {}
2547 
2548     bool
2549     DoExecute(Args &command, CommandReturnObject &result)
2550     {
2551         RenderScriptRuntime *runtime =
2552             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
2553         runtime->DumpKernels(result.GetOutputStream());
2554         result.SetStatus(eReturnStatusSuccessFinishResult);
2555         return true;
2556     }
2557 };
2558 
2559 class CommandObjectRenderScriptRuntimeKernelBreakpointSet : public CommandObjectParsed
2560 {
2561   private:
2562   public:
2563     CommandObjectRenderScriptRuntimeKernelBreakpointSet(CommandInterpreter &interpreter)
2564         : CommandObjectParsed(interpreter, "renderscript kernel breakpoint set",
2565                               "Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint set <kernel_name>",
2566                               eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
2567     {
2568     }
2569 
2570     ~CommandObjectRenderScriptRuntimeKernelBreakpointSet() {}
2571 
2572     bool
2573     DoExecute(Args &command, CommandReturnObject &result)
2574     {
2575         const size_t argc = command.GetArgumentCount();
2576         if (argc == 1)
2577         {
2578             RenderScriptRuntime *runtime =
2579                 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
2580 
2581             Error error;
2582             runtime->AttemptBreakpointAtKernelName(result.GetOutputStream(), command.GetArgumentAtIndex(0),
2583                                                    error, m_exe_ctx.GetTargetSP());
2584 
2585             if (error.Success())
2586             {
2587                 result.AppendMessage("Breakpoint(s) created");
2588                 result.SetStatus(eReturnStatusSuccessFinishResult);
2589                 return true;
2590             }
2591             result.SetStatus(eReturnStatusFailed);
2592             result.AppendErrorWithFormat("Error: %s", error.AsCString());
2593             return false;
2594         }
2595 
2596         result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name", m_cmd_name.c_str());
2597         result.SetStatus(eReturnStatusFailed);
2598         return false;
2599     }
2600 };
2601 
2602 class CommandObjectRenderScriptRuntimeKernelBreakpointAll : public CommandObjectParsed
2603 {
2604   private:
2605   public:
2606     CommandObjectRenderScriptRuntimeKernelBreakpointAll(CommandInterpreter &interpreter)
2607         : CommandObjectParsed(interpreter, "renderscript kernel breakpoint all",
2608                               "Automatically sets a breakpoint on all renderscript kernels that are or will be loaded.\n"
2609                               "Disabling option means breakpoints will no longer be set on any kernels loaded in the future, "
2610                               "but does not remove currently set breakpoints.",
2611                               "renderscript kernel breakpoint all <enable/disable>",
2612                               eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
2613     {
2614     }
2615 
2616     ~CommandObjectRenderScriptRuntimeKernelBreakpointAll() {}
2617 
2618     bool
2619     DoExecute(Args &command, CommandReturnObject &result)
2620     {
2621         const size_t argc = command.GetArgumentCount();
2622         if (argc != 1)
2623         {
2624             result.AppendErrorWithFormat("'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str());
2625             result.SetStatus(eReturnStatusFailed);
2626             return false;
2627         }
2628 
2629         RenderScriptRuntime *runtime =
2630           static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
2631 
2632         bool do_break = false;
2633         const char* argument = command.GetArgumentAtIndex(0);
2634         if (strcmp(argument, "enable") == 0)
2635         {
2636             do_break = true;
2637             result.AppendMessage("Breakpoints will be set on all kernels.");
2638         }
2639         else if (strcmp(argument, "disable") == 0)
2640         {
2641             do_break = false;
2642             result.AppendMessage("Breakpoints will not be set on any new kernels.");
2643         }
2644         else
2645         {
2646             result.AppendErrorWithFormat("Argument must be either 'enable' or 'disable'");
2647             result.SetStatus(eReturnStatusFailed);
2648             return false;
2649         }
2650 
2651         runtime->SetBreakAllKernels(do_break, m_exe_ctx.GetTargetSP());
2652 
2653         result.SetStatus(eReturnStatusSuccessFinishResult);
2654         return true;
2655     }
2656 };
2657 
2658 class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectMultiword
2659 {
2660   private:
2661   public:
2662     CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter)
2663         : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that generate breakpoints on renderscript kernels.",
2664                                  nullptr)
2665     {
2666         LoadSubCommand("set", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointSet(interpreter)));
2667         LoadSubCommand("all", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointAll(interpreter)));
2668     }
2669 
2670     ~CommandObjectRenderScriptRuntimeKernelBreakpoint() {}
2671 };
2672 
2673 class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword
2674 {
2675   private:
2676   public:
2677     CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter)
2678         : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with renderscript kernels.",
2679                                  NULL)
2680     {
2681         LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(interpreter)));
2682         LoadSubCommand("breakpoint", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter)));
2683     }
2684 
2685     ~CommandObjectRenderScriptRuntimeKernel() {}
2686 };
2687 
2688 class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed
2689 {
2690   private:
2691   public:
2692     CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter)
2693         : CommandObjectParsed(interpreter, "renderscript context dump",
2694                               "Dumps renderscript context information.", "renderscript context dump",
2695                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
2696     {
2697     }
2698 
2699     ~CommandObjectRenderScriptRuntimeContextDump() {}
2700 
2701     bool
2702     DoExecute(Args &command, CommandReturnObject &result)
2703     {
2704         RenderScriptRuntime *runtime =
2705             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
2706         runtime->DumpContexts(result.GetOutputStream());
2707         result.SetStatus(eReturnStatusSuccessFinishResult);
2708         return true;
2709     }
2710 };
2711 
2712 class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword
2713 {
2714   private:
2715   public:
2716     CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter)
2717         : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with renderscript contexts.",
2718                                  NULL)
2719     {
2720         LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(interpreter)));
2721     }
2722 
2723     ~CommandObjectRenderScriptRuntimeContext() {}
2724 };
2725 
2726 
2727 class CommandObjectRenderScriptRuntimeAllocationDump : public CommandObjectParsed
2728 {
2729   private:
2730   public:
2731     CommandObjectRenderScriptRuntimeAllocationDump(CommandInterpreter &interpreter)
2732         : CommandObjectParsed(interpreter, "renderscript allocation dump",
2733                               "Displays the contents of a particular allocation", "renderscript allocation dump <ID>",
2734                               eCommandRequiresProcess | eCommandProcessMustBeLaunched), m_options(interpreter)
2735     {
2736     }
2737 
2738     virtual Options*
2739     GetOptions()
2740     {
2741         return &m_options;
2742     }
2743 
2744     class CommandOptions : public Options
2745     {
2746       public:
2747         CommandOptions(CommandInterpreter &interpreter) : Options(interpreter)
2748         {
2749         }
2750 
2751         virtual
2752         ~CommandOptions()
2753         {
2754         }
2755 
2756         virtual Error
2757         SetOptionValue(uint32_t option_idx, const char *option_arg)
2758         {
2759             Error error;
2760             const int short_option = m_getopt_table[option_idx].val;
2761 
2762             switch (short_option)
2763             {
2764                 case 'f':
2765                     m_outfile.SetFile(option_arg, true);
2766                     if (m_outfile.Exists())
2767                     {
2768                         m_outfile.Clear();
2769                         error.SetErrorStringWithFormat("file already exists: '%s'", option_arg);
2770                     }
2771                     break;
2772                 default:
2773                     error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
2774                     break;
2775             }
2776             return error;
2777         }
2778 
2779         void
2780         OptionParsingStarting()
2781         {
2782             m_outfile.Clear();
2783         }
2784 
2785         const OptionDefinition*
2786         GetDefinitions()
2787         {
2788             return g_option_table;
2789         }
2790 
2791         static OptionDefinition g_option_table[];
2792         FileSpec m_outfile;
2793     };
2794 
2795     ~CommandObjectRenderScriptRuntimeAllocationDump() {}
2796 
2797     bool
2798     DoExecute(Args &command, CommandReturnObject &result)
2799     {
2800         const size_t argc = command.GetArgumentCount();
2801         if (argc < 1)
2802         {
2803             result.AppendErrorWithFormat("'%s' takes 1 argument, an allocation ID. As well as an optional -f argument",
2804                                          m_cmd_name.c_str());
2805             result.SetStatus(eReturnStatusFailed);
2806             return false;
2807         }
2808 
2809         RenderScriptRuntime *runtime =
2810           static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
2811 
2812         const char* id_cstr = command.GetArgumentAtIndex(0);
2813         bool convert_complete = false;
2814         const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete);
2815         if (!convert_complete)
2816         {
2817             result.AppendErrorWithFormat("invalid allocation id argument '%s'", id_cstr);
2818             result.SetStatus(eReturnStatusFailed);
2819             return false;
2820         }
2821 
2822         Stream* output_strm = nullptr;
2823         StreamFile outfile_stream;
2824         const FileSpec &outfile_spec = m_options.m_outfile; // Dump allocation to file instead
2825         if (outfile_spec)
2826         {
2827             // Open output file
2828             char path[256];
2829             outfile_spec.GetPath(path, sizeof(path));
2830             if (outfile_stream.GetFile().Open(path, File::eOpenOptionWrite | File::eOpenOptionCanCreate).Success())
2831             {
2832                 output_strm = &outfile_stream;
2833                 result.GetOutputStream().Printf("Results written to '%s'", path);
2834                 result.GetOutputStream().EOL();
2835             }
2836             else
2837             {
2838                 result.AppendErrorWithFormat("Couldn't open file '%s'", path);
2839                 result.SetStatus(eReturnStatusFailed);
2840                 return false;
2841             }
2842         }
2843         else
2844             output_strm = &result.GetOutputStream();
2845 
2846         assert(output_strm != nullptr);
2847         bool success = runtime->DumpAllocation(*output_strm, m_exe_ctx.GetFramePtr(), id);
2848 
2849         if (success)
2850             result.SetStatus(eReturnStatusSuccessFinishResult);
2851         else
2852             result.SetStatus(eReturnStatusFailed);
2853 
2854         return true;
2855     }
2856 
2857     private:
2858         CommandOptions m_options;
2859 };
2860 
2861 OptionDefinition
2862 CommandObjectRenderScriptRuntimeAllocationDump::CommandOptions::g_option_table[] =
2863 {
2864     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename,
2865       "Print results to specified file instead of command line."},
2866     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2867 };
2868 
2869 
2870 class CommandObjectRenderScriptRuntimeAllocationList : public CommandObjectParsed
2871 {
2872   public:
2873     CommandObjectRenderScriptRuntimeAllocationList(CommandInterpreter &interpreter)
2874         : CommandObjectParsed(interpreter, "renderscript allocation list",
2875                               "List renderscript allocations and their information.", "renderscript allocation list",
2876                               eCommandRequiresProcess | eCommandProcessMustBeLaunched), m_options(interpreter)
2877     {
2878     }
2879 
2880     virtual Options*
2881     GetOptions()
2882     {
2883         return &m_options;
2884     }
2885 
2886     class CommandOptions : public Options
2887     {
2888       public:
2889         CommandOptions(CommandInterpreter &interpreter) : Options(interpreter), m_refresh(false)
2890         {
2891         }
2892 
2893         virtual
2894         ~CommandOptions()
2895         {
2896         }
2897 
2898         virtual Error
2899         SetOptionValue(uint32_t option_idx, const char *option_arg)
2900         {
2901             Error error;
2902             const int short_option = m_getopt_table[option_idx].val;
2903 
2904             switch (short_option)
2905             {
2906                 case 'r':
2907                     m_refresh = true;
2908                     break;
2909                 default:
2910                     error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
2911                     break;
2912             }
2913             return error;
2914         }
2915 
2916         void
2917         OptionParsingStarting()
2918         {
2919             m_refresh = false;
2920         }
2921 
2922         const OptionDefinition*
2923         GetDefinitions()
2924         {
2925             return g_option_table;
2926         }
2927 
2928         static OptionDefinition g_option_table[];
2929         bool m_refresh;
2930     };
2931 
2932     ~CommandObjectRenderScriptRuntimeAllocationList() {}
2933 
2934     bool
2935     DoExecute(Args &command, CommandReturnObject &result)
2936     {
2937         RenderScriptRuntime *runtime =
2938           static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
2939         runtime->ListAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr(), m_options.m_refresh);
2940         result.SetStatus(eReturnStatusSuccessFinishResult);
2941         return true;
2942     }
2943 
2944   private:
2945     CommandOptions m_options;
2946 };
2947 
2948 OptionDefinition
2949 CommandObjectRenderScriptRuntimeAllocationList::CommandOptions::g_option_table[] =
2950 {
2951     { LLDB_OPT_SET_1, false, "refresh", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
2952       "Recompute allocation details."},
2953     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2954 };
2955 
2956 
2957 class CommandObjectRenderScriptRuntimeAllocationLoad : public CommandObjectParsed
2958 {
2959   private:
2960   public:
2961     CommandObjectRenderScriptRuntimeAllocationLoad(CommandInterpreter &interpreter)
2962         : CommandObjectParsed(interpreter, "renderscript allocation load",
2963                               "Loads renderscript allocation contents from a file.", "renderscript allocation load <ID> <filename>",
2964                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
2965     {
2966     }
2967 
2968     ~CommandObjectRenderScriptRuntimeAllocationLoad() {}
2969 
2970     bool
2971     DoExecute(Args &command, CommandReturnObject &result)
2972     {
2973         const size_t argc = command.GetArgumentCount();
2974         if (argc != 2)
2975         {
2976             result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.", m_cmd_name.c_str());
2977             result.SetStatus(eReturnStatusFailed);
2978             return false;
2979         }
2980 
2981         RenderScriptRuntime *runtime =
2982           static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
2983 
2984         const char* id_cstr = command.GetArgumentAtIndex(0);
2985         bool convert_complete = false;
2986         const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete);
2987         if (!convert_complete)
2988         {
2989             result.AppendErrorWithFormat ("invalid allocation id argument '%s'", id_cstr);
2990             result.SetStatus (eReturnStatusFailed);
2991             return false;
2992         }
2993 
2994         const char* filename = command.GetArgumentAtIndex(1);
2995         bool success = runtime->LoadAllocation(result.GetOutputStream(), id, filename, m_exe_ctx.GetFramePtr());
2996 
2997         if (success)
2998             result.SetStatus(eReturnStatusSuccessFinishResult);
2999         else
3000             result.SetStatus(eReturnStatusFailed);
3001 
3002         return true;
3003     }
3004 };
3005 
3006 
3007 class CommandObjectRenderScriptRuntimeAllocationSave : public CommandObjectParsed
3008 {
3009   private:
3010   public:
3011     CommandObjectRenderScriptRuntimeAllocationSave(CommandInterpreter &interpreter)
3012         : CommandObjectParsed(interpreter, "renderscript allocation save",
3013                               "Write renderscript allocation contents to a file.", "renderscript allocation save <ID> <filename>",
3014                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
3015     {
3016     }
3017 
3018     ~CommandObjectRenderScriptRuntimeAllocationSave() {}
3019 
3020     bool
3021     DoExecute(Args &command, CommandReturnObject &result)
3022     {
3023         const size_t argc = command.GetArgumentCount();
3024         if (argc != 2)
3025         {
3026             result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.", m_cmd_name.c_str());
3027             result.SetStatus(eReturnStatusFailed);
3028             return false;
3029         }
3030 
3031         RenderScriptRuntime *runtime =
3032           static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
3033 
3034         const char* id_cstr = command.GetArgumentAtIndex(0);
3035         bool convert_complete = false;
3036         const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete);
3037         if (!convert_complete)
3038         {
3039             result.AppendErrorWithFormat ("invalid allocation id argument '%s'", id_cstr);
3040             result.SetStatus (eReturnStatusFailed);
3041             return false;
3042         }
3043 
3044         const char* filename = command.GetArgumentAtIndex(1);
3045         bool success = runtime->SaveAllocation(result.GetOutputStream(), id, filename, m_exe_ctx.GetFramePtr());
3046 
3047         if (success)
3048             result.SetStatus(eReturnStatusSuccessFinishResult);
3049         else
3050             result.SetStatus(eReturnStatusFailed);
3051 
3052         return true;
3053     }
3054 };
3055 
3056 class CommandObjectRenderScriptRuntimeAllocation : public CommandObjectMultiword
3057 {
3058   private:
3059   public:
3060     CommandObjectRenderScriptRuntimeAllocation(CommandInterpreter &interpreter)
3061         : CommandObjectMultiword(interpreter, "renderscript allocation", "Commands that deal with renderscript allocations.",
3062                                  NULL)
3063     {
3064         LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationList(interpreter)));
3065         LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationDump(interpreter)));
3066         LoadSubCommand("save", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationSave(interpreter)));
3067         LoadSubCommand("load", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationLoad(interpreter)));
3068     }
3069 
3070     ~CommandObjectRenderScriptRuntimeAllocation() {}
3071 };
3072 
3073 
3074 class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed
3075 {
3076   private:
3077   public:
3078     CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter)
3079         : CommandObjectParsed(interpreter, "renderscript status",
3080                               "Displays current renderscript runtime status.", "renderscript status",
3081                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
3082     {
3083     }
3084 
3085     ~CommandObjectRenderScriptRuntimeStatus() {}
3086 
3087     bool
3088     DoExecute(Args &command, CommandReturnObject &result)
3089     {
3090         RenderScriptRuntime *runtime =
3091             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
3092         runtime->Status(result.GetOutputStream());
3093         result.SetStatus(eReturnStatusSuccessFinishResult);
3094         return true;
3095     }
3096 };
3097 
3098 class CommandObjectRenderScriptRuntime : public CommandObjectMultiword
3099 {
3100   public:
3101     CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter)
3102         : CommandObjectMultiword(interpreter, "renderscript", "A set of commands for operating on renderscript.",
3103                                  "renderscript <subcommand> [<subcommand-options>]")
3104     {
3105         LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter)));
3106         LoadSubCommand("status", CommandObjectSP(new CommandObjectRenderScriptRuntimeStatus(interpreter)));
3107         LoadSubCommand("kernel", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernel(interpreter)));
3108         LoadSubCommand("context", CommandObjectSP(new CommandObjectRenderScriptRuntimeContext(interpreter)));
3109         LoadSubCommand("allocation", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocation(interpreter)));
3110     }
3111 
3112     ~CommandObjectRenderScriptRuntime() {}
3113 };
3114 
3115 void
3116 RenderScriptRuntime::Initiate()
3117 {
3118     assert(!m_initiated);
3119 }
3120 
3121 RenderScriptRuntime::RenderScriptRuntime(Process *process)
3122     : lldb_private::CPPLanguageRuntime(process), m_initiated(false), m_debuggerPresentFlagged(false),
3123       m_breakAllKernels(false)
3124 {
3125     ModulesDidLoad(process->GetTarget().GetImages());
3126 }
3127 
3128 lldb::CommandObjectSP
3129 RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter& interpreter)
3130 {
3131     static CommandObjectSP command_object;
3132     if(!command_object)
3133     {
3134         command_object.reset(new CommandObjectRenderScriptRuntime(interpreter));
3135     }
3136     return command_object;
3137 }
3138 
3139 RenderScriptRuntime::~RenderScriptRuntime() = default;
3140