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