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