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