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 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 // Project includes
14 #include "RenderScriptRuntime.h"
15 
16 #include "lldb/Core/ConstString.h"
17 #include "lldb/Core/Debugger.h"
18 #include "lldb/Core/Error.h"
19 #include "lldb/Core/Log.h"
20 #include "lldb/Core/PluginManager.h"
21 #include "lldb/Core/ValueObjectVariable.h"
22 #include "lldb/Core/RegularExpression.h"
23 #include "lldb/DataFormatters/DumpValueObjectOptions.h"
24 #include "lldb/Host/StringConvert.h"
25 #include "lldb/Symbol/Symbol.h"
26 #include "lldb/Symbol/Type.h"
27 #include "lldb/Target/Process.h"
28 #include "lldb/Target/Target.h"
29 #include "lldb/Target/Thread.h"
30 #include "lldb/Interpreter/Args.h"
31 #include "lldb/Interpreter/Options.h"
32 #include "lldb/Interpreter/CommandInterpreter.h"
33 #include "lldb/Interpreter/CommandReturnObject.h"
34 #include "lldb/Interpreter/CommandObjectMultiword.h"
35 #include "lldb/Breakpoint/StoppointCallbackContext.h"
36 #include "lldb/Target/RegisterContext.h"
37 #include "lldb/Expression/UserExpression.h"
38 #include "lldb/Symbol/VariableList.h"
39 
40 using namespace lldb;
41 using namespace lldb_private;
42 using namespace lldb_renderscript;
43 
44 namespace {
45 
46 // The empirical_type adds a basic level of validation to arbitrary data
47 // allowing us to track if data has been discovered and stored or not.
48 // An empirical_type will be marked as valid only if it has been explicitly assigned to.
49 template <typename type_t>
50 class empirical_type
51 {
52 public:
53     // Ctor. Contents is invalid when constructed.
54     empirical_type()
55         : valid(false)
56     {}
57 
58     // Return true and copy contents to out if valid, else return false.
59     bool get(type_t& out) const
60     {
61         if (valid)
62             out = data;
63         return valid;
64     }
65 
66     // Return a pointer to the contents or nullptr if it was not valid.
67     const type_t* get() const
68     {
69         return valid ? &data : nullptr;
70     }
71 
72     // Assign data explicitly.
73     void set(const type_t in)
74     {
75         data = in;
76         valid = true;
77     }
78 
79     // Mark contents as invalid.
80     void invalidate()
81     {
82         valid = false;
83     }
84 
85     // Returns true if this type contains valid data.
86     bool isValid() const
87     {
88         return valid;
89     }
90 
91     // Assignment operator.
92     empirical_type<type_t>& operator = (const type_t in)
93     {
94         set(in);
95         return *this;
96     }
97 
98     // Dereference operator returns contents.
99     // Warning: Will assert if not valid so use only when you know data is valid.
100     const type_t& operator * () const
101     {
102         assert(valid);
103         return data;
104     }
105 
106 protected:
107     bool valid;
108     type_t data;
109 };
110 
111 } // anonymous namespace
112 
113 // The ScriptDetails class collects data associated with a single script instance.
114 struct RenderScriptRuntime::ScriptDetails
115 {
116     ~ScriptDetails() = default;
117 
118     enum ScriptType
119     {
120         eScript,
121         eScriptC
122     };
123 
124     // The derived type of the script.
125     empirical_type<ScriptType> type;
126     // The name of the original source file.
127     empirical_type<std::string> resName;
128     // Path to script .so file on the device.
129     empirical_type<std::string> scriptDyLib;
130     // Directory where kernel objects are cached on device.
131     empirical_type<std::string> cacheDir;
132     // Pointer to the context which owns this script.
133     empirical_type<lldb::addr_t> context;
134     // Pointer to the script object itself.
135     empirical_type<lldb::addr_t> script;
136 };
137 
138 // This Element class represents the Element object in RS,
139 // defining the type associated with an Allocation.
140 struct RenderScriptRuntime::Element
141 {
142     // Taken from rsDefines.h
143     enum DataKind
144     {
145         RS_KIND_USER,
146         RS_KIND_PIXEL_L = 7,
147         RS_KIND_PIXEL_A,
148         RS_KIND_PIXEL_LA,
149         RS_KIND_PIXEL_RGB,
150         RS_KIND_PIXEL_RGBA,
151         RS_KIND_PIXEL_DEPTH,
152         RS_KIND_PIXEL_YUV,
153         RS_KIND_INVALID = 100
154     };
155 
156     // Taken from rsDefines.h
157     enum DataType
158     {
159         RS_TYPE_NONE = 0,
160         RS_TYPE_FLOAT_16,
161         RS_TYPE_FLOAT_32,
162         RS_TYPE_FLOAT_64,
163         RS_TYPE_SIGNED_8,
164         RS_TYPE_SIGNED_16,
165         RS_TYPE_SIGNED_32,
166         RS_TYPE_SIGNED_64,
167         RS_TYPE_UNSIGNED_8,
168         RS_TYPE_UNSIGNED_16,
169         RS_TYPE_UNSIGNED_32,
170         RS_TYPE_UNSIGNED_64,
171         RS_TYPE_BOOLEAN,
172 
173         RS_TYPE_UNSIGNED_5_6_5,
174         RS_TYPE_UNSIGNED_5_5_5_1,
175         RS_TYPE_UNSIGNED_4_4_4_4,
176 
177         RS_TYPE_MATRIX_4X4,
178         RS_TYPE_MATRIX_3X3,
179         RS_TYPE_MATRIX_2X2,
180 
181         RS_TYPE_ELEMENT = 1000,
182         RS_TYPE_TYPE,
183         RS_TYPE_ALLOCATION,
184         RS_TYPE_SAMPLER,
185         RS_TYPE_SCRIPT,
186         RS_TYPE_MESH,
187         RS_TYPE_PROGRAM_FRAGMENT,
188         RS_TYPE_PROGRAM_VERTEX,
189         RS_TYPE_PROGRAM_RASTER,
190         RS_TYPE_PROGRAM_STORE,
191         RS_TYPE_FONT,
192 
193         RS_TYPE_INVALID = 10000
194     };
195 
196     std::vector<Element> children;                       // Child Element fields for structs
197     empirical_type<lldb::addr_t> element_ptr;            // Pointer to the RS Element of the Type
198     empirical_type<DataType> type;                       // Type of each data pointer stored by the allocation
199     empirical_type<DataKind> type_kind;                  // Defines pixel type if Allocation is created from an image
200     empirical_type<uint32_t> type_vec_size;              // Vector size of each data point, e.g '4' for uchar4
201     empirical_type<uint32_t> field_count;                // Number of Subelements
202     empirical_type<uint32_t> datum_size;                 // Size of a single Element with padding
203     empirical_type<uint32_t> padding;                    // Number of padding bytes
204     empirical_type<uint32_t> array_size;                 // Number of items in array, only needed for strucrs
205     ConstString type_name;                               // Name of type, only needed for structs
206 
207     static const ConstString &GetFallbackStructName();   // Print this as the type name of a struct Element
208                                                          // If we can't resolve the actual struct name
209 
210     bool shouldRefresh() const
211     {
212         const bool valid_ptr = element_ptr.isValid() && *element_ptr.get() != 0x0;
213         const bool valid_type = type.isValid() && type_vec_size.isValid() && type_kind.isValid();
214         return !valid_ptr || !valid_type || !datum_size.isValid();
215     }
216 };
217 
218 // This AllocationDetails class collects data associated with a single
219 // allocation instance.
220 struct RenderScriptRuntime::AllocationDetails
221 {
222     struct Dimension
223     {
224         uint32_t dim_1;
225         uint32_t dim_2;
226         uint32_t dim_3;
227         uint32_t cubeMap;
228 
229         Dimension()
230         {
231              dim_1 = 0;
232              dim_2 = 0;
233              dim_3 = 0;
234              cubeMap = 0;
235         }
236     };
237 
238     // The FileHeader struct specifies the header we use for writing allocations to a binary file.
239     // Our format begins with the ASCII characters "RSAD", identifying the file as an allocation dump.
240     // Member variables dims and hdr_size are then written consecutively, immediately followed by an instance of
241     // the ElementHeader struct. Because Elements can contain subelements, there may be more than one instance
242     // of the ElementHeader struct. With this first instance being the root element, and the other instances being
243     // the root's descendants. To identify which instances are an ElementHeader's children, each struct
244     // is immediately followed by a sequence of consecutive offsets to the start of its child structs.
245     // These offsets are 4 bytes in size, and the 0 offset signifies no more children.
246     struct FileHeader
247     {
248         uint8_t ident[4];      // ASCII 'RSAD' identifying the file
249         uint32_t dims[3];      // Dimensions
250         uint16_t hdr_size;     // Header size in bytes, including all element headers
251     };
252 
253     struct ElementHeader
254     {
255         uint16_t type;          // DataType enum
256         uint32_t kind;          // DataKind enum
257         uint32_t element_size;  // Size of a single element, including padding
258         uint16_t vector_size;   // Vector width
259         uint32_t array_size;    // Number of elements in array
260     };
261 
262     // Monotonically increasing from 1
263     static unsigned int ID;
264 
265     // Maps Allocation DataType enum and vector size to printable strings
266     // using mapping from RenderScript numerical types summary documentation
267     static const char* RsDataTypeToString[][4];
268 
269     // Maps Allocation DataKind enum to printable strings
270     static const char* RsDataKindToString[];
271 
272     // Maps allocation types to format sizes for printing.
273     static const unsigned int RSTypeToFormat[][3];
274 
275     // Give each allocation an ID as a way
276     // for commands to reference it.
277     const unsigned int id;
278 
279     RenderScriptRuntime::Element element;     // Allocation Element type
280     empirical_type<Dimension> dimension;      // Dimensions of the Allocation
281     empirical_type<lldb::addr_t> address;     // Pointer to address of the RS Allocation
282     empirical_type<lldb::addr_t> data_ptr;    // Pointer to the data held by the Allocation
283     empirical_type<lldb::addr_t> type_ptr;    // Pointer to the RS Type of the Allocation
284     empirical_type<lldb::addr_t> context;     // Pointer to the RS Context of the Allocation
285     empirical_type<uint32_t> size;            // Size of the allocation
286     empirical_type<uint32_t> stride;          // Stride between rows of the allocation
287 
288     // Give each allocation an id, so we can reference it in user commands.
289     AllocationDetails(): id(ID++)
290     {
291     }
292 
293     bool shouldRefresh() const
294     {
295         bool valid_ptrs = data_ptr.isValid() && *data_ptr.get() != 0x0;
296         valid_ptrs = valid_ptrs && type_ptr.isValid() && *type_ptr.get() != 0x0;
297         return !valid_ptrs || !dimension.isValid() || !size.isValid() || element.shouldRefresh();
298     }
299 };
300 
301 const ConstString &
302 RenderScriptRuntime::Element::GetFallbackStructName()
303 {
304     static const ConstString FallbackStructName("struct");
305     return FallbackStructName;
306 }
307 
308 unsigned int RenderScriptRuntime::AllocationDetails::ID = 1;
309 
310 const char* RenderScriptRuntime::AllocationDetails::RsDataKindToString[] =
311 {
312    "User",
313    "Undefined", "Undefined", "Undefined", // Enum jumps from 0 to 7
314    "Undefined", "Undefined", "Undefined",
315    "L Pixel",
316    "A Pixel",
317    "LA Pixel",
318    "RGB Pixel",
319    "RGBA Pixel",
320    "Pixel Depth",
321    "YUV Pixel"
322 };
323 
324 const char* RenderScriptRuntime::AllocationDetails::RsDataTypeToString[][4] =
325 {
326     {"None", "None", "None", "None"},
327     {"half", "half2", "half3", "half4"},
328     {"float", "float2", "float3", "float4"},
329     {"double", "double2", "double3", "double4"},
330     {"char", "char2", "char3", "char4"},
331     {"short", "short2", "short3", "short4"},
332     {"int", "int2", "int3", "int4"},
333     {"long", "long2", "long3", "long4"},
334     {"uchar", "uchar2", "uchar3", "uchar4"},
335     {"ushort", "ushort2", "ushort3", "ushort4"},
336     {"uint", "uint2", "uint3", "uint4"},
337     {"ulong", "ulong2", "ulong3", "ulong4"},
338     {"bool", "bool2", "bool3", "bool4"},
339     {"packed_565", "packed_565", "packed_565", "packed_565"},
340     {"packed_5551", "packed_5551", "packed_5551", "packed_5551"},
341     {"packed_4444", "packed_4444", "packed_4444", "packed_4444"},
342     {"rs_matrix4x4", "rs_matrix4x4", "rs_matrix4x4", "rs_matrix4x4"},
343     {"rs_matrix3x3", "rs_matrix3x3", "rs_matrix3x3", "rs_matrix3x3"},
344     {"rs_matrix2x2", "rs_matrix2x2", "rs_matrix2x2", "rs_matrix2x2"},
345 
346     // Handlers
347     {"RS Element", "RS Element", "RS Element", "RS Element"},
348     {"RS Type", "RS Type", "RS Type", "RS Type"},
349     {"RS Allocation", "RS Allocation", "RS Allocation", "RS Allocation"},
350     {"RS Sampler", "RS Sampler", "RS Sampler", "RS Sampler"},
351     {"RS Script", "RS Script", "RS Script", "RS Script"},
352 
353     // Deprecated
354     {"RS Mesh", "RS Mesh", "RS Mesh", "RS Mesh"},
355     {"RS Program Fragment", "RS Program Fragment", "RS Program Fragment", "RS Program Fragment"},
356     {"RS Program Vertex", "RS Program Vertex", "RS Program Vertex", "RS Program Vertex"},
357     {"RS Program Raster", "RS Program Raster", "RS Program Raster", "RS Program Raster"},
358     {"RS Program Store", "RS Program Store", "RS Program Store", "RS Program Store"},
359     {"RS Font", "RS Font", "RS Font", "RS Font"}
360 };
361 
362 // Used as an index into the RSTypeToFormat array elements
363 enum TypeToFormatIndex {
364    eFormatSingle = 0,
365    eFormatVector,
366    eElementSize
367 };
368 
369 // { format enum of single element, format enum of element vector, size of element}
370 const unsigned int RenderScriptRuntime::AllocationDetails::RSTypeToFormat[][3] =
371 {
372     {eFormatHex, eFormatHex, 1}, // RS_TYPE_NONE
373     {eFormatFloat, eFormatVectorOfFloat16, 2}, // RS_TYPE_FLOAT_16
374     {eFormatFloat, eFormatVectorOfFloat32, sizeof(float)}, // RS_TYPE_FLOAT_32
375     {eFormatFloat, eFormatVectorOfFloat64, sizeof(double)}, // RS_TYPE_FLOAT_64
376     {eFormatDecimal, eFormatVectorOfSInt8, sizeof(int8_t)}, // RS_TYPE_SIGNED_8
377     {eFormatDecimal, eFormatVectorOfSInt16, sizeof(int16_t)}, // RS_TYPE_SIGNED_16
378     {eFormatDecimal, eFormatVectorOfSInt32, sizeof(int32_t)}, // RS_TYPE_SIGNED_32
379     {eFormatDecimal, eFormatVectorOfSInt64, sizeof(int64_t)}, // RS_TYPE_SIGNED_64
380     {eFormatDecimal, eFormatVectorOfUInt8, sizeof(uint8_t)}, // RS_TYPE_UNSIGNED_8
381     {eFormatDecimal, eFormatVectorOfUInt16, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_16
382     {eFormatDecimal, eFormatVectorOfUInt32, sizeof(uint32_t)}, // RS_TYPE_UNSIGNED_32
383     {eFormatDecimal, eFormatVectorOfUInt64, sizeof(uint64_t)}, // RS_TYPE_UNSIGNED_64
384     {eFormatBoolean, eFormatBoolean, 1}, // RS_TYPE_BOOL
385     {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_5_6_5
386     {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_5_5_5_1
387     {eFormatHex, eFormatHex, sizeof(uint16_t)}, // RS_TYPE_UNSIGNED_4_4_4_4
388     {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 16}, // RS_TYPE_MATRIX_4X4
389     {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 9}, // RS_TYPE_MATRIX_3X3
390     {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 4} // RS_TYPE_MATRIX_2X2
391 };
392 
393 //------------------------------------------------------------------
394 // Static Functions
395 //------------------------------------------------------------------
396 LanguageRuntime *
397 RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType language)
398 {
399 
400     if (language == eLanguageTypeExtRenderScript)
401         return new RenderScriptRuntime(process);
402     else
403         return NULL;
404 }
405 
406 // Callback with a module to search for matching symbols.
407 // We first check that the module contains RS kernels.
408 // Then look for a symbol which matches our kernel name.
409 // The breakpoint address is finally set using the address of this symbol.
410 Searcher::CallbackReturn
411 RSBreakpointResolver::SearchCallback(SearchFilter &filter,
412                                      SymbolContext &context,
413                                      Address*,
414                                      bool)
415 {
416     ModuleSP module = context.module_sp;
417 
418     if (!module)
419         return Searcher::eCallbackReturnContinue;
420 
421     // Is this a module containing renderscript kernels?
422     if (nullptr == module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData))
423         return Searcher::eCallbackReturnContinue;
424 
425     // Attempt to set a breakpoint on the kernel name symbol within the module library.
426     // If it's not found, it's likely debug info is unavailable - try to set a
427     // breakpoint on <name>.expand.
428 
429     const Symbol* kernel_sym = module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode);
430     if (!kernel_sym)
431     {
432         std::string kernel_name_expanded(m_kernel_name.AsCString());
433         kernel_name_expanded.append(".expand");
434         kernel_sym = module->FindFirstSymbolWithNameAndType(ConstString(kernel_name_expanded.c_str()), eSymbolTypeCode);
435     }
436 
437     if (kernel_sym)
438     {
439         Address bp_addr = kernel_sym->GetAddress();
440         if (filter.AddressPasses(bp_addr))
441             m_breakpoint->AddLocation(bp_addr);
442     }
443 
444     return Searcher::eCallbackReturnContinue;
445 }
446 
447 void
448 RenderScriptRuntime::Initialize()
449 {
450     PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance, GetCommandObject);
451 }
452 
453 void
454 RenderScriptRuntime::Terminate()
455 {
456     PluginManager::UnregisterPlugin(CreateInstance);
457 }
458 
459 lldb_private::ConstString
460 RenderScriptRuntime::GetPluginNameStatic()
461 {
462     static ConstString g_name("renderscript");
463     return g_name;
464 }
465 
466 RenderScriptRuntime::ModuleKind
467 RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp)
468 {
469     if (module_sp)
470     {
471         // Is this a module containing renderscript kernels?
472         const Symbol *info_sym = module_sp->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
473         if (info_sym)
474         {
475             return eModuleKindKernelObj;
476         }
477 
478         // Is this the main RS runtime library
479         const ConstString rs_lib("libRS.so");
480         if (module_sp->GetFileSpec().GetFilename() == rs_lib)
481         {
482             return eModuleKindLibRS;
483         }
484 
485         const ConstString rs_driverlib("libRSDriver.so");
486         if (module_sp->GetFileSpec().GetFilename() == rs_driverlib)
487         {
488             return eModuleKindDriver;
489         }
490 
491         const ConstString rs_cpureflib("libRSCpuRef.so");
492         if (module_sp->GetFileSpec().GetFilename() == rs_cpureflib)
493         {
494             return eModuleKindImpl;
495         }
496 
497     }
498     return eModuleKindIgnored;
499 }
500 
501 bool
502 RenderScriptRuntime::IsRenderScriptModule(const lldb::ModuleSP &module_sp)
503 {
504     return GetModuleKind(module_sp) != eModuleKindIgnored;
505 }
506 
507 void
508 RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list )
509 {
510     Mutex::Locker locker (module_list.GetMutex ());
511 
512     size_t num_modules = module_list.GetSize();
513     for (size_t i = 0; i < num_modules; i++)
514     {
515         auto mod = module_list.GetModuleAtIndex (i);
516         if (IsRenderScriptModule (mod))
517         {
518             LoadModule(mod);
519         }
520     }
521 }
522 
523 //------------------------------------------------------------------
524 // PluginInterface protocol
525 //------------------------------------------------------------------
526 lldb_private::ConstString
527 RenderScriptRuntime::GetPluginName()
528 {
529     return GetPluginNameStatic();
530 }
531 
532 uint32_t
533 RenderScriptRuntime::GetPluginVersion()
534 {
535     return 1;
536 }
537 
538 bool
539 RenderScriptRuntime::IsVTableName(const char *name)
540 {
541     return false;
542 }
543 
544 bool
545 RenderScriptRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
546                                               TypeAndOrName &class_type_or_name, Address &address,
547                                               Value::ValueType &value_type)
548 {
549     return false;
550 }
551 
552 TypeAndOrName
553 RenderScriptRuntime::FixUpDynamicType (const TypeAndOrName& type_and_or_name,
554                                        ValueObject& static_value)
555 {
556     return type_and_or_name;
557 }
558 
559 bool
560 RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value)
561 {
562     return false;
563 }
564 
565 lldb::BreakpointResolverSP
566 RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp)
567 {
568     BreakpointResolverSP resolver_sp;
569     return resolver_sp;
570 }
571 
572 const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] =
573 {
574     //rsdScript
575     {
576         "rsdScriptInit", //name
577         "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhjj", // symbol name 32 bit
578         "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhmj", // symbol name 64 bit
579         0, // version
580         RenderScriptRuntime::eModuleKindDriver, // type
581         &lldb_private::RenderScriptRuntime::CaptureScriptInit1 // handler
582     },
583     {
584         "rsdScriptInvokeForEachMulti", // name
585         "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall", // symbol name 32bit
586         "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEmPS6_PKvmPK12RsScriptCall", // symbol name 64bit
587         0, // version
588         RenderScriptRuntime::eModuleKindDriver, // type
589         &lldb_private::RenderScriptRuntime::CaptureScriptInvokeForEachMulti // handler
590     },
591     {
592         "rsdScriptSetGlobalVar", // name
593         "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvj", // symbol name 32bit
594         "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvm", // symbol name 64bit
595         0, // version
596         RenderScriptRuntime::eModuleKindDriver, // type
597         &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar1 // handler
598     },
599 
600     //rsdAllocation
601     {
602         "rsdAllocationInit", // name
603         "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 32bit
604         "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 64bit
605         0, // version
606         RenderScriptRuntime::eModuleKindDriver, // type
607         &lldb_private::RenderScriptRuntime::CaptureAllocationInit1 // handler
608     },
609     {
610         "rsdAllocationRead2D", //name
611         "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvjj", // symbol name 32bit
612         "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvmm", // symbol name 64bit
613         0, // version
614         RenderScriptRuntime::eModuleKindDriver, // type
615         nullptr // handler
616     },
617     {
618         "rsdAllocationDestroy", // name
619         "_Z20rsdAllocationDestroyPKN7android12renderscript7ContextEPNS0_10AllocationE", // symbol name 32bit
620         "_Z20rsdAllocationDestroyPKN7android12renderscript7ContextEPNS0_10AllocationE", // symbol name 64bit
621         0, // version
622         RenderScriptRuntime::eModuleKindDriver, // type
623         &lldb_private::RenderScriptRuntime::CaptureAllocationDestroy // handler
624     },
625 };
626 
627 const size_t RenderScriptRuntime::s_runtimeHookCount = sizeof(s_runtimeHookDefns)/sizeof(s_runtimeHookDefns[0]);
628 
629 bool
630 RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
631 {
632     RuntimeHook* hook_info = (RuntimeHook*)baton;
633     ExecutionContext context(ctx->exe_ctx_ref);
634 
635     RenderScriptRuntime *lang_rt = (RenderScriptRuntime *)context.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
636 
637     lang_rt->HookCallback(hook_info, context);
638 
639     return false;
640 }
641 
642 void
643 RenderScriptRuntime::HookCallback(RuntimeHook* hook_info, ExecutionContext& context)
644 {
645     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
646 
647     if (log)
648         log->Printf ("RenderScriptRuntime::HookCallback - '%s' .", hook_info->defn->name);
649 
650     if (hook_info->defn->grabber)
651     {
652         (this->*(hook_info->defn->grabber))(hook_info, context);
653     }
654 }
655 
656 bool
657 RenderScriptRuntime::GetArgSimple(ExecutionContext &context, uint32_t arg, uint64_t *data)
658 {
659     // Get a positional integer argument.
660     // Given an ExecutionContext, ``context`` which should be a RenderScript
661     // frame, get the value of the positional argument ``arg`` and save its value
662     // to the address pointed to by ``data``.
663     // returns true on success, false otherwise.
664     // If unsuccessful, the value pointed to by ``data`` is undefined. Otherwise,
665     // ``data`` will be set to the value of the the given ``arg``.
666     // NOTE: only natural width integer arguments for the machine are supported.
667     // Behaviour with non primitive arguments is undefined.
668 
669     if (!data)
670         return false;
671 
672     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
673     Error error;
674     RegisterContext* reg_ctx = context.GetRegisterContext();
675     Process* process = context.GetProcessPtr();
676     bool success = false; // return value
677 
678     if (!context.GetTargetPtr())
679     {
680         if (log)
681             log->Printf("RenderScriptRuntime::GetArgSimple - Invalid target");
682 
683         return false;
684     }
685 
686     switch (context.GetTargetPtr()->GetArchitecture().GetMachine())
687     {
688         case llvm::Triple::ArchType::x86:
689         {
690             uint64_t sp = reg_ctx->GetSP();
691             uint32_t offset = (1 + arg) * sizeof(uint32_t);
692             uint32_t result = 0;
693             process->ReadMemory(sp + offset, &result, sizeof(uint32_t), error);
694             if (error.Fail())
695             {
696                 if (log)
697                     log->Printf("RenderScriptRuntime::GetArgSimple - error reading X86 stack: %s.", error.AsCString());
698             }
699             else
700             {
701                 *data = result;
702                 success = true;
703             }
704             break;
705         }
706         case llvm::Triple::ArchType::x86_64:
707         {
708             // amd64 has 6 integer registers, and 8 XMM registers for parameter passing.
709             // Surplus args are spilled onto the stack.
710             // rdi, rsi, rdx, rcx, r8, r9, (zmm0 - 7 for vectors)
711             // ref: AMD64 ABI Draft 0.99.6 – October 7, 2013 – 10:35; Figure 3.4. Retrieved from
712             // http://www.x86-64.org/documentation/abi.pdf
713             if (arg > 5)
714             {
715                 if (log)
716                     log->Warning("X86_64 register spill is not supported.");
717                 break;
718             }
719             const char * regnames[] = {"rdi", "rsi", "rdx", "rcx", "r8", "r9"};
720             assert((sizeof(regnames) / sizeof(const char *)) > arg);
721             const RegisterInfo *rArg = reg_ctx->GetRegisterInfoByName(regnames[arg]);
722             RegisterValue rVal;
723             success = reg_ctx->ReadRegister(rArg, rVal);
724             if (success)
725             {
726                 *data = rVal.GetAsUInt64(0u, &success);
727             }
728             else
729             {
730                 if (log)
731                     log->Printf("RenderScriptRuntime::GetArgSimple - error reading x86_64 register: %d.", arg);
732             }
733             break;
734         }
735         case llvm::Triple::ArchType::arm:
736         {
737             // arm 32 bit
738             // first 4 arguments are passed via registers
739             if (arg < 4)
740             {
741                 const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg);
742                 RegisterValue rVal;
743                 success = reg_ctx->ReadRegister(rArg, rVal);
744                 if (success)
745                 {
746                     (*data) = rVal.GetAsUInt32(0u, &success);
747                 }
748                 else
749                 {
750                     if (log)
751                         log->Printf("RenderScriptRuntime::GetArgSimple - error reading ARM register: %d.", arg);
752                 }
753             }
754             else
755             {
756                 uint64_t sp = reg_ctx->GetSP();
757                 uint32_t offset = (arg-4) * sizeof(uint32_t);
758                 uint32_t value = 0;
759                 size_t bytes_read = process->ReadMemory(sp + offset, &value, sizeof(value), error);
760                 if (error.Fail() || bytes_read != sizeof(value))
761                 {
762                     if (log)
763                         log->Printf("RenderScriptRuntime::GetArgSimple - error reading ARM stack: %s.", error.AsCString());
764                 }
765                 else
766                 {
767                     *data = value;
768                     success = true;
769                 }
770             }
771             break;
772         }
773         case llvm::Triple::ArchType::aarch64:
774         {
775             // arm 64 bit
776             // first 8 arguments are in the registers
777             if (arg < 8)
778             {
779                 const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg);
780                 RegisterValue rVal;
781                 success = reg_ctx->ReadRegister(rArg, rVal);
782                 if (success)
783                 {
784                     *data = rVal.GetAsUInt64(0u, &success);
785                 }
786                 else
787                 {
788                     if (log)
789                         log->Printf("RenderScriptRuntime::GetArgSimple() - AARCH64 - Error while reading the argument #%d", arg);
790                 }
791             }
792             else
793             {
794                 // @TODO: need to find the argument in the stack
795                 if (log)
796                     log->Printf("RenderScriptRuntime::GetArgSimple - AARCH64 - FOR #ARG >= 8 NOT IMPLEMENTED YET. Argument number: %d", arg);
797             }
798             break;
799         }
800         case llvm::Triple::ArchType::mipsel:
801         {
802             // read from the registers
803             // first 4 arguments are passed in registers
804             if (arg < 4){
805                 const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg + 4);
806                 RegisterValue rVal;
807                 success = reg_ctx->ReadRegister(rArg, rVal);
808                 if (success)
809                 {
810                     *data = rVal.GetAsUInt64(0u, &success);
811                 }
812                 else
813                 {
814                     if (log)
815                         log->Printf("RenderScriptRuntime::GetArgSimple() - Mips - Error while reading the argument #%d", arg);
816                 }
817             }
818             // arguments > 4 are read from the stack
819             else
820             {
821                 uint64_t sp = reg_ctx->GetSP();
822                 uint32_t offset = arg * sizeof(uint32_t);
823                 uint32_t value = 0;
824                 size_t bytes_read = process->ReadMemory(sp + offset, &value, sizeof(value), error);
825                 if (error.Fail() || bytes_read != sizeof(value))
826                 {
827                     if (log)
828                         log->Printf("RenderScriptRuntime::GetArgSimple - error reading Mips stack: %s.", error.AsCString());
829                 }
830                 else
831                 {
832                     *data = value;
833                     success = true;
834                 }
835             }
836             break;
837         }
838         case llvm::Triple::ArchType::mips64el:
839         {
840             // read from the registers
841             if (arg < 8)
842             {
843                 const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg + 4);
844                 RegisterValue rVal;
845                 success = reg_ctx->ReadRegister(rArg, rVal);
846                 if (success)
847                 {
848                     (*data) = rVal.GetAsUInt64(0u, &success);
849                 }
850                 else
851                 {
852                     if (log)
853                         log->Printf("RenderScriptRuntime::GetArgSimple - Mips64 - Error reading the argument #%d", arg);
854                 }
855             }
856             // arguments > 8 are read from the stack
857             else
858             {
859                 uint64_t sp = reg_ctx->GetSP();
860                 uint32_t offset = (arg - 8) * sizeof(uint64_t);
861                 uint64_t value = 0;
862                 size_t bytes_read = process->ReadMemory(sp + offset, &value, sizeof(value), error);
863                 if (error.Fail() || bytes_read != sizeof(value))
864                 {
865                     if (log)
866                         log->Printf("RenderScriptRuntime::GetArgSimple - Mips64 - Error reading Mips64 stack: %s.", error.AsCString());
867                 }
868                 else
869                 {
870                     *data = value;
871                     success = true;
872                 }
873             }
874             break;
875         }
876         default:
877         {
878             // invalid architecture
879             if (log)
880                 log->Printf("RenderScriptRuntime::GetArgSimple - Architecture not supported");
881         }
882     }
883 
884     if (!success)
885     {
886         if (log)
887             log->Printf("RenderScriptRuntime::GetArgSimple - failed to get argument at index %" PRIu32, arg);
888     }
889     return success;
890 }
891 
892 void
893 RenderScriptRuntime::CaptureScriptInvokeForEachMulti(RuntimeHook* hook_info,
894                                                      ExecutionContext& context)
895 {
896     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
897 
898     struct args_t
899     {
900         uint64_t context;   // const Context       *rsc
901         uint64_t script;    // Script              *s
902         uint64_t slot;      // uint32_t             slot
903         uint64_t aIns;      // const Allocation   **aIns
904         uint64_t inLen;     // size_t               inLen
905         uint64_t aOut;      // Allocation          *aout
906         uint64_t usr;       // const void          *usr
907         uint64_t usrLen;    // size_t               usrLen
908         uint64_t sc;        // const RsScriptCall  *sc
909     }
910     args;
911 
912     bool success =
913         GetArgSimple(context, 0, &args.context) &&
914         GetArgSimple(context, 1, &args.script) &&
915         GetArgSimple(context, 2, &args.slot) &&
916         GetArgSimple(context, 3, &args.aIns) &&
917         GetArgSimple(context, 4, &args.inLen) &&
918         GetArgSimple(context, 5, &args.aOut) &&
919         GetArgSimple(context, 6, &args.usr) &&
920         GetArgSimple(context, 7, &args.usrLen) &&
921         GetArgSimple(context, 8, &args.sc);
922 
923     if (!success)
924     {
925         if (log)
926             log->Printf("RenderScriptRuntime::CaptureScriptInvokeForEachMulti()"
927                         " - Error while reading the function parameters");
928         return;
929     }
930 
931     const uint32_t target_ptr_size = m_process->GetAddressByteSize();
932     Error error;
933     std::vector<uint64_t> allocs;
934 
935     // traverse allocation list
936     for (uint64_t i = 0; i < args.inLen; ++i)
937     {
938         // calculate offest to allocation pointer
939         const lldb::addr_t addr = args.aIns + i * target_ptr_size;
940 
941         // Note: due to little endian layout, reading 32bits or 64bits into res64 will
942         //       give the correct results.
943 
944         uint64_t res64 = 0;
945         size_t read = m_process->ReadMemory(addr, &res64, target_ptr_size, error);
946         if (read != target_ptr_size || !error.Success())
947         {
948             if (log)
949                 log->Printf("RenderScriptRuntime::CaptureScriptInvokeForEachMulti()"
950                             " - Error while reading allocation list argument %" PRId64, i);
951         }
952         else
953         {
954             allocs.push_back(res64);
955         }
956     }
957 
958     // if there is an output allocation track it
959     if (args.aOut)
960     {
961         allocs.push_back(args.aOut);
962     }
963 
964     // for all allocations we have found
965     for (const uint64_t alloc_addr : allocs)
966     {
967         AllocationDetails* alloc = LookUpAllocation(alloc_addr, true);
968         if (alloc)
969         {
970             // save the allocation address
971             if (alloc->address.isValid())
972             {
973                 // check the allocation address we already have matches
974                 assert(*alloc->address.get() == alloc_addr);
975             }
976             else
977             {
978                 alloc->address = alloc_addr;
979             }
980 
981             // save the context
982             if (log)
983             {
984                 if (alloc->context.isValid() && *alloc->context.get() != args.context)
985                     log->Printf("RenderScriptRuntime::CaptureScriptInvokeForEachMulti"
986                                 " - Allocation used by multiple contexts");
987             }
988             alloc->context = args.context;
989         }
990     }
991 
992     // make sure we track this script object
993     if (lldb_private::RenderScriptRuntime::ScriptDetails * script = LookUpScript(args.script, true))
994     {
995         if (log)
996         {
997             if (script->context.isValid() && *script->context.get() != args.context)
998                 log->Printf("RenderScriptRuntime::CaptureScriptInvokeForEachMulti"
999                             " - Script used by multiple contexts");
1000         }
1001         script->context = args.context;
1002     }
1003 }
1004 
1005 void
1006 RenderScriptRuntime::CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context)
1007 {
1008     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1009 
1010     //Context, Script, int, data, length
1011 
1012     uint64_t rs_context_u64 = 0U;
1013     uint64_t rs_script_u64 = 0U;
1014     uint64_t rs_id_u64 = 0U;
1015     uint64_t rs_data_u64 = 0U;
1016     uint64_t rs_length_u64 = 0U;
1017 
1018     bool success =
1019         GetArgSimple(context, 0, &rs_context_u64) &&
1020         GetArgSimple(context, 1, &rs_script_u64) &&
1021         GetArgSimple(context, 2, &rs_id_u64) &&
1022         GetArgSimple(context, 3, &rs_data_u64) &&
1023         GetArgSimple(context, 4, &rs_length_u64);
1024 
1025     if (!success)
1026     {
1027         if (log)
1028             log->Printf("RenderScriptRuntime::CaptureSetGlobalVar1 - Error while reading the function parameters");
1029         return;
1030     }
1031 
1032     if (log)
1033     {
1034         log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 ":%" PRIu64 "bytes.",
1035                         rs_context_u64, rs_script_u64, rs_id_u64, rs_data_u64, rs_length_u64);
1036 
1037         addr_t script_addr =  (addr_t)rs_script_u64;
1038         if (m_scriptMappings.find( script_addr ) != m_scriptMappings.end())
1039         {
1040             auto rsm = m_scriptMappings[script_addr];
1041             if (rs_id_u64 < rsm->m_globals.size())
1042             {
1043                 auto rsg = rsm->m_globals[rs_id_u64];
1044                 log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - Setting of '%s' within '%s' inferred", rsg.m_name.AsCString(),
1045                                 rsm->m_module->GetFileSpec().GetFilename().AsCString());
1046             }
1047         }
1048     }
1049 }
1050 
1051 void
1052 RenderScriptRuntime::CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context)
1053 {
1054     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1055 
1056     //Context, Alloc, bool
1057 
1058     uint64_t rs_context_u64 = 0U;
1059     uint64_t rs_alloc_u64 = 0U;
1060     uint64_t rs_forceZero_u64 = 0U;
1061 
1062     bool success =
1063         GetArgSimple(context, 0, &rs_context_u64) &&
1064         GetArgSimple(context, 1, &rs_alloc_u64) &&
1065         GetArgSimple(context, 2, &rs_forceZero_u64);
1066     if (!success) // error case
1067     {
1068         if (log)
1069             log->Printf("RenderScriptRuntime::CaptureAllocationInit1 - Error while reading the function parameters");
1070         return; // abort
1071     }
1072 
1073     if (log)
1074         log->Printf ("RenderScriptRuntime::CaptureAllocationInit1 - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .",
1075                         rs_context_u64, rs_alloc_u64, rs_forceZero_u64);
1076 
1077     AllocationDetails* alloc = LookUpAllocation(rs_alloc_u64, true);
1078     if (alloc)
1079         alloc->context = rs_context_u64;
1080 }
1081 
1082 void
1083 RenderScriptRuntime::CaptureAllocationDestroy(RuntimeHook* hook_info, ExecutionContext& context)
1084 {
1085     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1086 
1087     // Context, Alloc
1088     uint64_t rs_context_u64 = 0U;
1089     uint64_t rs_alloc_u64 = 0U;
1090 
1091     bool success = GetArgSimple(context, 0, &rs_context_u64) && GetArgSimple(context, 1, &rs_alloc_u64);
1092     if (!success) // error case
1093     {
1094         if (log)
1095             log->Printf("RenderScriptRuntime::CaptureAllocationDestroy - Error while reading the function parameters");
1096         return; // abort
1097     }
1098 
1099     if (log)
1100         log->Printf("RenderScriptRuntime::CaptureAllocationDestroy - 0x%" PRIx64 ", 0x%" PRIx64 ".",
1101                     rs_context_u64, rs_alloc_u64);
1102 
1103     for (auto iter = m_allocations.begin(); iter != m_allocations.end(); ++iter)
1104     {
1105         auto& allocation_ap = *iter; // get the unique pointer
1106         if (allocation_ap->address.isValid() && *allocation_ap->address.get() == rs_alloc_u64)
1107         {
1108             m_allocations.erase(iter);
1109             if (log)
1110                 log->Printf("RenderScriptRuntime::CaptureAllocationDestroy - Deleted allocation entry");
1111             return;
1112         }
1113     }
1114 
1115     if (log)
1116         log->Printf("RenderScriptRuntime::CaptureAllocationDestroy - Couldn't find destroyed allocation");
1117 }
1118 
1119 void
1120 RenderScriptRuntime::CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context)
1121 {
1122     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1123 
1124     //Context, Script, resname Str, cachedir Str
1125     Error error;
1126     Process* process = context.GetProcessPtr();
1127 
1128     uint64_t rs_context_u64 = 0U;
1129     uint64_t rs_script_u64 = 0U;
1130     uint64_t rs_resnameptr_u64 = 0U;
1131     uint64_t rs_cachedirptr_u64 = 0U;
1132 
1133     std::string resname;
1134     std::string cachedir;
1135 
1136     // read the function parameters
1137     bool success =
1138         GetArgSimple(context, 0, &rs_context_u64) &&
1139         GetArgSimple(context, 1, &rs_script_u64) &&
1140         GetArgSimple(context, 2, &rs_resnameptr_u64) &&
1141         GetArgSimple(context, 3, &rs_cachedirptr_u64);
1142 
1143     if (!success)
1144     {
1145         if (log)
1146             log->Printf("RenderScriptRuntime::CaptureScriptInit1 - Error while reading the function parameters");
1147         return;
1148     }
1149 
1150     process->ReadCStringFromMemory((lldb::addr_t)rs_resnameptr_u64, resname, error);
1151     if (error.Fail())
1152     {
1153         if (log)
1154             log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading resname: %s.", error.AsCString());
1155 
1156     }
1157 
1158     process->ReadCStringFromMemory((lldb::addr_t)rs_cachedirptr_u64, cachedir, error);
1159     if (error.Fail())
1160     {
1161         if (log)
1162             log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading cachedir: %s.", error.AsCString());
1163     }
1164 
1165     if (log)
1166         log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .",
1167                      rs_context_u64, rs_script_u64, resname.c_str(), cachedir.c_str());
1168 
1169     if (resname.size() > 0)
1170     {
1171         StreamString strm;
1172         strm.Printf("librs.%s.so", resname.c_str());
1173 
1174         ScriptDetails* script = LookUpScript(rs_script_u64, true);
1175         if (script)
1176         {
1177             script->type = ScriptDetails::eScriptC;
1178             script->cacheDir = cachedir;
1179             script->resName = resname;
1180             script->scriptDyLib = strm.GetData();
1181             script->context = addr_t(rs_context_u64);
1182         }
1183 
1184         if (log)
1185             log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - '%s' tagged with context 0x%" PRIx64 " and script 0x%" PRIx64 ".",
1186                          strm.GetData(), rs_context_u64, rs_script_u64);
1187     }
1188     else if (log)
1189     {
1190         log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - resource name invalid, Script not tagged");
1191     }
1192 }
1193 
1194 void
1195 RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
1196 {
1197     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1198 
1199     if (!module)
1200     {
1201         return;
1202     }
1203 
1204     Target &target = GetProcess()->GetTarget();
1205     llvm::Triple::ArchType targetArchType = target.GetArchitecture().GetMachine();
1206 
1207     if (targetArchType != llvm::Triple::ArchType::x86
1208         && targetArchType != llvm::Triple::ArchType::arm
1209         && targetArchType != llvm::Triple::ArchType::aarch64
1210         && targetArchType != llvm::Triple::ArchType::mipsel
1211         && targetArchType != llvm::Triple::ArchType::mips64el
1212         && targetArchType != llvm::Triple::ArchType::x86_64
1213     )
1214     {
1215         if (log)
1216             log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to hook runtime. Only X86, ARM, Mips supported currently.");
1217 
1218         return;
1219     }
1220 
1221     uint32_t archByteSize = target.GetArchitecture().GetAddressByteSize();
1222 
1223     for (size_t idx = 0; idx < s_runtimeHookCount; idx++)
1224     {
1225         const HookDefn* hook_defn = &s_runtimeHookDefns[idx];
1226         if (hook_defn->kind != kind) {
1227             continue;
1228         }
1229 
1230         const char* symbol_name = (archByteSize == 4) ? hook_defn->symbol_name_m32 : hook_defn->symbol_name_m64;
1231 
1232         const Symbol *sym = module->FindFirstSymbolWithNameAndType(ConstString(symbol_name), eSymbolTypeCode);
1233         if (!sym){
1234             if (log){
1235                 log->Printf("RenderScriptRuntime::LoadRuntimeHooks - ERROR: Symbol '%s' related to the function %s not found", symbol_name, hook_defn->name);
1236             }
1237             continue;
1238         }
1239 
1240         addr_t addr = sym->GetLoadAddress(&target);
1241         if (addr == LLDB_INVALID_ADDRESS)
1242         {
1243             if (log)
1244                 log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to resolve the address of hook function '%s' with symbol '%s'.",
1245                              hook_defn->name, symbol_name);
1246             continue;
1247         }
1248         else
1249         {
1250             if (log)
1251                 log->Printf("RenderScriptRuntime::LoadRuntimeHooks - Function %s, address resolved at 0x%" PRIx64, hook_defn->name, addr);
1252         }
1253 
1254         RuntimeHookSP hook(new RuntimeHook());
1255         hook->address = addr;
1256         hook->defn = hook_defn;
1257         hook->bp_sp = target.CreateBreakpoint(addr, true, false);
1258         hook->bp_sp->SetCallback(HookCallback, hook.get(), true);
1259         m_runtimeHooks[addr] = hook;
1260         if (log)
1261         {
1262             log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Successfully hooked '%s' in '%s' version %" PRIu64 " at 0x%" PRIx64 ".",
1263                 hook_defn->name, module->GetFileSpec().GetFilename().AsCString(), (uint64_t)hook_defn->version, (uint64_t)addr);
1264         }
1265     }
1266 }
1267 
1268 void
1269 RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp)
1270 {
1271     if (!rsmodule_sp)
1272         return;
1273 
1274     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1275 
1276     const ModuleSP module = rsmodule_sp->m_module;
1277     const FileSpec& file = module->GetPlatformFileSpec();
1278 
1279     // Iterate over all of the scripts that we currently know of.
1280     // Note: We cant push or pop to m_scripts here or it may invalidate rs_script.
1281     for (const auto & rs_script : m_scripts)
1282     {
1283         // Extract the expected .so file path for this script.
1284         std::string dylib;
1285         if (!rs_script->scriptDyLib.get(dylib))
1286             continue;
1287 
1288         // Only proceed if the module that has loaded corresponds to this script.
1289         if (file.GetFilename() != ConstString(dylib.c_str()))
1290             continue;
1291 
1292         // Obtain the script address which we use as a key.
1293         lldb::addr_t script;
1294         if (!rs_script->script.get(script))
1295             continue;
1296 
1297         // If we have a script mapping for the current script.
1298         if (m_scriptMappings.find(script) != m_scriptMappings.end())
1299         {
1300             // if the module we have stored is different to the one we just received.
1301             if (m_scriptMappings[script] != rsmodule_sp)
1302             {
1303                 if (log)
1304                     log->Printf ("RenderScriptRuntime::FixupScriptDetails - Error: script %" PRIx64 " wants reassigned to new rsmodule '%s'.",
1305                                     (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
1306             }
1307         }
1308         // We don't have a script mapping for the current script.
1309         else
1310         {
1311             // Obtain the script resource name.
1312             std::string resName;
1313             if (rs_script->resName.get(resName))
1314                 // Set the modules resource name.
1315                 rsmodule_sp->m_resname = resName;
1316             // Add Script/Module pair to map.
1317             m_scriptMappings[script] = rsmodule_sp;
1318             if (log)
1319                 log->Printf ("RenderScriptRuntime::FixupScriptDetails - script %" PRIx64 " associated with rsmodule '%s'.",
1320                                 (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
1321         }
1322     }
1323 }
1324 
1325 // Uses the Target API to evaluate the expression passed as a parameter to the function
1326 // The result of that expression is returned an unsigned 64 bit int, via the result* paramter.
1327 // Function returns true on success, and false on failure
1328 bool
1329 RenderScriptRuntime::EvalRSExpression(const char* expression, StackFrame* frame_ptr, uint64_t* result)
1330 {
1331     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1332     if (log)
1333         log->Printf("RenderScriptRuntime::EvalRSExpression(%s)", expression);
1334 
1335     ValueObjectSP expr_result;
1336     // Perform the actual expression evaluation
1337     GetProcess()->GetTarget().EvaluateExpression(expression, frame_ptr, expr_result);
1338 
1339     if (!expr_result)
1340     {
1341        if (log)
1342            log->Printf("RenderScriptRuntime::EvalRSExpression -  Error: Couldn't evaluate expression");
1343        return false;
1344     }
1345 
1346     // The result of the expression is invalid
1347     if (!expr_result->GetError().Success())
1348     {
1349         Error err = expr_result->GetError();
1350         if (err.GetError() == UserExpression::kNoResult) // Expression returned void, so this is actually a success
1351         {
1352             if (log)
1353                 log->Printf("RenderScriptRuntime::EvalRSExpression - Expression returned void");
1354 
1355             result = nullptr;
1356             return true;
1357         }
1358 
1359         if (log)
1360             log->Printf("RenderScriptRuntime::EvalRSExpression - Error evaluating expression result: %s", err.AsCString());
1361         return false;
1362     }
1363 
1364     bool success = false;
1365     *result = expr_result->GetValueAsUnsigned(0, &success); // We only read the result as an unsigned int.
1366 
1367     if (!success)
1368     {
1369        if (log)
1370            log->Printf("RenderScriptRuntime::EvalRSExpression -  Error: Couldn't convert expression result to unsigned int");
1371        return false;
1372     }
1373 
1374     return true;
1375 }
1376 
1377 namespace // anonymous
1378 {
1379     // max length of an expanded expression
1380     const int jit_max_expr_size = 768;
1381 
1382     // Format strings containing the expressions we may need to evaluate.
1383     const char runtimeExpressions[][256] =
1384     {
1385      // Mangled GetOffsetPointer(Allocation*, xoff, yoff, zoff, lod, cubemap)
1386      "(int*)_Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocationCubemapFace(0x%lx, %u, %u, %u, 0, 0)",
1387 
1388      // Type* rsaAllocationGetType(Context*, Allocation*)
1389      "(void*)rsaAllocationGetType(0x%lx, 0x%lx)",
1390 
1391      // rsaTypeGetNativeData(Context*, Type*, void* typeData, size)
1392      // Pack the data in the following way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ;
1393      // mHal.state.lodCount; mHal.state.faces; mElement; into typeData
1394      // Need to specify 32 or 64 bit for uint_t since this differs between devices
1395      "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[0]", // X dim
1396      "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[1]", // Y dim
1397      "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[2]", // Z dim
1398      "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[5]", // Element ptr
1399 
1400      // rsaElementGetNativeData(Context*, Element*, uint32_t* elemData,size)
1401      // Pack mType; mKind; mNormalized; mVectorSize; NumSubElements into elemData
1402      "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[0]", // Type
1403      "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[1]", // Kind
1404      "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[3]", // Vector Size
1405      "uint32_t data[5]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[4]", // Field Count
1406 
1407       // rsaElementGetSubElements(RsContext con, RsElement elem, uintptr_t *ids, const char **names,
1408       // size_t *arraySizes, uint32_t dataSize)
1409       // Needed for Allocations of structs to gather details about fields/Subelements
1410      "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
1411      "(void*)rsaElementGetSubElements(0x%lx, 0x%lx, ids, names, arr_size, %u); ids[%u]",     // Element* of field
1412 
1413      "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
1414      "(void*)rsaElementGetSubElements(0x%lx, 0x%lx, ids, names, arr_size, %u); names[%u]",   // Name of field
1415 
1416      "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
1417      "(void*)rsaElementGetSubElements(0x%lx, 0x%lx, ids, names, arr_size, %u); arr_size[%u]" // Array size of field
1418     };
1419 
1420 
1421     // Temporary workaround for MIPS, until the compiler emits the JAL instruction when invoking directly the function.
1422     // At the moment, when evaluating an expression involving a function call, the LLVM codegen for Mips  emits a JAL
1423     // instruction, which is able to jump in the range +/- 128MB with respect to the current program counter ($pc). If
1424     // the requested function happens to reside outside the above region, the function address will be truncated and the
1425     // function invocation will fail. This is a problem in the RS plugin as we rely on the RS API to probe the number and
1426     // the nature of allocations. A proper solution in the MIPS compiler is currently being investigated. As temporary
1427     // work around for this context, we'll invoke the RS API through function pointers, which cause the compiler to emit a
1428     // register based JALR instruction.
1429     const char runtimeExpressions_mips[][512] =
1430     {
1431     // Mangled GetOffsetPointer(Allocation*, xoff, yoff, zoff, lod, cubemap)
1432     "int* (*f) (void*, int, int, int, int, int) = (int* (*) (void*, int, int, int, int, int)) "
1433         "_Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocationCubemapFace; "
1434         "(int*) f((void*) 0x%lx, %u, %u, %u, 0, 0)",
1435 
1436     // Type* rsaAllocationGetType(Context*, Allocation*)
1437     "void* (*f) (void*, void*) = (void* (*) (void*, void*)) rsaAllocationGetType; (void*) f((void*) 0x%lx, (void*) 0x%lx)",
1438 
1439     // rsaTypeGetNativeData(Context*, Type*, void* typeData, size)
1440     // Pack the data in the following way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ;
1441     // mHal.state.lodCount; mHal.state.faces; mElement; into typeData
1442     // Need to specify 32 or 64 bit for uint_t since this differs between devices
1443     "uint%u_t data[6]; void* (*f)(void*, void*, uintptr_t*, uint32_t) = (void* (*)(void*, void*, uintptr_t*, uint32_t)) "
1444         "rsaTypeGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 6); data[0]",
1445     "uint%u_t data[6]; void* (*f)(void*, void*, uintptr_t*, uint32_t) = (void* (*)(void*, void*, uintptr_t*, uint32_t)) "
1446         "rsaTypeGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 6); data[1]",
1447     "uint%u_t data[6]; void* (*f)(void*, void*, uintptr_t*, uint32_t) = (void* (*)(void*, void*, uintptr_t*, uint32_t)) "
1448         "rsaTypeGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 6); data[2]",
1449     "uint%u_t data[6]; void* (*f)(void*, void*, uintptr_t*, uint32_t) = (void* (*)(void*, void*, uintptr_t*, uint32_t)) "
1450         "rsaTypeGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 6); data[5]",
1451 
1452     // rsaElementGetNativeData(Context*, Element*, uint32_t* elemData,size)
1453     // Pack mType; mKind; mNormalized; mVectorSize; NumSubElements into elemData
1454     "uint32_t data[5]; void* (*f)(void*, void*, uint32_t*, uint32_t) = (void* (*)(void*, void*, uint32_t*, uint32_t)) "
1455         "rsaElementGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 5); data[0]", // Type
1456     "uint32_t data[5]; void* (*f)(void*, void*, uint32_t*, uint32_t) = (void* (*)(void*, void*, uint32_t*, uint32_t)) "
1457         "rsaElementGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 5); data[1]", // Kind
1458     "uint32_t data[5]; void* (*f)(void*, void*, uint32_t*, uint32_t) = (void* (*)(void*, void*, uint32_t*, uint32_t)) "
1459         "rsaElementGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 5); data[3]", // Vector size
1460     "uint32_t data[5]; void* (*f)(void*, void*, uint32_t*, uint32_t) = (void* (*)(void*, void*, uint32_t*, uint32_t)) "
1461         "rsaElementGetNativeData; (void*) f((void*) 0x%lx, (void*) 0x%lx, data, 5); data[4]", // Field count
1462 
1463     // rsaElementGetSubElements(RsContext con, RsElement elem, uintptr_t *ids, const char **names,
1464     // size_t *arraySizes, uint32_t dataSize)
1465     // Needed for Allocations of structs to gather details about fields/Subelements
1466    "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
1467         "void* (*f) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t) = "
1468         "(void* (*) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t)) rsaElementGetSubElements;"
1469         "(void*) f((void*) 0x%lx, (void*) 0x%lx, (uintptr_t*) ids, names, arr_size, (uint32_t) %u);"
1470         "ids[%u]", // Element* of field
1471    "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
1472         "void* (*f) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t) = "
1473         "(void* (*) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t)) rsaElementGetSubElements;"
1474         "(void*) f((void*) 0x%lx, (void*) 0x%lx, (uintptr_t*) ids, names, arr_size, (uint32_t) %u);"
1475         "names[%u]", // Name of field
1476    "void* ids[%u]; const char* names[%u]; size_t arr_size[%u];"
1477         "void* (*f) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t) = "
1478         "(void* (*) (void*, void*, uintptr_t*, const char**, size_t*, uint32_t)) rsaElementGetSubElements;"
1479         "(void*) f((void*) 0x%lx, (void*) 0x%lx, (uintptr_t*) ids, names, arr_size, (uint32_t) %u);"
1480         "arr_size[%u]" // Array size of field
1481     };
1482 
1483 } // end of the anonymous namespace
1484 
1485 
1486 // Retrieve the string to JIT for the given expression
1487 const char*
1488 RenderScriptRuntime::JITTemplate(ExpressionStrings e)
1489 {
1490     // be nice to your Mips friend when adding new expression strings
1491     static_assert(sizeof(runtimeExpressions)/sizeof(runtimeExpressions[0]) ==
1492             sizeof(runtimeExpressions_mips)/sizeof(runtimeExpressions_mips[0]),
1493             "#runtimeExpressions != #runtimeExpressions_mips");
1494 
1495     assert((e >= eExprGetOffsetPtr && e <= eExprSubelementsArrSize) &&
1496            "Expression string out of bounds");
1497 
1498     llvm::Triple::ArchType arch = GetTargetRef().GetArchitecture().GetMachine();
1499 
1500     // mips JAL workaround
1501     if(arch == llvm::Triple::ArchType::mips64el || arch == llvm::Triple::ArchType::mipsel)
1502         return runtimeExpressions_mips[e];
1503     else
1504         return runtimeExpressions[e];
1505 }
1506 
1507 
1508 // JITs the RS runtime for the internal data pointer of an allocation.
1509 // Is passed x,y,z coordinates for the pointer to a specific element.
1510 // Then sets the data_ptr member in Allocation with the result.
1511 // Returns true on success, false otherwise
1512 bool
1513 RenderScriptRuntime::JITDataPointer(AllocationDetails* allocation, StackFrame* frame_ptr,
1514                                     unsigned int x, unsigned int y, unsigned int z)
1515 {
1516     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1517 
1518     if (!allocation->address.isValid())
1519     {
1520         if (log)
1521             log->Printf("RenderScriptRuntime::JITDataPointer - Failed to find allocation details");
1522         return false;
1523     }
1524 
1525     const char* expr_cstr = JITTemplate(eExprGetOffsetPtr);
1526     char buffer[jit_max_expr_size];
1527 
1528     int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->address.get(), x, y, z);
1529     if (chars_written < 0)
1530     {
1531         if (log)
1532             log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
1533         return false;
1534     }
1535     else if (chars_written >= jit_max_expr_size)
1536     {
1537         if (log)
1538             log->Printf("RenderScriptRuntime::JITDataPointer - Expression too long");
1539         return false;
1540     }
1541 
1542     uint64_t result = 0;
1543     if (!EvalRSExpression(buffer, frame_ptr, &result))
1544         return false;
1545 
1546     addr_t mem_ptr = static_cast<lldb::addr_t>(result);
1547     allocation->data_ptr = mem_ptr;
1548 
1549     return true;
1550 }
1551 
1552 // JITs the RS runtime for the internal pointer to the RS Type of an allocation
1553 // Then sets the type_ptr member in Allocation with the result.
1554 // Returns true on success, false otherwise
1555 bool
1556 RenderScriptRuntime::JITTypePointer(AllocationDetails* allocation, StackFrame* frame_ptr)
1557 {
1558     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1559 
1560     if (!allocation->address.isValid() || !allocation->context.isValid())
1561     {
1562         if (log)
1563             log->Printf("RenderScriptRuntime::JITTypePointer - Failed to find allocation details");
1564         return false;
1565     }
1566 
1567     const char* expr_cstr = JITTemplate(eExprAllocGetType);
1568     char buffer[jit_max_expr_size];
1569 
1570     int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->context.get(), *allocation->address.get());
1571     if (chars_written < 0)
1572     {
1573         if (log)
1574             log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
1575         return false;
1576     }
1577     else if (chars_written >= jit_max_expr_size)
1578     {
1579         if (log)
1580             log->Printf("RenderScriptRuntime::JITTypePointer - Expression too long");
1581         return false;
1582     }
1583 
1584     uint64_t result = 0;
1585     if (!EvalRSExpression(buffer, frame_ptr, &result))
1586         return false;
1587 
1588     addr_t type_ptr = static_cast<lldb::addr_t>(result);
1589     allocation->type_ptr = type_ptr;
1590 
1591     return true;
1592 }
1593 
1594 // JITs the RS runtime for information about the dimensions and type of an allocation
1595 // Then sets dimension and element_ptr members in Allocation with the result.
1596 // Returns true on success, false otherwise
1597 bool
1598 RenderScriptRuntime::JITTypePacked(AllocationDetails* allocation, StackFrame* frame_ptr)
1599 {
1600     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1601 
1602     if (!allocation->type_ptr.isValid() || !allocation->context.isValid())
1603     {
1604         if (log)
1605             log->Printf("RenderScriptRuntime::JITTypePacked - Failed to find allocation details");
1606         return false;
1607     }
1608 
1609     // Expression is different depending on if device is 32 or 64 bit
1610     uint32_t archByteSize = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
1611     const unsigned int bits = archByteSize == 4 ? 32 : 64;
1612 
1613     // We want 4 elements from packed data
1614     const unsigned int num_exprs = 4;
1615     assert(num_exprs == (eExprTypeElemPtr - eExprTypeDimX + 1) && "Invalid number of expressions");
1616 
1617     char buffer[num_exprs][jit_max_expr_size];
1618     uint64_t results[num_exprs];
1619 
1620     for (unsigned int i = 0; i < num_exprs; ++i)
1621     {
1622         const char* expr_cstr = JITTemplate((ExpressionStrings) (eExprTypeDimX + i));
1623         int chars_written = snprintf(buffer[i], jit_max_expr_size, expr_cstr, bits,
1624                                      *allocation->context.get(), *allocation->type_ptr.get());
1625         if (chars_written < 0)
1626         {
1627             if (log)
1628                 log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
1629             return false;
1630         }
1631         else if (chars_written >= jit_max_expr_size)
1632         {
1633             if (log)
1634                 log->Printf("RenderScriptRuntime::JITTypePacked - Expression too long");
1635             return false;
1636         }
1637 
1638         // Perform expression evaluation
1639         if (!EvalRSExpression(buffer[i], frame_ptr, &results[i]))
1640             return false;
1641     }
1642 
1643     // Assign results to allocation members
1644     AllocationDetails::Dimension dims;
1645     dims.dim_1 = static_cast<uint32_t>(results[0]);
1646     dims.dim_2 = static_cast<uint32_t>(results[1]);
1647     dims.dim_3 = static_cast<uint32_t>(results[2]);
1648     allocation->dimension = dims;
1649 
1650     addr_t elem_ptr = static_cast<lldb::addr_t>(results[3]);
1651     allocation->element.element_ptr = elem_ptr;
1652 
1653     if (log)
1654         log->Printf("RenderScriptRuntime::JITTypePacked - dims (%u, %u, %u) Element*: 0x%" PRIx64,
1655                     dims.dim_1, dims.dim_2, dims.dim_3, elem_ptr);
1656 
1657     return true;
1658 }
1659 
1660 // JITs the RS runtime for information about the Element of an allocation
1661 // Then sets type, type_vec_size, field_count and type_kind members in Element with the result.
1662 // Returns true on success, false otherwise
1663 bool
1664 RenderScriptRuntime::JITElementPacked(Element& elem, const lldb::addr_t context, StackFrame* frame_ptr)
1665 {
1666     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1667 
1668     if (!elem.element_ptr.isValid())
1669     {
1670         if (log)
1671             log->Printf("RenderScriptRuntime::JITElementPacked - Failed to find allocation details");
1672         return false;
1673     }
1674 
1675     // We want 4 elements from packed data
1676     const unsigned int num_exprs = 4;
1677     assert(num_exprs == (eExprElementFieldCount - eExprElementType + 1) && "Invalid number of expressions");
1678 
1679     char buffer[num_exprs][jit_max_expr_size];
1680     uint64_t results[num_exprs];
1681 
1682     for (unsigned int i = 0; i < num_exprs; i++)
1683     {
1684         const char* expr_cstr = JITTemplate((ExpressionStrings) (eExprElementType + i));
1685         int chars_written = snprintf(buffer[i], jit_max_expr_size, expr_cstr, context, *elem.element_ptr.get());
1686         if (chars_written < 0)
1687         {
1688             if (log)
1689                 log->Printf("RenderScriptRuntime::JITElementPacked - Encoding error in snprintf()");
1690             return false;
1691         }
1692         else if (chars_written >= jit_max_expr_size)
1693         {
1694             if (log)
1695                 log->Printf("RenderScriptRuntime::JITElementPacked - Expression too long");
1696             return false;
1697         }
1698 
1699         // Perform expression evaluation
1700         if (!EvalRSExpression(buffer[i], frame_ptr, &results[i]))
1701             return false;
1702     }
1703 
1704     // Assign results to allocation members
1705     elem.type = static_cast<RenderScriptRuntime::Element::DataType>(results[0]);
1706     elem.type_kind = static_cast<RenderScriptRuntime::Element::DataKind>(results[1]);
1707     elem.type_vec_size = static_cast<uint32_t>(results[2]);
1708     elem.field_count = static_cast<uint32_t>(results[3]);
1709 
1710     if (log)
1711         log->Printf("RenderScriptRuntime::JITElementPacked - data type %u, pixel type %u, vector size %u, field count %u",
1712                     *elem.type.get(), *elem.type_kind.get(), *elem.type_vec_size.get(), *elem.field_count.get());
1713 
1714     // If this Element has subelements then JIT rsaElementGetSubElements() for details about its fields
1715     if (*elem.field_count.get() > 0 && !JITSubelements(elem, context, frame_ptr))
1716         return false;
1717 
1718     return true;
1719 }
1720 
1721 // JITs the RS runtime for information about the subelements/fields of a struct allocation
1722 // This is necessary for infering the struct type so we can pretty print the allocation's contents.
1723 // Returns true on success, false otherwise
1724 bool
1725 RenderScriptRuntime::JITSubelements(Element& elem, const lldb::addr_t context, StackFrame* frame_ptr)
1726 {
1727     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1728 
1729     if (!elem.element_ptr.isValid() || !elem.field_count.isValid())
1730     {
1731         if (log)
1732             log->Printf("RenderScriptRuntime::JITSubelements - Failed to find allocation details");
1733         return false;
1734     }
1735 
1736     const short num_exprs = 3;
1737     assert(num_exprs == (eExprSubelementsArrSize - eExprSubelementsId + 1) && "Invalid number of expressions");
1738 
1739     char expr_buffer[jit_max_expr_size];
1740     uint64_t results;
1741 
1742     // Iterate over struct fields.
1743     const uint32_t field_count = *elem.field_count.get();
1744     for (unsigned int field_index = 0; field_index < field_count; ++field_index)
1745     {
1746         Element child;
1747         for (unsigned int expr_index = 0; expr_index < num_exprs; ++expr_index)
1748         {
1749             const char* expr_cstr = JITTemplate((ExpressionStrings) (eExprSubelementsId + expr_index));
1750             int chars_written = snprintf(expr_buffer, jit_max_expr_size, expr_cstr,
1751                                          field_count, field_count, field_count,
1752                                          context, *elem.element_ptr.get(), field_count, field_index);
1753             if (chars_written < 0)
1754             {
1755                 if (log)
1756                     log->Printf("RenderScriptRuntime::JITSubelements - Encoding error in snprintf()");
1757                 return false;
1758             }
1759             else if (chars_written >= jit_max_expr_size)
1760             {
1761                 if (log)
1762                     log->Printf("RenderScriptRuntime::JITSubelements - Expression too long");
1763                 return false;
1764             }
1765 
1766             // Perform expression evaluation
1767             if (!EvalRSExpression(expr_buffer, frame_ptr, &results))
1768                 return false;
1769 
1770             if (log)
1771                 log->Printf("RenderScriptRuntime::JITSubelements - Expr result 0x%" PRIx64, results);
1772 
1773             switch(expr_index)
1774             {
1775                 case 0: // Element* of child
1776                     child.element_ptr = static_cast<addr_t>(results);
1777                     break;
1778                 case 1: // Name of child
1779                 {
1780                     lldb::addr_t address = static_cast<addr_t>(results);
1781                     Error err;
1782                     std::string name;
1783                     GetProcess()->ReadCStringFromMemory(address, name, err);
1784                     if (!err.Fail())
1785                         child.type_name = ConstString(name);
1786                     else
1787                     {
1788                         if (log)
1789                             log->Printf("RenderScriptRuntime::JITSubelements - Warning: Couldn't read field name");
1790                     }
1791                     break;
1792                 }
1793                 case 2: // Array size of child
1794                     child.array_size = static_cast<uint32_t>(results);
1795                     break;
1796             }
1797         }
1798 
1799         // We need to recursively JIT each Element field of the struct since
1800         // structs can be nested inside structs.
1801         if (!JITElementPacked(child, context, frame_ptr))
1802             return false;
1803         elem.children.push_back(child);
1804     }
1805 
1806     // Try to infer the name of the struct type so we can pretty print the allocation contents.
1807     FindStructTypeName(elem, frame_ptr);
1808 
1809     return true;
1810 }
1811 
1812 // JITs the RS runtime for the address of the last element in the allocation.
1813 // The `elem_size` paramter represents the size of a single element, including padding.
1814 // Which is needed as an offset from the last element pointer.
1815 // Using this offset minus the starting address we can calculate the size of the allocation.
1816 // Returns true on success, false otherwise
1817 bool
1818 RenderScriptRuntime::JITAllocationSize(AllocationDetails* allocation, StackFrame* frame_ptr)
1819 {
1820     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1821 
1822     if (!allocation->address.isValid() || !allocation->dimension.isValid()
1823         || !allocation->data_ptr.isValid() || !allocation->element.datum_size.isValid())
1824     {
1825         if (log)
1826             log->Printf("RenderScriptRuntime::JITAllocationSize - Failed to find allocation details");
1827         return false;
1828     }
1829 
1830     // Find dimensions
1831     unsigned int dim_x = allocation->dimension.get()->dim_1;
1832     unsigned int dim_y = allocation->dimension.get()->dim_2;
1833     unsigned int dim_z = allocation->dimension.get()->dim_3;
1834 
1835     // Our plan of jitting the last element address doesn't seem to work for struct Allocations
1836     // Instead try to infer the size ourselves without any inter element padding.
1837     if (allocation->element.children.size() > 0)
1838     {
1839         if (dim_x == 0) dim_x = 1;
1840         if (dim_y == 0) dim_y = 1;
1841         if (dim_z == 0) dim_z = 1;
1842 
1843         allocation->size = dim_x * dim_y * dim_z * *allocation->element.datum_size.get();
1844 
1845         if (log)
1846             log->Printf("RenderScriptRuntime::JITAllocationSize - Infered size of struct allocation %u", *allocation->size.get());
1847 
1848         return true;
1849     }
1850 
1851     const char* expr_cstr = JITTemplate(eExprGetOffsetPtr);
1852     char buffer[jit_max_expr_size];
1853 
1854     // Calculate last element
1855     dim_x = dim_x == 0 ? 0 : dim_x - 1;
1856     dim_y = dim_y == 0 ? 0 : dim_y - 1;
1857     dim_z = dim_z == 0 ? 0 : dim_z - 1;
1858 
1859     int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->address.get(),
1860                                  dim_x, dim_y, dim_z);
1861     if (chars_written < 0)
1862     {
1863         if (log)
1864             log->Printf("RenderScriptRuntime::JITAllocationSize - Encoding error in snprintf()");
1865         return false;
1866     }
1867     else if (chars_written >= jit_max_expr_size)
1868     {
1869         if (log)
1870             log->Printf("RenderScriptRuntime::JITAllocationSize - Expression too long");
1871         return false;
1872     }
1873 
1874     uint64_t result = 0;
1875     if (!EvalRSExpression(buffer, frame_ptr, &result))
1876         return false;
1877 
1878     addr_t mem_ptr = static_cast<lldb::addr_t>(result);
1879     // Find pointer to last element and add on size of an element
1880     allocation->size = static_cast<uint32_t>(mem_ptr - *allocation->data_ptr.get()) + *allocation->element.datum_size.get();
1881 
1882     return true;
1883 }
1884 
1885 // JITs the RS runtime for information about the stride between rows in the allocation.
1886 // This is done to detect padding, since allocated memory is 16-byte aligned.
1887 // Returns true on success, false otherwise
1888 bool
1889 RenderScriptRuntime::JITAllocationStride(AllocationDetails* allocation, StackFrame* frame_ptr)
1890 {
1891     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1892 
1893     if (!allocation->address.isValid() || !allocation->data_ptr.isValid())
1894     {
1895         if (log)
1896             log->Printf("RenderScriptRuntime::JITAllocationStride - Failed to find allocation details");
1897         return false;
1898     }
1899 
1900     const char* expr_cstr = JITTemplate(eExprGetOffsetPtr);
1901     char buffer[jit_max_expr_size];
1902 
1903     int chars_written = snprintf(buffer, jit_max_expr_size, expr_cstr, *allocation->address.get(),
1904                                  0, 1, 0);
1905     if (chars_written < 0)
1906     {
1907         if (log)
1908             log->Printf("RenderScriptRuntime::JITAllocationStride - Encoding error in snprintf()");
1909         return false;
1910     }
1911     else if (chars_written >= jit_max_expr_size)
1912     {
1913         if (log)
1914             log->Printf("RenderScriptRuntime::JITAllocationStride - Expression too long");
1915         return false;
1916     }
1917 
1918     uint64_t result = 0;
1919     if (!EvalRSExpression(buffer, frame_ptr, &result))
1920         return false;
1921 
1922     addr_t mem_ptr = static_cast<lldb::addr_t>(result);
1923     allocation->stride = static_cast<uint32_t>(mem_ptr - *allocation->data_ptr.get());
1924 
1925     return true;
1926 }
1927 
1928 // JIT all the current runtime info regarding an allocation
1929 bool
1930 RenderScriptRuntime::RefreshAllocation(AllocationDetails* allocation, StackFrame* frame_ptr)
1931 {
1932     // GetOffsetPointer()
1933     if (!JITDataPointer(allocation, frame_ptr))
1934         return false;
1935 
1936     // rsaAllocationGetType()
1937     if (!JITTypePointer(allocation, frame_ptr))
1938         return false;
1939 
1940     // rsaTypeGetNativeData()
1941     if (!JITTypePacked(allocation, frame_ptr))
1942         return false;
1943 
1944     // rsaElementGetNativeData()
1945     if (!JITElementPacked(allocation->element, *allocation->context.get(), frame_ptr))
1946         return false;
1947 
1948     // Sets the datum_size member in Element
1949     SetElementSize(allocation->element);
1950 
1951     // Use GetOffsetPointer() to infer size of the allocation
1952     if (!JITAllocationSize(allocation, frame_ptr))
1953         return false;
1954 
1955     return true;
1956 }
1957 
1958 // Function attempts to set the type_name member of the paramaterised Element object.
1959 // This string should be the name of the struct type the Element represents.
1960 // We need this string for pretty printing the Element to users.
1961 void
1962 RenderScriptRuntime::FindStructTypeName(Element& elem, StackFrame* frame_ptr)
1963 {
1964     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1965 
1966     if (!elem.type_name.IsEmpty()) // Name already set
1967         return;
1968     else
1969         elem.type_name = Element::GetFallbackStructName(); // Default type name if we don't succeed
1970 
1971     // Find all the global variables from the script rs modules
1972     VariableList variable_list;
1973     for (auto module_sp : m_rsmodules)
1974         module_sp->m_module->FindGlobalVariables(RegularExpression("."), true, UINT32_MAX, variable_list);
1975 
1976     // Iterate over all the global variables looking for one with a matching type to the Element.
1977     // We make the assumption a match exists since there needs to be a global variable to reflect the
1978     // struct type back into java host code.
1979     for (uint32_t var_index = 0; var_index < variable_list.GetSize(); ++var_index)
1980     {
1981         const VariableSP var_sp(variable_list.GetVariableAtIndex(var_index));
1982         if (!var_sp)
1983            continue;
1984 
1985         ValueObjectSP valobj_sp = ValueObjectVariable::Create(frame_ptr, var_sp);
1986         if (!valobj_sp)
1987             continue;
1988 
1989         // Find the number of variable fields.
1990         // If it has no fields, or more fields than our Element, then it can't be the struct we're looking for.
1991         // Don't check for equality since RS can add extra struct members for padding.
1992         size_t num_children = valobj_sp->GetNumChildren();
1993         if (num_children > elem.children.size() || num_children == 0)
1994             continue;
1995 
1996         // Iterate over children looking for members with matching field names.
1997         // If all the field names match, this is likely the struct we want.
1998         //
1999         //   TODO: This could be made more robust by also checking children data sizes, or array size
2000         bool found = true;
2001         for (size_t child_index = 0; child_index < num_children; ++child_index)
2002         {
2003             ValueObjectSP child = valobj_sp->GetChildAtIndex(child_index, true);
2004             if (!child || (child->GetName() != elem.children[child_index].type_name))
2005             {
2006                 found = false;
2007                 break;
2008             }
2009         }
2010 
2011         // RS can add extra struct members for padding in the format '#rs_padding_[0-9]+'
2012         if (found && num_children < elem.children.size())
2013         {
2014             const unsigned int size_diff = elem.children.size() - num_children;
2015             if (log)
2016                 log->Printf("RenderScriptRuntime::FindStructTypeName - %u padding struct entries", size_diff);
2017 
2018             for (unsigned int padding_index = 0; padding_index < size_diff; ++padding_index)
2019             {
2020                 const ConstString& name = elem.children[num_children + padding_index].type_name;
2021                 if (strcmp(name.AsCString(), "#rs_padding") < 0)
2022                     found = false;
2023             }
2024         }
2025 
2026         // We've found a global var with matching type
2027         if (found)
2028         {
2029             // Dereference since our Element type isn't a pointer.
2030             if (valobj_sp->IsPointerType())
2031             {
2032                 Error err;
2033                 ValueObjectSP deref_valobj = valobj_sp->Dereference(err);
2034                 if (!err.Fail())
2035                     valobj_sp = deref_valobj;
2036             }
2037 
2038             // Save name of variable in Element.
2039             elem.type_name = valobj_sp->GetTypeName();
2040             if (log)
2041                 log->Printf("RenderScriptRuntime::FindStructTypeName - Element name set to %s", elem.type_name.AsCString());
2042 
2043             return;
2044         }
2045     }
2046 }
2047 
2048 // Function sets the datum_size member of Element. Representing the size of a single instance including padding.
2049 // Assumes the relevant allocation information has already been jitted.
2050 void
2051 RenderScriptRuntime::SetElementSize(Element& elem)
2052 {
2053     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
2054     const Element::DataType type = *elem.type.get();
2055     assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT
2056                                                    && "Invalid allocation type");
2057 
2058     const unsigned int vec_size = *elem.type_vec_size.get();
2059     unsigned int data_size = 0;
2060     unsigned int padding = 0;
2061 
2062     // Element is of a struct type, calculate size recursively.
2063     if ((type == Element::RS_TYPE_NONE) && (elem.children.size() > 0))
2064     {
2065         for (Element& child : elem.children)
2066         {
2067             SetElementSize(child);
2068             const unsigned int array_size = child.array_size.isValid() ? *child.array_size.get() : 1;
2069             data_size += *child.datum_size.get() * array_size;
2070         }
2071     }
2072     else if (type == Element::RS_TYPE_UNSIGNED_5_6_5 || type == Element::RS_TYPE_UNSIGNED_5_5_5_1 ||
2073              type == Element::RS_TYPE_UNSIGNED_4_4_4_4) // These have been packed already
2074     {
2075         data_size = AllocationDetails::RSTypeToFormat[type][eElementSize];
2076     }
2077     else if (type < Element::RS_TYPE_ELEMENT)
2078     {
2079         data_size = vec_size * AllocationDetails::RSTypeToFormat[type][eElementSize];
2080         if (vec_size == 3)
2081             padding = AllocationDetails::RSTypeToFormat[type][eElementSize];
2082     }
2083     else
2084         data_size = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
2085 
2086     elem.padding = padding;
2087     elem.datum_size = data_size + padding;
2088     if (log)
2089         log->Printf("RenderScriptRuntime::SetElementSize - element size set to %u", data_size + padding);
2090 }
2091 
2092 // Given an allocation, this function copies the allocation contents from device into a buffer on the heap.
2093 // Returning a shared pointer to the buffer containing the data.
2094 std::shared_ptr<uint8_t>
2095 RenderScriptRuntime::GetAllocationData(AllocationDetails* allocation, StackFrame* frame_ptr)
2096 {
2097     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
2098 
2099     // JIT all the allocation details
2100     if (allocation->shouldRefresh())
2101     {
2102         if (log)
2103             log->Printf("RenderScriptRuntime::GetAllocationData - Allocation details not calculated yet, jitting info");
2104 
2105         if (!RefreshAllocation(allocation, frame_ptr))
2106         {
2107             if (log)
2108                 log->Printf("RenderScriptRuntime::GetAllocationData - Couldn't JIT allocation details");
2109             return nullptr;
2110         }
2111     }
2112 
2113     assert(allocation->data_ptr.isValid() && allocation->element.type.isValid() && allocation->element.type_vec_size.isValid()
2114            && allocation->size.isValid() && "Allocation information not available");
2115 
2116     // Allocate a buffer to copy data into
2117     const unsigned int size = *allocation->size.get();
2118     std::shared_ptr<uint8_t> buffer(new uint8_t[size]);
2119     if (!buffer)
2120     {
2121         if (log)
2122             log->Printf("RenderScriptRuntime::GetAllocationData - Couldn't allocate a %u byte buffer", size);
2123         return nullptr;
2124     }
2125 
2126     // Read the inferior memory
2127     Error error;
2128     lldb::addr_t data_ptr = *allocation->data_ptr.get();
2129     GetProcess()->ReadMemory(data_ptr, buffer.get(), size, error);
2130     if (error.Fail())
2131     {
2132         if (log)
2133             log->Printf("RenderScriptRuntime::GetAllocationData - '%s' Couldn't read %u bytes of allocation data from 0x%" PRIx64,
2134                         error.AsCString(), size, data_ptr);
2135         return nullptr;
2136     }
2137 
2138     return buffer;
2139 }
2140 
2141 // Function copies data from a binary file into an allocation.
2142 // There is a header at the start of the file, FileHeader, before the data content itself.
2143 // Information from this header is used to display warnings to the user about incompatabilities
2144 bool
2145 RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr)
2146 {
2147     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
2148 
2149     // Find allocation with the given id
2150     AllocationDetails* alloc = FindAllocByID(strm, alloc_id);
2151     if (!alloc)
2152         return false;
2153 
2154     if (log)
2155         log->Printf("RenderScriptRuntime::LoadAllocation - Found allocation 0x%" PRIx64, *alloc->address.get());
2156 
2157     // JIT all the allocation details
2158     if (alloc->shouldRefresh())
2159     {
2160         if (log)
2161             log->Printf("RenderScriptRuntime::LoadAllocation - Allocation details not calculated yet, jitting info");
2162 
2163         if (!RefreshAllocation(alloc, frame_ptr))
2164         {
2165             if (log)
2166                 log->Printf("RenderScriptRuntime::LoadAllocation - Couldn't JIT allocation details");
2167             return false;
2168         }
2169     }
2170 
2171     assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() && alloc->element.type_vec_size.isValid()
2172            && alloc->size.isValid() && alloc->element.datum_size.isValid() && "Allocation information not available");
2173 
2174     // Check we can read from file
2175     FileSpec file(filename, true);
2176     if (!file.Exists())
2177     {
2178         strm.Printf("Error: File %s does not exist", filename);
2179         strm.EOL();
2180         return false;
2181     }
2182 
2183     if (!file.Readable())
2184     {
2185         strm.Printf("Error: File %s does not have readable permissions", filename);
2186         strm.EOL();
2187         return false;
2188     }
2189 
2190     // Read file into data buffer
2191     DataBufferSP data_sp(file.ReadFileContents());
2192 
2193     // Cast start of buffer to FileHeader and use pointer to read metadata
2194     void* file_buffer = data_sp->GetBytes();
2195     if (file_buffer == NULL || data_sp->GetByteSize() <
2196         (sizeof(AllocationDetails::FileHeader) + sizeof(AllocationDetails::ElementHeader)))
2197     {
2198         strm.Printf("Error: File %s does not contain enough data for header", filename);
2199         strm.EOL();
2200         return false;
2201     }
2202     const AllocationDetails::FileHeader* file_header = static_cast<AllocationDetails::FileHeader*>(file_buffer);
2203 
2204     // Check file starts with ascii characters "RSAD"
2205     if (file_header->ident[0] != 'R' || file_header->ident[1] != 'S' || file_header->ident[2] != 'A'
2206         || file_header->ident[3] != 'D')
2207     {
2208         strm.Printf("Error: File doesn't contain identifier for an RS allocation dump. Are you sure this is the correct file?");
2209         strm.EOL();
2210         return false;
2211     }
2212 
2213     // Look at the type of the root element in the header
2214     AllocationDetails::ElementHeader root_element_header;
2215     memcpy(&root_element_header, static_cast<uint8_t*>(file_buffer) + sizeof(AllocationDetails::FileHeader),
2216            sizeof(AllocationDetails::ElementHeader));
2217 
2218     if (log)
2219         log->Printf("RenderScriptRuntime::LoadAllocation - header type %u, element size %u",
2220                     root_element_header.type, root_element_header.element_size);
2221 
2222     // Check if the target allocation and file both have the same number of bytes for an Element
2223     if (*alloc->element.datum_size.get() != root_element_header.element_size)
2224     {
2225         strm.Printf("Warning: Mismatched Element sizes - file %u bytes, allocation %u bytes",
2226                     root_element_header.element_size, *alloc->element.datum_size.get());
2227         strm.EOL();
2228     }
2229 
2230     // Check if the target allocation and file both have the same type
2231     const unsigned int alloc_type = static_cast<unsigned int>(*alloc->element.type.get());
2232     const unsigned int file_type = root_element_header.type;
2233 
2234     if (file_type > Element::RS_TYPE_FONT)
2235     {
2236         strm.Printf("Warning: File has unknown allocation type");
2237         strm.EOL();
2238     }
2239     else if (alloc_type != file_type)
2240     {
2241         // Enum value isn't monotonous, so doesn't always index RsDataTypeToString array
2242         unsigned int printable_target_type_index = alloc_type;
2243         unsigned int printable_head_type_index = file_type;
2244         if (alloc_type >= Element::RS_TYPE_ELEMENT && alloc_type <= Element::RS_TYPE_FONT)
2245             printable_target_type_index = static_cast<Element::DataType>(
2246                                          (alloc_type - Element::RS_TYPE_ELEMENT) + Element::RS_TYPE_MATRIX_2X2 + 1);
2247 
2248         if (file_type >= Element::RS_TYPE_ELEMENT && file_type <= Element::RS_TYPE_FONT)
2249             printable_head_type_index = static_cast<Element::DataType>(
2250                                         (file_type - Element::RS_TYPE_ELEMENT) + Element::RS_TYPE_MATRIX_2X2 + 1);
2251 
2252         const char* file_type_cstr = AllocationDetails::RsDataTypeToString[printable_head_type_index][0];
2253         const char* target_type_cstr = AllocationDetails::RsDataTypeToString[printable_target_type_index][0];
2254 
2255         strm.Printf("Warning: Mismatched Types - file '%s' type, allocation '%s' type",
2256                     file_type_cstr, target_type_cstr);
2257         strm.EOL();
2258     }
2259 
2260     // Advance buffer past header
2261     file_buffer = static_cast<uint8_t*>(file_buffer) + file_header->hdr_size;
2262 
2263     // Calculate size of allocation data in file
2264     size_t length = data_sp->GetByteSize() - file_header->hdr_size;
2265 
2266     // Check if the target allocation and file both have the same total data size.
2267     const unsigned int alloc_size = *alloc->size.get();
2268     if (alloc_size != length)
2269     {
2270         strm.Printf("Warning: Mismatched allocation sizes - file 0x%" PRIx64 " bytes, allocation 0x%x bytes",
2271                     (uint64_t) length, alloc_size);
2272         strm.EOL();
2273         length = alloc_size < length ? alloc_size : length; // Set length to copy to minimum
2274     }
2275 
2276     // Copy file data from our buffer into the target allocation.
2277     lldb::addr_t alloc_data = *alloc->data_ptr.get();
2278     Error error;
2279     size_t bytes_written = GetProcess()->WriteMemory(alloc_data, file_buffer, length, error);
2280     if (!error.Success() || bytes_written != length)
2281     {
2282         strm.Printf("Error: Couldn't write data to allocation %s", error.AsCString());
2283         strm.EOL();
2284         return false;
2285     }
2286 
2287     strm.Printf("Contents of file '%s' read into allocation %u", filename, alloc->id);
2288     strm.EOL();
2289 
2290     return true;
2291 }
2292 
2293 // Function takes as parameters a byte buffer, which will eventually be written to file as the element header,
2294 // an offset into that buffer, and an Element that will be saved into the buffer at the parametrised offset.
2295 // Return value is the new offset after writing the element into the buffer.
2296 // Elements are saved to the file as the ElementHeader struct followed by offsets to the structs of all the element's children.
2297 size_t
2298 RenderScriptRuntime::PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer, size_t offset, const Element& elem)
2299 {
2300     // File struct for an element header with all the relevant details copied from elem.
2301     // We assume members are valid already.
2302     AllocationDetails::ElementHeader elem_header;
2303     elem_header.type = *elem.type.get();
2304     elem_header.kind = *elem.type_kind.get();
2305     elem_header.element_size = *elem.datum_size.get();
2306     elem_header.vector_size = *elem.type_vec_size.get();
2307     elem_header.array_size = elem.array_size.isValid() ? *elem.array_size.get() : 0;
2308     const size_t elem_header_size = sizeof(AllocationDetails::ElementHeader);
2309 
2310     // Copy struct into buffer and advance offset
2311     // We assume that header_buffer has been checked for NULL before this method is called
2312     memcpy(header_buffer.get() + offset, &elem_header, elem_header_size);
2313     offset += elem_header_size;
2314 
2315     // Starting offset of child ElementHeader struct
2316     size_t child_offset = offset + ((elem.children.size() + 1) * sizeof(uint32_t));
2317     for (const RenderScriptRuntime::Element& child : elem.children)
2318     {
2319         // Recursively populate the buffer with the element header structs of children.
2320         // Then save the offsets where they were set after the parent element header.
2321         memcpy(header_buffer.get() + offset, &child_offset, sizeof(uint32_t));
2322         offset += sizeof(uint32_t);
2323 
2324         child_offset = PopulateElementHeaders(header_buffer, child_offset, child);
2325     }
2326 
2327     // Zero indicates no more children
2328     memset(header_buffer.get() + offset, 0, sizeof(uint32_t));
2329 
2330     return child_offset;
2331 }
2332 
2333 // Given an Element object this function returns the total size needed in the file header to store the element's details.
2334 // Taking into account the size of the element header struct, plus the offsets to all the element's children.
2335 // Function is recursive so that the size of all ancestors is taken into account.
2336 size_t
2337 RenderScriptRuntime::CalculateElementHeaderSize(const Element& elem)
2338 {
2339     size_t size = (elem.children.size() + 1) * sizeof(uint32_t); // Offsets to children plus zero terminator
2340     size += sizeof(AllocationDetails::ElementHeader); // Size of header struct with type details
2341 
2342     // Calculate recursively for all descendants
2343     for (const Element& child : elem.children)
2344         size += CalculateElementHeaderSize(child);
2345 
2346     return size;
2347 }
2348 
2349 // Function copies allocation contents into a binary file.
2350 // This file can then be loaded later into a different allocation.
2351 // There is a header, FileHeader, before the allocation data containing meta-data.
2352 bool
2353 RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr)
2354 {
2355     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
2356 
2357     // Find allocation with the given id
2358     AllocationDetails* alloc = FindAllocByID(strm, alloc_id);
2359     if (!alloc)
2360         return false;
2361 
2362     if (log)
2363         log->Printf("RenderScriptRuntime::SaveAllocation - Found allocation 0x%" PRIx64, *alloc->address.get());
2364 
2365      // JIT all the allocation details
2366     if (alloc->shouldRefresh())
2367     {
2368         if (log)
2369             log->Printf("RenderScriptRuntime::SaveAllocation - Allocation details not calculated yet, jitting info");
2370 
2371         if (!RefreshAllocation(alloc, frame_ptr))
2372         {
2373             if (log)
2374                 log->Printf("RenderScriptRuntime::SaveAllocation - Couldn't JIT allocation details");
2375             return false;
2376         }
2377     }
2378 
2379     assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() && alloc->element.type_vec_size.isValid() && alloc->element.datum_size.get()
2380            && alloc->element.type_kind.isValid() && alloc->dimension.isValid() && "Allocation information not available");
2381 
2382     // Check we can create writable file
2383     FileSpec file_spec(filename, true);
2384     File file(file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate | File::eOpenOptionTruncate);
2385     if (!file)
2386     {
2387         strm.Printf("Error: Failed to open '%s' for writing", filename);
2388         strm.EOL();
2389         return false;
2390     }
2391 
2392     // Read allocation into buffer of heap memory
2393     const std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr);
2394     if (!buffer)
2395     {
2396         strm.Printf("Error: Couldn't read allocation data into buffer");
2397         strm.EOL();
2398         return false;
2399     }
2400 
2401     // Create the file header
2402     AllocationDetails::FileHeader head;
2403     head.ident[0] = 'R'; head.ident[1] = 'S'; head.ident[2] = 'A'; head.ident[3] = 'D';
2404     head.dims[0] = static_cast<uint32_t>(alloc->dimension.get()->dim_1);
2405     head.dims[1] = static_cast<uint32_t>(alloc->dimension.get()->dim_2);
2406     head.dims[2] = static_cast<uint32_t>(alloc->dimension.get()->dim_3);
2407 
2408     const size_t element_header_size = CalculateElementHeaderSize(alloc->element);
2409     assert((sizeof(AllocationDetails::FileHeader) + element_header_size) < UINT16_MAX && "Element header too large");
2410     head.hdr_size = static_cast<uint16_t>(sizeof(AllocationDetails::FileHeader) + element_header_size);
2411 
2412     // Write the file header
2413     size_t num_bytes = sizeof(AllocationDetails::FileHeader);
2414     if (log)
2415         log->Printf("RenderScriptRuntime::SaveAllocation - Writing File Header, 0x%zX bytes", num_bytes);
2416 
2417     Error err = file.Write(&head, num_bytes);
2418     if (!err.Success())
2419     {
2420         strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), filename);
2421         strm.EOL();
2422         return false;
2423     }
2424 
2425     // Create the headers describing the element type of the allocation.
2426     std::shared_ptr<uint8_t> element_header_buffer(new uint8_t[element_header_size]);
2427     if (element_header_buffer == nullptr)
2428     {
2429         strm.Printf("Internal Error: Couldn't allocate %zu bytes on the heap", element_header_size);
2430         strm.EOL();
2431         return false;
2432     }
2433 
2434     PopulateElementHeaders(element_header_buffer, 0, alloc->element);
2435 
2436     // Write headers for allocation element type to file
2437     num_bytes = element_header_size;
2438     if (log)
2439         log->Printf("RenderScriptRuntime::SaveAllocation - Writing Element Headers, 0x%zX bytes", num_bytes);
2440 
2441     err = file.Write(element_header_buffer.get(), num_bytes);
2442     if (!err.Success())
2443     {
2444         strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), filename);
2445         strm.EOL();
2446         return false;
2447     }
2448 
2449     // Write allocation data to file
2450     num_bytes = static_cast<size_t>(*alloc->size.get());
2451     if (log)
2452         log->Printf("RenderScriptRuntime::SaveAllocation - Writing 0x%zX bytes", num_bytes);
2453 
2454     err = file.Write(buffer.get(), num_bytes);
2455     if (!err.Success())
2456     {
2457         strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), filename);
2458         strm.EOL();
2459         return false;
2460     }
2461 
2462     strm.Printf("Allocation written to file '%s'", filename);
2463     strm.EOL();
2464     return true;
2465 }
2466 
2467 bool
2468 RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
2469 {
2470     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
2471 
2472     if (module_sp)
2473     {
2474         for (const auto &rs_module : m_rsmodules)
2475         {
2476             if (rs_module->m_module == module_sp)
2477             {
2478                 // Check if the user has enabled automatically breaking on
2479                 // all RS kernels.
2480                 if (m_breakAllKernels)
2481                     BreakOnModuleKernels(rs_module);
2482 
2483                 return false;
2484             }
2485         }
2486         bool module_loaded = false;
2487         switch (GetModuleKind(module_sp))
2488         {
2489             case eModuleKindKernelObj:
2490             {
2491                 RSModuleDescriptorSP module_desc;
2492                 module_desc.reset(new RSModuleDescriptor(module_sp));
2493                 if (module_desc->ParseRSInfo())
2494                 {
2495                     m_rsmodules.push_back(module_desc);
2496                     module_loaded = true;
2497                 }
2498                 if (module_loaded)
2499                 {
2500                     FixupScriptDetails(module_desc);
2501                 }
2502                 break;
2503             }
2504             case eModuleKindDriver:
2505             {
2506                 if (!m_libRSDriver)
2507                 {
2508                     m_libRSDriver = module_sp;
2509                     LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver);
2510                 }
2511                 break;
2512             }
2513             case eModuleKindImpl:
2514             {
2515                 m_libRSCpuRef = module_sp;
2516                 break;
2517             }
2518             case eModuleKindLibRS:
2519             {
2520                 if (!m_libRS)
2521                 {
2522                     m_libRS = module_sp;
2523                     static ConstString gDbgPresentStr("gDebuggerPresent");
2524                     const Symbol* debug_present = m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData);
2525                     if (debug_present)
2526                     {
2527                         Error error;
2528                         uint32_t flag = 0x00000001U;
2529                         Target &target = GetProcess()->GetTarget();
2530                         addr_t addr = debug_present->GetLoadAddress(&target);
2531                         GetProcess()->WriteMemory(addr, &flag, sizeof(flag), error);
2532                         if(error.Success())
2533                         {
2534                             if (log)
2535                                 log->Printf ("RenderScriptRuntime::LoadModule - Debugger present flag set on debugee");
2536 
2537                             m_debuggerPresentFlagged = true;
2538                         }
2539                         else if (log)
2540                         {
2541                             log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags '%s' ", error.AsCString());
2542                         }
2543                     }
2544                     else if (log)
2545                     {
2546                         log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags - symbol not found");
2547                     }
2548                 }
2549                 break;
2550             }
2551             default:
2552                 break;
2553         }
2554         if (module_loaded)
2555             Update();
2556         return module_loaded;
2557     }
2558     return false;
2559 }
2560 
2561 void
2562 RenderScriptRuntime::Update()
2563 {
2564     if (m_rsmodules.size() > 0)
2565     {
2566         if (!m_initiated)
2567         {
2568             Initiate();
2569         }
2570     }
2571 }
2572 
2573 // The maximum line length of an .rs.info packet
2574 #define MAXLINE 500
2575 
2576 // The .rs.info symbol in renderscript modules contains a string which needs to be parsed.
2577 // The string is basic and is parsed on a line by line basis.
2578 bool
2579 RSModuleDescriptor::ParseRSInfo()
2580 {
2581     const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
2582     if (info_sym)
2583     {
2584         const addr_t addr = info_sym->GetAddressRef().GetFileAddress();
2585         const addr_t size = info_sym->GetByteSize();
2586         const FileSpec fs = m_module->GetFileSpec();
2587 
2588         DataBufferSP buffer = fs.ReadFileContents(addr, size);
2589 
2590         if (!buffer)
2591             return false;
2592 
2593         std::string info((const char *)buffer->GetBytes());
2594 
2595         std::vector<std::string> info_lines;
2596         size_t lpos = info.find('\n');
2597         while (lpos != std::string::npos)
2598         {
2599             info_lines.push_back(info.substr(0, lpos));
2600             info = info.substr(lpos + 1);
2601             lpos = info.find('\n');
2602         }
2603         size_t offset = 0;
2604         while (offset < info_lines.size())
2605         {
2606             std::string line = info_lines[offset];
2607             // Parse directives
2608             uint32_t numDefns = 0;
2609             if (sscanf(line.c_str(), "exportVarCount: %u", &numDefns) == 1)
2610             {
2611                 while (numDefns--)
2612                     m_globals.push_back(RSGlobalDescriptor(this, info_lines[++offset].c_str()));
2613             }
2614             else if (sscanf(line.c_str(), "exportFuncCount: %u", &numDefns) == 1)
2615             {
2616             }
2617             else if (sscanf(line.c_str(), "exportForEachCount: %u", &numDefns) == 1)
2618             {
2619                 char name[MAXLINE];
2620                 while (numDefns--)
2621                 {
2622                     uint32_t slot = 0;
2623                     name[0] = '\0';
2624                     if (sscanf(info_lines[++offset].c_str(), "%u - %s", &slot, &name[0]) == 2)
2625                     {
2626                         m_kernels.push_back(RSKernelDescriptor(this, name, slot));
2627                     }
2628                 }
2629             }
2630             else if (sscanf(line.c_str(), "pragmaCount: %u", &numDefns) == 1)
2631             {
2632                 char name[MAXLINE];
2633                 char value[MAXLINE];
2634                 while (numDefns--)
2635                 {
2636                     name[0] = '\0';
2637                     value[0] = '\0';
2638                     if (sscanf(info_lines[++offset].c_str(), "%s - %s", &name[0], &value[0]) != 0
2639                         && (name[0] != '\0'))
2640                     {
2641                         m_pragmas[std::string(name)] = value;
2642                     }
2643                 }
2644             }
2645             else if (sscanf(line.c_str(), "objectSlotCount: %u", &numDefns) == 1)
2646             {
2647             }
2648 
2649             offset++;
2650         }
2651         return m_kernels.size() > 0;
2652     }
2653     return false;
2654 }
2655 
2656 bool
2657 RenderScriptRuntime::ProbeModules(const ModuleList module_list)
2658 {
2659     bool rs_found = false;
2660     size_t num_modules = module_list.GetSize();
2661     for (size_t i = 0; i < num_modules; i++)
2662     {
2663         auto module = module_list.GetModuleAtIndex(i);
2664         rs_found |= LoadModule(module);
2665     }
2666     return rs_found;
2667 }
2668 
2669 void
2670 RenderScriptRuntime::Status(Stream &strm) const
2671 {
2672     if (m_libRS)
2673     {
2674         strm.Printf("Runtime Library discovered.");
2675         strm.EOL();
2676     }
2677     if (m_libRSDriver)
2678     {
2679         strm.Printf("Runtime Driver discovered.");
2680         strm.EOL();
2681     }
2682     if (m_libRSCpuRef)
2683     {
2684         strm.Printf("CPU Reference Implementation discovered.");
2685         strm.EOL();
2686     }
2687 
2688     if (m_runtimeHooks.size())
2689     {
2690         strm.Printf("Runtime functions hooked:");
2691         strm.EOL();
2692         for (auto b : m_runtimeHooks)
2693         {
2694             strm.Indent(b.second->defn->name);
2695             strm.EOL();
2696         }
2697     }
2698     else
2699     {
2700         strm.Printf("Runtime is not hooked.");
2701         strm.EOL();
2702     }
2703 }
2704 
2705 void
2706 RenderScriptRuntime::DumpContexts(Stream &strm) const
2707 {
2708     strm.Printf("Inferred RenderScript Contexts:");
2709     strm.EOL();
2710     strm.IndentMore();
2711 
2712     std::map<addr_t, uint64_t> contextReferences;
2713 
2714     // Iterate over all of the currently discovered scripts.
2715     // Note: We cant push or pop from m_scripts inside this loop or it may invalidate script.
2716     for (const auto & script : m_scripts)
2717     {
2718         if (!script->context.isValid())
2719             continue;
2720         lldb::addr_t context = *script->context;
2721 
2722         if (contextReferences.find(context) != contextReferences.end())
2723         {
2724             contextReferences[context]++;
2725         }
2726         else
2727         {
2728             contextReferences[context] = 1;
2729         }
2730     }
2731 
2732     for (const auto& cRef : contextReferences)
2733     {
2734         strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances", cRef.first, cRef.second);
2735         strm.EOL();
2736     }
2737     strm.IndentLess();
2738 }
2739 
2740 void
2741 RenderScriptRuntime::DumpKernels(Stream &strm) const
2742 {
2743     strm.Printf("RenderScript Kernels:");
2744     strm.EOL();
2745     strm.IndentMore();
2746     for (const auto &module : m_rsmodules)
2747     {
2748         strm.Printf("Resource '%s':",module->m_resname.c_str());
2749         strm.EOL();
2750         for (const auto &kernel : module->m_kernels)
2751         {
2752             strm.Indent(kernel.m_name.AsCString());
2753             strm.EOL();
2754         }
2755     }
2756     strm.IndentLess();
2757 }
2758 
2759 RenderScriptRuntime::AllocationDetails*
2760 RenderScriptRuntime::FindAllocByID(Stream &strm, const uint32_t alloc_id)
2761 {
2762     AllocationDetails* alloc = nullptr;
2763 
2764     // See if we can find allocation using id as an index;
2765     if (alloc_id <= m_allocations.size() && alloc_id != 0
2766         && m_allocations[alloc_id-1]->id == alloc_id)
2767     {
2768         alloc = m_allocations[alloc_id-1].get();
2769         return alloc;
2770     }
2771 
2772     // Fallback to searching
2773     for (const auto & a : m_allocations)
2774     {
2775        if (a->id == alloc_id)
2776        {
2777            alloc = a.get();
2778            break;
2779        }
2780     }
2781 
2782     if (alloc == nullptr)
2783     {
2784         strm.Printf("Error: Couldn't find allocation with id matching %u", alloc_id);
2785         strm.EOL();
2786     }
2787 
2788     return alloc;
2789 }
2790 
2791 // Prints the contents of an allocation to the output stream, which may be a file
2792 bool
2793 RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame* frame_ptr, const uint32_t id)
2794 {
2795     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
2796 
2797     // Check we can find the desired allocation
2798     AllocationDetails* alloc = FindAllocByID(strm, id);
2799     if (!alloc)
2800         return false; // FindAllocByID() will print error message for us here
2801 
2802     if (log)
2803         log->Printf("RenderScriptRuntime::DumpAllocation - Found allocation 0x%" PRIx64, *alloc->address.get());
2804 
2805     // Check we have information about the allocation, if not calculate it
2806     if (alloc->shouldRefresh())
2807     {
2808         if (log)
2809             log->Printf("RenderScriptRuntime::DumpAllocation - Allocation details not calculated yet, jitting info");
2810 
2811         // JIT all the allocation information
2812         if (!RefreshAllocation(alloc, frame_ptr))
2813         {
2814             strm.Printf("Error: Couldn't JIT allocation details");
2815             strm.EOL();
2816             return false;
2817         }
2818     }
2819 
2820     // Establish format and size of each data element
2821     const unsigned int vec_size = *alloc->element.type_vec_size.get();
2822     const Element::DataType type = *alloc->element.type.get();
2823 
2824     assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT
2825                                                    && "Invalid allocation type");
2826 
2827     lldb::Format format;
2828     if (type >= Element::RS_TYPE_ELEMENT)
2829         format = eFormatHex;
2830     else
2831         format = vec_size == 1 ? static_cast<lldb::Format>(AllocationDetails::RSTypeToFormat[type][eFormatSingle])
2832                                : static_cast<lldb::Format>(AllocationDetails::RSTypeToFormat[type][eFormatVector]);
2833 
2834     const unsigned int data_size = *alloc->element.datum_size.get();
2835 
2836     if (log)
2837         log->Printf("RenderScriptRuntime::DumpAllocation - Element size %u bytes, including padding", data_size);
2838 
2839     // Allocate a buffer to copy data into
2840     std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr);
2841     if (!buffer)
2842     {
2843         strm.Printf("Error: Couldn't read allocation data");
2844         strm.EOL();
2845         return false;
2846     }
2847 
2848     // Calculate stride between rows as there may be padding at end of rows since
2849     // allocated memory is 16-byte aligned
2850     if (!alloc->stride.isValid())
2851     {
2852         if (alloc->dimension.get()->dim_2 == 0) // We only have one dimension
2853             alloc->stride = 0;
2854         else if (!JITAllocationStride(alloc, frame_ptr))
2855         {
2856             strm.Printf("Error: Couldn't calculate allocation row stride");
2857             strm.EOL();
2858             return false;
2859         }
2860     }
2861     const unsigned int stride = *alloc->stride.get();
2862     const unsigned int size = *alloc->size.get(); // Size of whole allocation
2863     const unsigned int padding = alloc->element.padding.isValid() ? *alloc->element.padding.get() : 0;
2864     if (log)
2865         log->Printf("RenderScriptRuntime::DumpAllocation - stride %u bytes, size %u bytes, padding %u", stride, size, padding);
2866 
2867     // Find dimensions used to index loops, so need to be non-zero
2868     unsigned int dim_x = alloc->dimension.get()->dim_1;
2869     dim_x = dim_x == 0 ? 1 : dim_x;
2870 
2871     unsigned int dim_y = alloc->dimension.get()->dim_2;
2872     dim_y = dim_y == 0 ? 1 : dim_y;
2873 
2874     unsigned int dim_z = alloc->dimension.get()->dim_3;
2875     dim_z = dim_z == 0 ? 1 : dim_z;
2876 
2877     // Use data extractor to format output
2878     const uint32_t archByteSize = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
2879     DataExtractor alloc_data(buffer.get(), size, GetProcess()->GetByteOrder(), archByteSize);
2880 
2881     unsigned int offset = 0;   // Offset in buffer to next element to be printed
2882     unsigned int prev_row = 0; // Offset to the start of the previous row
2883 
2884     // Iterate over allocation dimensions, printing results to user
2885     strm.Printf("Data (X, Y, Z):");
2886     for (unsigned int z = 0; z < dim_z; ++z)
2887     {
2888         for (unsigned int y = 0; y < dim_y; ++y)
2889         {
2890             // Use stride to index start of next row.
2891             if (!(y==0 && z==0))
2892                 offset = prev_row + stride;
2893             prev_row = offset;
2894 
2895             // Print each element in the row individually
2896             for (unsigned int x = 0; x < dim_x; ++x)
2897             {
2898                 strm.Printf("\n(%u, %u, %u) = ", x, y, z);
2899                 if ((type == Element::RS_TYPE_NONE) && (alloc->element.children.size() > 0) &&
2900                     (alloc->element.type_name != Element::GetFallbackStructName()))
2901                 {
2902                     // Here we are dumping an Element of struct type.
2903                     // This is done using expression evaluation with the name of the struct type and pointer to element.
2904 
2905                     // Don't print the name of the resulting expression, since this will be '$[0-9]+'
2906                     DumpValueObjectOptions expr_options;
2907                     expr_options.SetHideName(true);
2908 
2909                     // Setup expression as derefrencing a pointer cast to element address.
2910                     char expr_char_buffer[jit_max_expr_size];
2911                     int chars_written = snprintf(expr_char_buffer, jit_max_expr_size, "*(%s*) 0x%" PRIx64,
2912                                         alloc->element.type_name.AsCString(), *alloc->data_ptr.get() + offset);
2913 
2914                     if (chars_written < 0 || chars_written >= jit_max_expr_size)
2915                     {
2916                         if (log)
2917                             log->Printf("RenderScriptRuntime::DumpAllocation- Error in snprintf()");
2918                         continue;
2919                     }
2920 
2921                     // Evaluate expression
2922                     ValueObjectSP expr_result;
2923                     GetProcess()->GetTarget().EvaluateExpression(expr_char_buffer, frame_ptr, expr_result);
2924 
2925                     // Print the results to our stream.
2926                     expr_result->Dump(strm, expr_options);
2927                 }
2928                 else
2929                 {
2930                     alloc_data.Dump(&strm, offset, format, data_size - padding, 1, 1, LLDB_INVALID_ADDRESS, 0, 0);
2931                 }
2932                 offset += data_size;
2933             }
2934         }
2935     }
2936     strm.EOL();
2937 
2938     return true;
2939 }
2940 
2941 // Prints infomation regarding all the currently loaded allocations.
2942 // These details are gathered by jitting the runtime, which has as latency.
2943 void
2944 RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame* frame_ptr, bool recompute)
2945 {
2946     strm.Printf("RenderScript Allocations:");
2947     strm.EOL();
2948     strm.IndentMore();
2949 
2950     for (auto &alloc : m_allocations)
2951     {
2952         // JIT the allocation info if we haven't done it, or the user forces us to.
2953         bool do_refresh = alloc->shouldRefresh() || recompute;
2954 
2955         // JIT current allocation information
2956         if (do_refresh && !RefreshAllocation(alloc.get(), frame_ptr))
2957         {
2958             strm.Printf("Error: Couldn't evaluate details for allocation %u\n", alloc->id);
2959             continue;
2960         }
2961 
2962         strm.Printf("%u:\n",alloc->id);
2963         strm.IndentMore();
2964 
2965         strm.Indent("Context: ");
2966         if (!alloc->context.isValid())
2967             strm.Printf("unknown\n");
2968         else
2969             strm.Printf("0x%" PRIx64 "\n", *alloc->context.get());
2970 
2971         strm.Indent("Address: ");
2972         if (!alloc->address.isValid())
2973             strm.Printf("unknown\n");
2974         else
2975             strm.Printf("0x%" PRIx64 "\n", *alloc->address.get());
2976 
2977         strm.Indent("Data pointer: ");
2978         if (!alloc->data_ptr.isValid())
2979             strm.Printf("unknown\n");
2980         else
2981             strm.Printf("0x%" PRIx64 "\n", *alloc->data_ptr.get());
2982 
2983         strm.Indent("Dimensions: ");
2984         if (!alloc->dimension.isValid())
2985             strm.Printf("unknown\n");
2986         else
2987             strm.Printf("(%d, %d, %d)\n", alloc->dimension.get()->dim_1,
2988                                           alloc->dimension.get()->dim_2,
2989                                           alloc->dimension.get()->dim_3);
2990 
2991         strm.Indent("Data Type: ");
2992         if (!alloc->element.type.isValid() || !alloc->element.type_vec_size.isValid())
2993             strm.Printf("unknown\n");
2994         else
2995         {
2996             const int vector_size = *alloc->element.type_vec_size.get();
2997             Element::DataType type = *alloc->element.type.get();
2998 
2999             if (!alloc->element.type_name.IsEmpty())
3000                 strm.Printf("%s\n", alloc->element.type_name.AsCString());
3001             else
3002             {
3003                 // Enum value isn't monotonous, so doesn't always index RsDataTypeToString array
3004                 if (type >= Element::RS_TYPE_ELEMENT && type <= Element::RS_TYPE_FONT)
3005                     type = static_cast<Element::DataType>((type - Element::RS_TYPE_ELEMENT) +  Element::RS_TYPE_MATRIX_2X2 + 1);
3006 
3007                 if (type >= (sizeof(AllocationDetails::RsDataTypeToString) / sizeof(AllocationDetails::RsDataTypeToString[0]))
3008                     || vector_size > 4 || vector_size < 1)
3009                     strm.Printf("invalid type\n");
3010                 else
3011                     strm.Printf("%s\n", AllocationDetails::RsDataTypeToString[static_cast<unsigned int>(type)][vector_size-1]);
3012             }
3013         }
3014 
3015         strm.Indent("Data Kind: ");
3016         if (!alloc->element.type_kind.isValid())
3017             strm.Printf("unknown\n");
3018         else
3019         {
3020             const Element::DataKind kind = *alloc->element.type_kind.get();
3021             if (kind < Element::RS_KIND_USER || kind > Element::RS_KIND_PIXEL_YUV)
3022                 strm.Printf("invalid kind\n");
3023             else
3024                 strm.Printf("%s\n", AllocationDetails::RsDataKindToString[static_cast<unsigned int>(kind)]);
3025         }
3026 
3027         strm.EOL();
3028         strm.IndentLess();
3029     }
3030     strm.IndentLess();
3031 }
3032 
3033 // Set breakpoints on every kernel found in RS module
3034 void
3035 RenderScriptRuntime::BreakOnModuleKernels(const RSModuleDescriptorSP rsmodule_sp)
3036 {
3037     for (const auto &kernel : rsmodule_sp->m_kernels)
3038     {
3039         // Don't set breakpoint on 'root' kernel
3040         if (strcmp(kernel.m_name.AsCString(), "root") == 0)
3041             continue;
3042 
3043         CreateKernelBreakpoint(kernel.m_name);
3044     }
3045 }
3046 
3047 // Method is internally called by the 'kernel breakpoint all' command to
3048 // enable or disable breaking on all kernels.
3049 //
3050 // When do_break is true we want to enable this functionality.
3051 // When do_break is false we want to disable it.
3052 void
3053 RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target)
3054 {
3055     Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
3056 
3057     InitSearchFilter(target);
3058 
3059     // Set breakpoints on all the kernels
3060     if (do_break && !m_breakAllKernels)
3061     {
3062         m_breakAllKernels = true;
3063 
3064         for (const auto &module : m_rsmodules)
3065             BreakOnModuleKernels(module);
3066 
3067         if (log)
3068             log->Printf("RenderScriptRuntime::SetBreakAllKernels(True)"
3069                         "- breakpoints set on all currently loaded kernels");
3070     }
3071     else if (!do_break && m_breakAllKernels) // Breakpoints won't be set on any new kernels.
3072     {
3073         m_breakAllKernels = false;
3074 
3075         if (log)
3076             log->Printf("RenderScriptRuntime::SetBreakAllKernels(False) - breakpoints no longer automatically set");
3077     }
3078 }
3079 
3080 // Given the name of a kernel this function creates a breakpoint using our
3081 // own breakpoint resolver, and returns the Breakpoint shared pointer.
3082 BreakpointSP
3083 RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name)
3084 {
3085     Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
3086 
3087     if (!m_filtersp)
3088     {
3089         if (log)
3090             log->Printf("RenderScriptRuntime::CreateKernelBreakpoint - Error: No breakpoint search filter set");
3091         return nullptr;
3092     }
3093 
3094     BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name));
3095     BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(m_filtersp, resolver_sp, false, false, false);
3096 
3097     // Give RS breakpoints a specific name, so the user can manipulate them as a group.
3098     Error err;
3099     if (!bp->AddName("RenderScriptKernel", err) && log)
3100         log->Printf("RenderScriptRuntime::CreateKernelBreakpoint: Error setting break name, %s", err.AsCString());
3101 
3102     return bp;
3103 }
3104 
3105 // Given an expression for a variable this function tries to calculate the variable's value.
3106 // If this is possible it returns true and sets the uint64_t parameter to the variables unsigned value.
3107 // Otherwise function returns false.
3108 bool
3109 RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp, const char* var_name, uint64_t& val)
3110 {
3111     Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE));
3112     Error error;
3113     VariableSP var_sp;
3114 
3115     // Find variable in stack frame
3116     ValueObjectSP value_sp(frame_sp->GetValueForVariableExpressionPath(var_name,
3117                                                                        eNoDynamicValues,
3118                                                                        StackFrame::eExpressionPathOptionCheckPtrVsMember |
3119                                                                        StackFrame::eExpressionPathOptionsAllowDirectIVarAccess,
3120                                                                        var_sp,
3121                                                                        error));
3122     if (!error.Success())
3123     {
3124         if (log)
3125             log->Printf("RenderScriptRuntime::GetFrameVarAsUnsigned - Error, couldn't find '%s' in frame", var_name);
3126 
3127         return false;
3128     }
3129 
3130     // Find the unsigned int value for the variable
3131     bool success = false;
3132     val = value_sp->GetValueAsUnsigned(0, &success);
3133     if (!success)
3134     {
3135         if (log)
3136             log->Printf("RenderScriptRuntime::GetFrameVarAsUnsigned - Error, couldn't parse '%s' as an unsigned int", var_name);
3137 
3138         return false;
3139     }
3140 
3141     return true;
3142 }
3143 
3144 // Callback when a kernel breakpoint hits and we're looking for a specific coordinate.
3145 // Baton parameter contains a pointer to the target coordinate we want to break on.
3146 // Function then checks the .expand frame for the current coordinate and breaks to user if it matches.
3147 // Parameter 'break_id' is the id of the Breakpoint which made the callback.
3148 // Parameter 'break_loc_id' is the id for the BreakpointLocation which was hit,
3149 // a single logical breakpoint can have multiple addresses.
3150 bool
3151 RenderScriptRuntime::KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx,
3152                                          user_id_t break_id, user_id_t break_loc_id)
3153 {
3154     Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
3155 
3156     assert(baton && "Error: null baton in conditional kernel breakpoint callback");
3157 
3158     // Coordinate we want to stop on
3159     const int* target_coord = static_cast<const int*>(baton);
3160 
3161     if (log)
3162         log->Printf("RenderScriptRuntime::KernelBreakpointHit - Break ID %" PRIu64 ", target coord (%d, %d, %d)",
3163                     break_id, target_coord[0], target_coord[1], target_coord[2]);
3164 
3165     // Go up one stack frame to .expand kernel
3166     ExecutionContext context(ctx->exe_ctx_ref);
3167     ThreadSP thread_sp = context.GetThreadSP();
3168     if (!thread_sp->SetSelectedFrameByIndex(1))
3169     {
3170         if (log)
3171             log->Printf("RenderScriptRuntime::KernelBreakpointHit - Error, couldn't go up stack frame");
3172 
3173        return false;
3174     }
3175 
3176     StackFrameSP frame_sp = thread_sp->GetSelectedFrame();
3177     if (!frame_sp)
3178     {
3179         if (log)
3180             log->Printf("RenderScriptRuntime::KernelBreakpointHit - Error, couldn't select .expand stack frame");
3181 
3182         return false;
3183     }
3184 
3185     // Get values for variables in .expand frame that tell us the current kernel invocation
3186     const char* coord_expressions[] = {"rsIndex", "p->current.y", "p->current.z"};
3187     uint64_t current_coord[3] = {0, 0, 0};
3188 
3189     for(int i = 0; i < 3; ++i)
3190     {
3191         if (!GetFrameVarAsUnsigned(frame_sp, coord_expressions[i], current_coord[i]))
3192             return false;
3193 
3194         if (log)
3195             log->Printf("RenderScriptRuntime::KernelBreakpointHit, %s = %" PRIu64, coord_expressions[i], current_coord[i]);
3196     }
3197 
3198     // Check if the current kernel invocation coordinate matches our target coordinate
3199     if (current_coord[0] == static_cast<uint64_t>(target_coord[0]) &&
3200         current_coord[1] == static_cast<uint64_t>(target_coord[1]) &&
3201         current_coord[2] == static_cast<uint64_t>(target_coord[2]))
3202     {
3203         if (log)
3204              log->Printf("RenderScriptRuntime::KernelBreakpointHit, BREAKING %" PRIu64 ", %" PRIu64 ", %" PRIu64,
3205                          current_coord[0], current_coord[1], current_coord[2]);
3206 
3207         BreakpointSP breakpoint_sp = context.GetTargetPtr()->GetBreakpointByID(break_id);
3208         assert(breakpoint_sp != nullptr && "Error: Couldn't find breakpoint matching break id for callback");
3209         breakpoint_sp->SetEnabled(false); // Optimise since conditional breakpoint should only be hit once.
3210         return true;
3211     }
3212 
3213     // No match on coordinate
3214     return false;
3215 }
3216 
3217 // Tries to set a breakpoint on the start of a kernel, resolved using the kernel name.
3218 // Argument 'coords', represents a three dimensional coordinate which can be used to specify
3219 // a single kernel instance to break on. If this is set then we add a callback to the breakpoint.
3220 void
3221 RenderScriptRuntime::PlaceBreakpointOnKernel(Stream &strm, const char* name, const std::array<int,3> coords,
3222                                              Error& error, TargetSP target)
3223 {
3224     if (!name)
3225     {
3226         error.SetErrorString("invalid kernel name");
3227         return;
3228     }
3229 
3230     InitSearchFilter(target);
3231 
3232     ConstString kernel_name(name);
3233     BreakpointSP bp = CreateKernelBreakpoint(kernel_name);
3234 
3235     // We have a conditional breakpoint on a specific coordinate
3236     if (coords[0] != -1)
3237     {
3238         strm.Printf("Conditional kernel breakpoint on coordinate %d, %d, %d", coords[0], coords[1], coords[2]);
3239         strm.EOL();
3240 
3241         // Allocate memory for the baton, and copy over coordinate
3242         int* baton = new int[3];
3243         baton[0] = coords[0]; baton[1] = coords[1]; baton[2] = coords[2];
3244 
3245         // Create a callback that will be invoked everytime the breakpoint is hit.
3246         // The baton object passed to the handler is the target coordinate we want to break on.
3247         bp->SetCallback(KernelBreakpointHit, baton, true);
3248 
3249         // Store a shared pointer to the baton, so the memory will eventually be cleaned up after destruction
3250         m_conditional_breaks[bp->GetID()] = std::shared_ptr<int>(baton);
3251     }
3252 
3253     if (bp)
3254         bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false);
3255 }
3256 
3257 void
3258 RenderScriptRuntime::DumpModules(Stream &strm) const
3259 {
3260     strm.Printf("RenderScript Modules:");
3261     strm.EOL();
3262     strm.IndentMore();
3263     for (const auto &module : m_rsmodules)
3264     {
3265         module->Dump(strm);
3266     }
3267     strm.IndentLess();
3268 }
3269 
3270 RenderScriptRuntime::ScriptDetails*
3271 RenderScriptRuntime::LookUpScript(addr_t address, bool create)
3272 {
3273     for (const auto & s : m_scripts)
3274     {
3275         if (s->script.isValid())
3276             if (*s->script == address)
3277                 return s.get();
3278     }
3279     if (create)
3280     {
3281         std::unique_ptr<ScriptDetails> s(new ScriptDetails);
3282         s->script = address;
3283         m_scripts.push_back(std::move(s));
3284         return m_scripts.back().get();
3285     }
3286     return nullptr;
3287 }
3288 
3289 RenderScriptRuntime::AllocationDetails*
3290 RenderScriptRuntime::LookUpAllocation(addr_t address, bool create)
3291 {
3292     for (const auto & a : m_allocations)
3293     {
3294         if (a->address.isValid())
3295             if (*a->address == address)
3296                 return a.get();
3297     }
3298     if (create)
3299     {
3300         std::unique_ptr<AllocationDetails> a(new AllocationDetails);
3301         a->address = address;
3302         m_allocations.push_back(std::move(a));
3303         return m_allocations.back().get();
3304     }
3305     return nullptr;
3306 }
3307 
3308 void
3309 RSModuleDescriptor::Dump(Stream &strm) const
3310 {
3311     strm.Indent();
3312     m_module->GetFileSpec().Dump(&strm);
3313     if(m_module->GetNumCompileUnits())
3314     {
3315         strm.Indent("Debug info loaded.");
3316     }
3317     else
3318     {
3319         strm.Indent("Debug info does not exist.");
3320     }
3321     strm.EOL();
3322     strm.IndentMore();
3323     strm.Indent();
3324     strm.Printf("Globals: %" PRIu64, static_cast<uint64_t>(m_globals.size()));
3325     strm.EOL();
3326     strm.IndentMore();
3327     for (const auto &global : m_globals)
3328     {
3329         global.Dump(strm);
3330     }
3331     strm.IndentLess();
3332     strm.Indent();
3333     strm.Printf("Kernels: %" PRIu64, static_cast<uint64_t>(m_kernels.size()));
3334     strm.EOL();
3335     strm.IndentMore();
3336     for (const auto &kernel : m_kernels)
3337     {
3338         kernel.Dump(strm);
3339     }
3340     strm.Printf("Pragmas: %"  PRIu64 , static_cast<uint64_t>(m_pragmas.size()));
3341     strm.EOL();
3342     strm.IndentMore();
3343     for (const auto &key_val : m_pragmas)
3344     {
3345         strm.Printf("%s: %s", key_val.first.c_str(), key_val.second.c_str());
3346         strm.EOL();
3347     }
3348     strm.IndentLess(4);
3349 }
3350 
3351 void
3352 RSGlobalDescriptor::Dump(Stream &strm) const
3353 {
3354     strm.Indent(m_name.AsCString());
3355     VariableList var_list;
3356     m_module->m_module->FindGlobalVariables(m_name, nullptr, true, 1U, var_list);
3357     if (var_list.GetSize() == 1)
3358     {
3359         auto var = var_list.GetVariableAtIndex(0);
3360         auto type = var->GetType();
3361         if(type)
3362         {
3363             strm.Printf(" - ");
3364             type->DumpTypeName(&strm);
3365         }
3366         else
3367         {
3368             strm.Printf(" - Unknown Type");
3369         }
3370     }
3371     else
3372     {
3373         strm.Printf(" - variable identified, but not found in binary");
3374         const Symbol* s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData);
3375         if (s)
3376         {
3377             strm.Printf(" (symbol exists) ");
3378         }
3379     }
3380 
3381     strm.EOL();
3382 }
3383 
3384 void
3385 RSKernelDescriptor::Dump(Stream &strm) const
3386 {
3387     strm.Indent(m_name.AsCString());
3388     strm.EOL();
3389 }
3390 
3391 class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed
3392 {
3393 public:
3394     CommandObjectRenderScriptRuntimeModuleProbe(CommandInterpreter &interpreter)
3395         : CommandObjectParsed(interpreter, "renderscript module probe",
3396                               "Initiates a Probe of all loaded modules for kernels and other renderscript objects.",
3397                               "renderscript module probe",
3398                               eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBeLaunched)
3399     {
3400     }
3401 
3402     ~CommandObjectRenderScriptRuntimeModuleProbe() override = default;
3403 
3404     bool
3405     DoExecute(Args &command, CommandReturnObject &result) override
3406     {
3407         const size_t argc = command.GetArgumentCount();
3408         if (argc == 0)
3409         {
3410             Target *target = m_exe_ctx.GetTargetPtr();
3411             RenderScriptRuntime *runtime =
3412                 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
3413             auto module_list = target->GetImages();
3414             bool new_rs_details = runtime->ProbeModules(module_list);
3415             if (new_rs_details)
3416             {
3417                 result.AppendMessage("New renderscript modules added to runtime model.");
3418             }
3419             result.SetStatus(eReturnStatusSuccessFinishResult);
3420             return true;
3421         }
3422 
3423         result.AppendErrorWithFormat("'%s' takes no arguments", m_cmd_name.c_str());
3424         result.SetStatus(eReturnStatusFailed);
3425         return false;
3426     }
3427 };
3428 
3429 class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed
3430 {
3431 public:
3432     CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter)
3433         : CommandObjectParsed(interpreter, "renderscript module dump",
3434                               "Dumps renderscript specific information for all modules.", "renderscript module dump",
3435                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
3436     {
3437     }
3438 
3439     ~CommandObjectRenderScriptRuntimeModuleDump() override = default;
3440 
3441     bool
3442     DoExecute(Args &command, CommandReturnObject &result) override
3443     {
3444         RenderScriptRuntime *runtime =
3445             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
3446         runtime->DumpModules(result.GetOutputStream());
3447         result.SetStatus(eReturnStatusSuccessFinishResult);
3448         return true;
3449     }
3450 };
3451 
3452 class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword
3453 {
3454 public:
3455     CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter)
3456         : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with renderscript modules.",
3457                                  NULL)
3458     {
3459         LoadSubCommand("probe", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleProbe(interpreter)));
3460         LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter)));
3461     }
3462 
3463     ~CommandObjectRenderScriptRuntimeModule() override = default;
3464 };
3465 
3466 class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed
3467 {
3468 public:
3469     CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter)
3470         : CommandObjectParsed(interpreter, "renderscript kernel list",
3471                               "Lists renderscript kernel names and associated script resources.", "renderscript kernel list",
3472                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
3473     {
3474     }
3475 
3476     ~CommandObjectRenderScriptRuntimeKernelList() override = default;
3477 
3478     bool
3479     DoExecute(Args &command, CommandReturnObject &result) override
3480     {
3481         RenderScriptRuntime *runtime =
3482             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
3483         runtime->DumpKernels(result.GetOutputStream());
3484         result.SetStatus(eReturnStatusSuccessFinishResult);
3485         return true;
3486     }
3487 };
3488 
3489 class CommandObjectRenderScriptRuntimeKernelBreakpointSet : public CommandObjectParsed
3490 {
3491 public:
3492     CommandObjectRenderScriptRuntimeKernelBreakpointSet(CommandInterpreter &interpreter)
3493         : CommandObjectParsed(interpreter, "renderscript kernel breakpoint set",
3494                               "Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint set <kernel_name> [-c x,y,z]",
3495                               eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused), m_options(interpreter)
3496     {
3497     }
3498 
3499     ~CommandObjectRenderScriptRuntimeKernelBreakpointSet() override = default;
3500 
3501     Options*
3502     GetOptions() override
3503     {
3504         return &m_options;
3505     }
3506 
3507     class CommandOptions : public Options
3508     {
3509     public:
3510         CommandOptions(CommandInterpreter &interpreter) : Options(interpreter)
3511         {
3512         }
3513 
3514         ~CommandOptions() override = default;
3515 
3516         Error
3517         SetOptionValue(uint32_t option_idx, const char *option_arg) override
3518         {
3519             Error error;
3520             const int short_option = m_getopt_table[option_idx].val;
3521 
3522             switch (short_option)
3523             {
3524                 case 'c':
3525                     if (!ParseCoordinate(option_arg))
3526                         error.SetErrorStringWithFormat("Couldn't parse coordinate '%s', should be in format 'x,y,z'.", option_arg);
3527                     break;
3528                 default:
3529                     error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
3530                     break;
3531             }
3532             return error;
3533         }
3534 
3535         // -c takes an argument of the form 'num[,num][,num]'.
3536         // Where 'id_cstr' is this argument with the whitespace trimmed.
3537         // Missing coordinates are defaulted to zero.
3538         bool
3539         ParseCoordinate(const char* id_cstr)
3540         {
3541             RegularExpression regex;
3542             RegularExpression::Match regex_match(3);
3543 
3544             bool matched = false;
3545             if(regex.Compile("^([0-9]+),([0-9]+),([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
3546                 matched = true;
3547             else if(regex.Compile("^([0-9]+),([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
3548                 matched = true;
3549             else if(regex.Compile("^([0-9]+)$") && regex.Execute(id_cstr, &regex_match))
3550                 matched = true;
3551             for(uint32_t i = 0; i < 3; i++)
3552             {
3553                 std::string group;
3554                 if(regex_match.GetMatchAtIndex(id_cstr, i + 1, group))
3555                     m_coord[i] = (uint32_t)strtoul(group.c_str(), NULL, 0);
3556                 else
3557                     m_coord[i] = 0;
3558             }
3559             return matched;
3560         }
3561 
3562         void
3563         OptionParsingStarting() override
3564         {
3565             // -1 means the -c option hasn't been set
3566             m_coord[0] = -1;
3567             m_coord[1] = -1;
3568             m_coord[2] = -1;
3569         }
3570 
3571         const OptionDefinition*
3572         GetDefinitions() override
3573         {
3574             return g_option_table;
3575         }
3576 
3577         static OptionDefinition g_option_table[];
3578         std::array<int,3> m_coord;
3579     };
3580 
3581     bool
3582     DoExecute(Args &command, CommandReturnObject &result) override
3583     {
3584         const size_t argc = command.GetArgumentCount();
3585         if (argc < 1)
3586         {
3587             result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name, and an optional coordinate.", m_cmd_name.c_str());
3588             result.SetStatus(eReturnStatusFailed);
3589             return false;
3590         }
3591 
3592         RenderScriptRuntime *runtime =
3593                 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
3594 
3595         Error error;
3596         runtime->PlaceBreakpointOnKernel(result.GetOutputStream(), command.GetArgumentAtIndex(0), m_options.m_coord,
3597                                          error, m_exe_ctx.GetTargetSP());
3598 
3599         if (error.Success())
3600         {
3601             result.AppendMessage("Breakpoint(s) created");
3602             result.SetStatus(eReturnStatusSuccessFinishResult);
3603             return true;
3604         }
3605         result.SetStatus(eReturnStatusFailed);
3606         result.AppendErrorWithFormat("Error: %s", error.AsCString());
3607         return false;
3608     }
3609 
3610 private:
3611     CommandOptions m_options;
3612 };
3613 
3614 OptionDefinition
3615 CommandObjectRenderScriptRuntimeKernelBreakpointSet::CommandOptions::g_option_table[] =
3616 {
3617     { LLDB_OPT_SET_1, false, "coordinate", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeValue,
3618       "Set a breakpoint on a single invocation of the kernel with specified coordinate.\n"
3619       "Coordinate takes the form 'x[,y][,z] where x,y,z are positive integers representing kernel dimensions. "
3620       "Any unset dimensions will be defaulted to zero."},
3621     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
3622 };
3623 
3624 class CommandObjectRenderScriptRuntimeKernelBreakpointAll : public CommandObjectParsed
3625 {
3626 public:
3627     CommandObjectRenderScriptRuntimeKernelBreakpointAll(CommandInterpreter &interpreter)
3628         : CommandObjectParsed(interpreter, "renderscript kernel breakpoint all",
3629                               "Automatically sets a breakpoint on all renderscript kernels that are or will be loaded.\n"
3630                               "Disabling option means breakpoints will no longer be set on any kernels loaded in the future, "
3631                               "but does not remove currently set breakpoints.",
3632                               "renderscript kernel breakpoint all <enable/disable>",
3633                               eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
3634     {
3635     }
3636 
3637     ~CommandObjectRenderScriptRuntimeKernelBreakpointAll() override = default;
3638 
3639     bool
3640     DoExecute(Args &command, CommandReturnObject &result) override
3641     {
3642         const size_t argc = command.GetArgumentCount();
3643         if (argc != 1)
3644         {
3645             result.AppendErrorWithFormat("'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str());
3646             result.SetStatus(eReturnStatusFailed);
3647             return false;
3648         }
3649 
3650         RenderScriptRuntime *runtime =
3651           static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
3652 
3653         bool do_break = false;
3654         const char* argument = command.GetArgumentAtIndex(0);
3655         if (strcmp(argument, "enable") == 0)
3656         {
3657             do_break = true;
3658             result.AppendMessage("Breakpoints will be set on all kernels.");
3659         }
3660         else if (strcmp(argument, "disable") == 0)
3661         {
3662             do_break = false;
3663             result.AppendMessage("Breakpoints will not be set on any new kernels.");
3664         }
3665         else
3666         {
3667             result.AppendErrorWithFormat("Argument must be either 'enable' or 'disable'");
3668             result.SetStatus(eReturnStatusFailed);
3669             return false;
3670         }
3671 
3672         runtime->SetBreakAllKernels(do_break, m_exe_ctx.GetTargetSP());
3673 
3674         result.SetStatus(eReturnStatusSuccessFinishResult);
3675         return true;
3676     }
3677 };
3678 
3679 class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectMultiword
3680 {
3681 public:
3682     CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter)
3683         : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that generate breakpoints on renderscript kernels.",
3684                                  nullptr)
3685     {
3686         LoadSubCommand("set", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointSet(interpreter)));
3687         LoadSubCommand("all", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointAll(interpreter)));
3688     }
3689 
3690     ~CommandObjectRenderScriptRuntimeKernelBreakpoint() override = default;
3691 };
3692 
3693 class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword
3694 {
3695 public:
3696     CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter)
3697         : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with renderscript kernels.",
3698                                  NULL)
3699     {
3700         LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(interpreter)));
3701         LoadSubCommand("breakpoint", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter)));
3702     }
3703 
3704     ~CommandObjectRenderScriptRuntimeKernel() override = default;
3705 };
3706 
3707 class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed
3708 {
3709 public:
3710     CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter)
3711         : CommandObjectParsed(interpreter, "renderscript context dump",
3712                               "Dumps renderscript context information.", "renderscript context dump",
3713                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
3714     {
3715     }
3716 
3717     ~CommandObjectRenderScriptRuntimeContextDump() override = default;
3718 
3719     bool
3720     DoExecute(Args &command, CommandReturnObject &result) override
3721     {
3722         RenderScriptRuntime *runtime =
3723             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
3724         runtime->DumpContexts(result.GetOutputStream());
3725         result.SetStatus(eReturnStatusSuccessFinishResult);
3726         return true;
3727     }
3728 };
3729 
3730 class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword
3731 {
3732 public:
3733     CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter)
3734         : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with renderscript contexts.",
3735                                  NULL)
3736     {
3737         LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(interpreter)));
3738     }
3739 
3740     ~CommandObjectRenderScriptRuntimeContext() override = default;
3741 };
3742 
3743 class CommandObjectRenderScriptRuntimeAllocationDump : public CommandObjectParsed
3744 {
3745 public:
3746     CommandObjectRenderScriptRuntimeAllocationDump(CommandInterpreter &interpreter)
3747         : CommandObjectParsed(interpreter, "renderscript allocation dump",
3748                               "Displays the contents of a particular allocation", "renderscript allocation dump <ID>",
3749                               eCommandRequiresProcess | eCommandProcessMustBeLaunched), m_options(interpreter)
3750     {
3751     }
3752 
3753     ~CommandObjectRenderScriptRuntimeAllocationDump() override = default;
3754 
3755     Options*
3756     GetOptions() override
3757     {
3758         return &m_options;
3759     }
3760 
3761     class CommandOptions : public Options
3762     {
3763     public:
3764         CommandOptions(CommandInterpreter &interpreter) : Options(interpreter)
3765         {
3766         }
3767 
3768         ~CommandOptions() override = default;
3769 
3770         Error
3771         SetOptionValue(uint32_t option_idx, const char *option_arg) override
3772         {
3773             Error error;
3774             const int short_option = m_getopt_table[option_idx].val;
3775 
3776             switch (short_option)
3777             {
3778                 case 'f':
3779                     m_outfile.SetFile(option_arg, true);
3780                     if (m_outfile.Exists())
3781                     {
3782                         m_outfile.Clear();
3783                         error.SetErrorStringWithFormat("file already exists: '%s'", option_arg);
3784                     }
3785                     break;
3786                 default:
3787                     error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
3788                     break;
3789             }
3790             return error;
3791         }
3792 
3793         void
3794         OptionParsingStarting() override
3795         {
3796             m_outfile.Clear();
3797         }
3798 
3799         const OptionDefinition*
3800         GetDefinitions() override
3801         {
3802             return g_option_table;
3803         }
3804 
3805         static OptionDefinition g_option_table[];
3806         FileSpec m_outfile;
3807     };
3808 
3809     bool
3810     DoExecute(Args &command, CommandReturnObject &result) override
3811     {
3812         const size_t argc = command.GetArgumentCount();
3813         if (argc < 1)
3814         {
3815             result.AppendErrorWithFormat("'%s' takes 1 argument, an allocation ID. As well as an optional -f argument",
3816                                          m_cmd_name.c_str());
3817             result.SetStatus(eReturnStatusFailed);
3818             return false;
3819         }
3820 
3821         RenderScriptRuntime *runtime =
3822           static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
3823 
3824         const char* id_cstr = command.GetArgumentAtIndex(0);
3825         bool convert_complete = false;
3826         const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete);
3827         if (!convert_complete)
3828         {
3829             result.AppendErrorWithFormat("invalid allocation id argument '%s'", id_cstr);
3830             result.SetStatus(eReturnStatusFailed);
3831             return false;
3832         }
3833 
3834         Stream* output_strm = nullptr;
3835         StreamFile outfile_stream;
3836         const FileSpec &outfile_spec = m_options.m_outfile; // Dump allocation to file instead
3837         if (outfile_spec)
3838         {
3839             // Open output file
3840             char path[256];
3841             outfile_spec.GetPath(path, sizeof(path));
3842             if (outfile_stream.GetFile().Open(path, File::eOpenOptionWrite | File::eOpenOptionCanCreate).Success())
3843             {
3844                 output_strm = &outfile_stream;
3845                 result.GetOutputStream().Printf("Results written to '%s'", path);
3846                 result.GetOutputStream().EOL();
3847             }
3848             else
3849             {
3850                 result.AppendErrorWithFormat("Couldn't open file '%s'", path);
3851                 result.SetStatus(eReturnStatusFailed);
3852                 return false;
3853             }
3854         }
3855         else
3856             output_strm = &result.GetOutputStream();
3857 
3858         assert(output_strm != nullptr);
3859         bool success = runtime->DumpAllocation(*output_strm, m_exe_ctx.GetFramePtr(), id);
3860 
3861         if (success)
3862             result.SetStatus(eReturnStatusSuccessFinishResult);
3863         else
3864             result.SetStatus(eReturnStatusFailed);
3865 
3866         return true;
3867     }
3868 
3869 private:
3870     CommandOptions m_options;
3871 };
3872 
3873 OptionDefinition
3874 CommandObjectRenderScriptRuntimeAllocationDump::CommandOptions::g_option_table[] =
3875 {
3876     { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFilename,
3877       "Print results to specified file instead of command line."},
3878     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
3879 };
3880 
3881 class CommandObjectRenderScriptRuntimeAllocationList : public CommandObjectParsed
3882 {
3883 public:
3884     CommandObjectRenderScriptRuntimeAllocationList(CommandInterpreter &interpreter)
3885         : CommandObjectParsed(interpreter, "renderscript allocation list",
3886                               "List renderscript allocations and their information.", "renderscript allocation list",
3887                               eCommandRequiresProcess | eCommandProcessMustBeLaunched), m_options(interpreter)
3888     {
3889     }
3890 
3891     ~CommandObjectRenderScriptRuntimeAllocationList() override = default;
3892 
3893     Options*
3894     GetOptions() override
3895     {
3896         return &m_options;
3897     }
3898 
3899     class CommandOptions : public Options
3900     {
3901     public:
3902         CommandOptions(CommandInterpreter &interpreter) : Options(interpreter), m_refresh(false)
3903         {
3904         }
3905 
3906         ~CommandOptions() override = default;
3907 
3908         Error
3909         SetOptionValue(uint32_t option_idx, const char *option_arg) override
3910         {
3911             Error error;
3912             const int short_option = m_getopt_table[option_idx].val;
3913 
3914             switch (short_option)
3915             {
3916                 case 'r':
3917                     m_refresh = true;
3918                     break;
3919                 default:
3920                     error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
3921                     break;
3922             }
3923             return error;
3924         }
3925 
3926         void
3927         OptionParsingStarting() override
3928         {
3929             m_refresh = false;
3930         }
3931 
3932         const OptionDefinition*
3933         GetDefinitions() override
3934         {
3935             return g_option_table;
3936         }
3937 
3938         static OptionDefinition g_option_table[];
3939         bool m_refresh;
3940     };
3941 
3942     bool
3943     DoExecute(Args &command, CommandReturnObject &result) override
3944     {
3945         RenderScriptRuntime *runtime =
3946           static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
3947         runtime->ListAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr(), m_options.m_refresh);
3948         result.SetStatus(eReturnStatusSuccessFinishResult);
3949         return true;
3950     }
3951 
3952 private:
3953     CommandOptions m_options;
3954 };
3955 
3956 OptionDefinition
3957 CommandObjectRenderScriptRuntimeAllocationList::CommandOptions::g_option_table[] =
3958 {
3959     { LLDB_OPT_SET_1, false, "refresh", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
3960       "Recompute allocation details."},
3961     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
3962 };
3963 
3964 class CommandObjectRenderScriptRuntimeAllocationLoad : public CommandObjectParsed
3965 {
3966 public:
3967     CommandObjectRenderScriptRuntimeAllocationLoad(CommandInterpreter &interpreter)
3968         : CommandObjectParsed(interpreter, "renderscript allocation load",
3969                               "Loads renderscript allocation contents from a file.", "renderscript allocation load <ID> <filename>",
3970                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
3971     {
3972     }
3973 
3974     ~CommandObjectRenderScriptRuntimeAllocationLoad() override = default;
3975 
3976     bool
3977     DoExecute(Args &command, CommandReturnObject &result) override
3978     {
3979         const size_t argc = command.GetArgumentCount();
3980         if (argc != 2)
3981         {
3982             result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.", m_cmd_name.c_str());
3983             result.SetStatus(eReturnStatusFailed);
3984             return false;
3985         }
3986 
3987         RenderScriptRuntime *runtime =
3988           static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
3989 
3990         const char* id_cstr = command.GetArgumentAtIndex(0);
3991         bool convert_complete = false;
3992         const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete);
3993         if (!convert_complete)
3994         {
3995             result.AppendErrorWithFormat ("invalid allocation id argument '%s'", id_cstr);
3996             result.SetStatus (eReturnStatusFailed);
3997             return false;
3998         }
3999 
4000         const char* filename = command.GetArgumentAtIndex(1);
4001         bool success = runtime->LoadAllocation(result.GetOutputStream(), id, filename, m_exe_ctx.GetFramePtr());
4002 
4003         if (success)
4004             result.SetStatus(eReturnStatusSuccessFinishResult);
4005         else
4006             result.SetStatus(eReturnStatusFailed);
4007 
4008         return true;
4009     }
4010 };
4011 
4012 class CommandObjectRenderScriptRuntimeAllocationSave : public CommandObjectParsed
4013 {
4014 public:
4015     CommandObjectRenderScriptRuntimeAllocationSave(CommandInterpreter &interpreter)
4016         : CommandObjectParsed(interpreter, "renderscript allocation save",
4017                               "Write renderscript allocation contents to a file.", "renderscript allocation save <ID> <filename>",
4018                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
4019     {
4020     }
4021 
4022     ~CommandObjectRenderScriptRuntimeAllocationSave() override = default;
4023 
4024     bool
4025     DoExecute(Args &command, CommandReturnObject &result) override
4026     {
4027         const size_t argc = command.GetArgumentCount();
4028         if (argc != 2)
4029         {
4030             result.AppendErrorWithFormat("'%s' takes 2 arguments, an allocation ID and filename to read from.", m_cmd_name.c_str());
4031             result.SetStatus(eReturnStatusFailed);
4032             return false;
4033         }
4034 
4035         RenderScriptRuntime *runtime =
4036           static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
4037 
4038         const char* id_cstr = command.GetArgumentAtIndex(0);
4039         bool convert_complete = false;
4040         const uint32_t id = StringConvert::ToUInt32(id_cstr, UINT32_MAX, 0, &convert_complete);
4041         if (!convert_complete)
4042         {
4043             result.AppendErrorWithFormat ("invalid allocation id argument '%s'", id_cstr);
4044             result.SetStatus (eReturnStatusFailed);
4045             return false;
4046         }
4047 
4048         const char* filename = command.GetArgumentAtIndex(1);
4049         bool success = runtime->SaveAllocation(result.GetOutputStream(), id, filename, m_exe_ctx.GetFramePtr());
4050 
4051         if (success)
4052             result.SetStatus(eReturnStatusSuccessFinishResult);
4053         else
4054             result.SetStatus(eReturnStatusFailed);
4055 
4056         return true;
4057     }
4058 };
4059 
4060 class CommandObjectRenderScriptRuntimeAllocation : public CommandObjectMultiword
4061 {
4062 public:
4063     CommandObjectRenderScriptRuntimeAllocation(CommandInterpreter &interpreter)
4064         : CommandObjectMultiword(interpreter, "renderscript allocation", "Commands that deal with renderscript allocations.",
4065                                  NULL)
4066     {
4067         LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationList(interpreter)));
4068         LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationDump(interpreter)));
4069         LoadSubCommand("save", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationSave(interpreter)));
4070         LoadSubCommand("load", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationLoad(interpreter)));
4071     }
4072 
4073     ~CommandObjectRenderScriptRuntimeAllocation() override = default;
4074 };
4075 
4076 class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed
4077 {
4078 public:
4079     CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter)
4080         : CommandObjectParsed(interpreter, "renderscript status",
4081                               "Displays current renderscript runtime status.", "renderscript status",
4082                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
4083     {
4084     }
4085 
4086     ~CommandObjectRenderScriptRuntimeStatus() override = default;
4087 
4088     bool
4089     DoExecute(Args &command, CommandReturnObject &result) override
4090     {
4091         RenderScriptRuntime *runtime =
4092             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
4093         runtime->Status(result.GetOutputStream());
4094         result.SetStatus(eReturnStatusSuccessFinishResult);
4095         return true;
4096     }
4097 };
4098 
4099 class CommandObjectRenderScriptRuntime : public CommandObjectMultiword
4100 {
4101 public:
4102     CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter)
4103         : CommandObjectMultiword(interpreter, "renderscript", "A set of commands for operating on renderscript.",
4104                                  "renderscript <subcommand> [<subcommand-options>]")
4105     {
4106         LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter)));
4107         LoadSubCommand("status", CommandObjectSP(new CommandObjectRenderScriptRuntimeStatus(interpreter)));
4108         LoadSubCommand("kernel", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernel(interpreter)));
4109         LoadSubCommand("context", CommandObjectSP(new CommandObjectRenderScriptRuntimeContext(interpreter)));
4110         LoadSubCommand("allocation", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocation(interpreter)));
4111     }
4112 
4113     ~CommandObjectRenderScriptRuntime() override = default;
4114 };
4115 
4116 void
4117 RenderScriptRuntime::Initiate()
4118 {
4119     assert(!m_initiated);
4120 }
4121 
4122 RenderScriptRuntime::RenderScriptRuntime(Process *process)
4123     : lldb_private::CPPLanguageRuntime(process), m_initiated(false), m_debuggerPresentFlagged(false),
4124       m_breakAllKernels(false)
4125 {
4126     ModulesDidLoad(process->GetTarget().GetImages());
4127 }
4128 
4129 lldb::CommandObjectSP
4130 RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter& interpreter)
4131 {
4132     static CommandObjectSP command_object;
4133     if(!command_object)
4134     {
4135         command_object.reset(new CommandObjectRenderScriptRuntime(interpreter));
4136     }
4137     return command_object;
4138 }
4139 
4140 RenderScriptRuntime::~RenderScriptRuntime() = default;
4141