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