15ec532a9SColin Riley //===-- RenderScriptRuntime.cpp ---------------------------------*- C++ -*-===//
25ec532a9SColin Riley //
35ec532a9SColin Riley //                     The LLVM Compiler Infrastructure
45ec532a9SColin Riley //
55ec532a9SColin Riley // This file is distributed under the University of Illinois Open Source
65ec532a9SColin Riley // License. See LICENSE.TXT for details.
75ec532a9SColin Riley //
85ec532a9SColin Riley //===----------------------------------------------------------------------===//
95ec532a9SColin Riley 
105ec532a9SColin Riley #include "RenderScriptRuntime.h"
115ec532a9SColin Riley 
125ec532a9SColin Riley #include "lldb/Core/ConstString.h"
135ec532a9SColin Riley #include "lldb/Core/Debugger.h"
145ec532a9SColin Riley #include "lldb/Core/Error.h"
155ec532a9SColin Riley #include "lldb/Core/Log.h"
165ec532a9SColin Riley #include "lldb/Core/PluginManager.h"
175ec532a9SColin Riley #include "lldb/Symbol/Symbol.h"
184640cde1SColin Riley #include "lldb/Symbol/Type.h"
195ec532a9SColin Riley #include "lldb/Target/Process.h"
205ec532a9SColin Riley #include "lldb/Target/Target.h"
215ec532a9SColin Riley #include "lldb/Interpreter/Args.h"
225ec532a9SColin Riley #include "lldb/Interpreter/Options.h"
235ec532a9SColin Riley #include "lldb/Interpreter/CommandInterpreter.h"
245ec532a9SColin Riley #include "lldb/Interpreter/CommandReturnObject.h"
255ec532a9SColin Riley #include "lldb/Interpreter/CommandObjectMultiword.h"
264640cde1SColin Riley #include "lldb/Breakpoint/StoppointCallbackContext.h"
274640cde1SColin Riley #include "lldb/Target/RegisterContext.h"
28*15f2bd95SEwan Crawford #include "lldb/Expression/UserExpression.h"
294640cde1SColin Riley #include "lldb/Symbol/VariableList.h"
305ec532a9SColin Riley 
315ec532a9SColin Riley using namespace lldb;
325ec532a9SColin Riley using namespace lldb_private;
3398156583SEwan Crawford using namespace lldb_renderscript;
345ec532a9SColin Riley 
3578f339d1SEwan Crawford namespace {
3678f339d1SEwan Crawford 
3778f339d1SEwan Crawford // The empirical_type adds a basic level of validation to arbitrary data
3878f339d1SEwan Crawford // allowing us to track if data has been discovered and stored or not.
3978f339d1SEwan Crawford // An empirical_type will be marked as valid only if it has been explicitly assigned to.
4078f339d1SEwan Crawford template <typename type_t>
4178f339d1SEwan Crawford class empirical_type
4278f339d1SEwan Crawford {
4378f339d1SEwan Crawford   public:
4478f339d1SEwan Crawford     // Ctor. Contents is invalid when constructed.
4578f339d1SEwan Crawford     empirical_type()
4678f339d1SEwan Crawford         : valid(false)
4778f339d1SEwan Crawford     {}
4878f339d1SEwan Crawford 
4978f339d1SEwan Crawford     // Return true and copy contents to out if valid, else return false.
5078f339d1SEwan Crawford     bool get(type_t& out) const
5178f339d1SEwan Crawford     {
5278f339d1SEwan Crawford         if (valid)
5378f339d1SEwan Crawford             out = data;
5478f339d1SEwan Crawford         return valid;
5578f339d1SEwan Crawford     }
5678f339d1SEwan Crawford 
5778f339d1SEwan Crawford     // Return a pointer to the contents or nullptr if it was not valid.
5878f339d1SEwan Crawford     const type_t* get() const
5978f339d1SEwan Crawford     {
6078f339d1SEwan Crawford         return valid ? &data : nullptr;
6178f339d1SEwan Crawford     }
6278f339d1SEwan Crawford 
6378f339d1SEwan Crawford     // Assign data explicitly.
6478f339d1SEwan Crawford     void set(const type_t in)
6578f339d1SEwan Crawford     {
6678f339d1SEwan Crawford         data = in;
6778f339d1SEwan Crawford         valid = true;
6878f339d1SEwan Crawford     }
6978f339d1SEwan Crawford 
7078f339d1SEwan Crawford     // Mark contents as invalid.
7178f339d1SEwan Crawford     void invalidate()
7278f339d1SEwan Crawford     {
7378f339d1SEwan Crawford         valid = false;
7478f339d1SEwan Crawford     }
7578f339d1SEwan Crawford 
7678f339d1SEwan Crawford     // Returns true if this type contains valid data.
7778f339d1SEwan Crawford     bool isValid() const
7878f339d1SEwan Crawford     {
7978f339d1SEwan Crawford         return valid;
8078f339d1SEwan Crawford     }
8178f339d1SEwan Crawford 
8278f339d1SEwan Crawford     // Assignment operator.
8378f339d1SEwan Crawford     empirical_type<type_t>& operator = (const type_t in)
8478f339d1SEwan Crawford     {
8578f339d1SEwan Crawford         set(in);
8678f339d1SEwan Crawford         return *this;
8778f339d1SEwan Crawford     }
8878f339d1SEwan Crawford 
8978f339d1SEwan Crawford     // Dereference operator returns contents.
9078f339d1SEwan Crawford     // Warning: Will assert if not valid so use only when you know data is valid.
9178f339d1SEwan Crawford     const type_t& operator * () const
9278f339d1SEwan Crawford     {
9378f339d1SEwan Crawford         assert(valid);
9478f339d1SEwan Crawford         return data;
9578f339d1SEwan Crawford     }
9678f339d1SEwan Crawford 
9778f339d1SEwan Crawford   protected:
9878f339d1SEwan Crawford     bool valid;
9978f339d1SEwan Crawford     type_t data;
10078f339d1SEwan Crawford };
10178f339d1SEwan Crawford 
10278f339d1SEwan Crawford } // namespace {}
10378f339d1SEwan Crawford 
10478f339d1SEwan Crawford // The ScriptDetails class collects data associated with a single script instance.
10578f339d1SEwan Crawford struct RenderScriptRuntime::ScriptDetails
10678f339d1SEwan Crawford {
10778f339d1SEwan Crawford     ~ScriptDetails() {};
10878f339d1SEwan Crawford 
10978f339d1SEwan Crawford     enum ScriptType
11078f339d1SEwan Crawford     {
11178f339d1SEwan Crawford         eScript,
11278f339d1SEwan Crawford         eScriptC
11378f339d1SEwan Crawford     };
11478f339d1SEwan Crawford 
11578f339d1SEwan Crawford     // The derived type of the script.
11678f339d1SEwan Crawford     empirical_type<ScriptType> type;
11778f339d1SEwan Crawford     // The name of the original source file.
11878f339d1SEwan Crawford     empirical_type<std::string> resName;
11978f339d1SEwan Crawford     // Path to script .so file on the device.
12078f339d1SEwan Crawford     empirical_type<std::string> scriptDyLib;
12178f339d1SEwan Crawford     // Directory where kernel objects are cached on device.
12278f339d1SEwan Crawford     empirical_type<std::string> cacheDir;
12378f339d1SEwan Crawford     // Pointer to the context which owns this script.
12478f339d1SEwan Crawford     empirical_type<lldb::addr_t> context;
12578f339d1SEwan Crawford     // Pointer to the script object itself.
12678f339d1SEwan Crawford     empirical_type<lldb::addr_t> script;
12778f339d1SEwan Crawford };
12878f339d1SEwan Crawford 
12978f339d1SEwan Crawford // This AllocationDetails class collects data associated with a single
13078f339d1SEwan Crawford // allocation instance.
13178f339d1SEwan Crawford struct RenderScriptRuntime::AllocationDetails
13278f339d1SEwan Crawford {
133*15f2bd95SEwan Crawford    // Taken from rsDefines.h
134*15f2bd95SEwan Crawford    enum DataKind
135*15f2bd95SEwan Crawford    {
136*15f2bd95SEwan Crawford        RS_KIND_USER,
137*15f2bd95SEwan Crawford        RS_KIND_PIXEL_L = 7,
138*15f2bd95SEwan Crawford        RS_KIND_PIXEL_A,
139*15f2bd95SEwan Crawford        RS_KIND_PIXEL_LA,
140*15f2bd95SEwan Crawford        RS_KIND_PIXEL_RGB,
141*15f2bd95SEwan Crawford        RS_KIND_PIXEL_RGBA,
142*15f2bd95SEwan Crawford        RS_KIND_PIXEL_DEPTH,
143*15f2bd95SEwan Crawford        RS_KIND_PIXEL_YUV,
144*15f2bd95SEwan Crawford        RS_KIND_INVALID = 100
145*15f2bd95SEwan Crawford    };
14678f339d1SEwan Crawford 
147*15f2bd95SEwan Crawford    // Taken from rsDefines.h
14878f339d1SEwan Crawford    enum DataType
14978f339d1SEwan Crawford    {
150*15f2bd95SEwan Crawford        RS_TYPE_NONE = 0,
151*15f2bd95SEwan Crawford        RS_TYPE_FLOAT_16,
152*15f2bd95SEwan Crawford        RS_TYPE_FLOAT_32,
153*15f2bd95SEwan Crawford        RS_TYPE_FLOAT_64,
154*15f2bd95SEwan Crawford        RS_TYPE_SIGNED_8,
155*15f2bd95SEwan Crawford        RS_TYPE_SIGNED_16,
156*15f2bd95SEwan Crawford        RS_TYPE_SIGNED_32,
157*15f2bd95SEwan Crawford        RS_TYPE_SIGNED_64,
158*15f2bd95SEwan Crawford        RS_TYPE_UNSIGNED_8,
159*15f2bd95SEwan Crawford        RS_TYPE_UNSIGNED_16,
160*15f2bd95SEwan Crawford        RS_TYPE_UNSIGNED_32,
161*15f2bd95SEwan Crawford        RS_TYPE_UNSIGNED_64,
162*15f2bd95SEwan Crawford        RS_TYPE_BOOLEAN
16378f339d1SEwan Crawford     };
16478f339d1SEwan Crawford 
165*15f2bd95SEwan Crawford     struct Dimension
16678f339d1SEwan Crawford     {
167*15f2bd95SEwan Crawford         uint32_t dim_1;
168*15f2bd95SEwan Crawford         uint32_t dim_2;
169*15f2bd95SEwan Crawford         uint32_t dim_3;
170*15f2bd95SEwan Crawford         uint32_t cubeMap;
171*15f2bd95SEwan Crawford 
172*15f2bd95SEwan Crawford         Dimension()
173*15f2bd95SEwan Crawford         {
174*15f2bd95SEwan Crawford              dim_1 = 0;
175*15f2bd95SEwan Crawford              dim_2 = 0;
176*15f2bd95SEwan Crawford              dim_3 = 0;
177*15f2bd95SEwan Crawford              cubeMap = 0;
178*15f2bd95SEwan Crawford         }
17978f339d1SEwan Crawford     };
18078f339d1SEwan Crawford 
181*15f2bd95SEwan Crawford     // Monotonically increasing from 1
182*15f2bd95SEwan Crawford     static unsigned int ID;
183*15f2bd95SEwan Crawford 
184*15f2bd95SEwan Crawford     // Maps Allocation DataType enum and vector size to printable strings
185*15f2bd95SEwan Crawford     // using mapping from RenderScript numerical types summary documentation
186*15f2bd95SEwan Crawford     static const char* RsDataTypeToString[][4];
187*15f2bd95SEwan Crawford 
188*15f2bd95SEwan Crawford     // Maps Allocation DataKind enum to printable strings
189*15f2bd95SEwan Crawford     static const char* RsDataKindToString[];
190*15f2bd95SEwan Crawford 
191*15f2bd95SEwan Crawford     // Give each allocation an ID as a way
192*15f2bd95SEwan Crawford     // for commands to reference it.
193*15f2bd95SEwan Crawford     const unsigned int id;
194*15f2bd95SEwan Crawford 
195*15f2bd95SEwan Crawford     empirical_type<DataType> type;            // Type of each data pointer stored by the allocation
196*15f2bd95SEwan Crawford     empirical_type<DataKind> type_kind;       // Defines pixel type if Allocation is created from an image
197*15f2bd95SEwan Crawford     empirical_type<uint32_t> type_vec_size;   // Vector size of each data point, e.g '4' for uchar4
198*15f2bd95SEwan Crawford     empirical_type<Dimension> dimension;      // Dimensions of the Allocation
199*15f2bd95SEwan Crawford     empirical_type<lldb::addr_t> address;     // Pointer to address of the RS Allocation
200*15f2bd95SEwan Crawford     empirical_type<lldb::addr_t> data_ptr;    // Pointer to the data held by the Allocation
201*15f2bd95SEwan Crawford     empirical_type<lldb::addr_t> type_ptr;    // Pointer to the RS Type of the Allocation
202*15f2bd95SEwan Crawford     empirical_type<lldb::addr_t> element_ptr; // Pointer to the RS Element of the Type
203*15f2bd95SEwan Crawford     empirical_type<lldb::addr_t> context;     // Pointer to the RS Context of the Allocation
204*15f2bd95SEwan Crawford 
205*15f2bd95SEwan Crawford     // Give each allocation an id, so we can reference it in user commands.
206*15f2bd95SEwan Crawford     AllocationDetails(): id(ID++)
207*15f2bd95SEwan Crawford     {
208*15f2bd95SEwan Crawford     }
209*15f2bd95SEwan Crawford 
210*15f2bd95SEwan Crawford };
211*15f2bd95SEwan Crawford 
212*15f2bd95SEwan Crawford unsigned int RenderScriptRuntime::AllocationDetails::ID = 1;
213*15f2bd95SEwan Crawford 
214*15f2bd95SEwan Crawford const char* RenderScriptRuntime::AllocationDetails::RsDataKindToString[] =
215*15f2bd95SEwan Crawford {
216*15f2bd95SEwan Crawford    "User",
217*15f2bd95SEwan Crawford    "Undefined", "Undefined", "Undefined", // Enum jumps from 0 to 7
218*15f2bd95SEwan Crawford    "Undefined", "Undefined", "Undefined",
219*15f2bd95SEwan Crawford    "L Pixel",
220*15f2bd95SEwan Crawford    "A Pixel",
221*15f2bd95SEwan Crawford    "LA Pixel",
222*15f2bd95SEwan Crawford    "RGB Pixel",
223*15f2bd95SEwan Crawford    "RGBA Pixel",
224*15f2bd95SEwan Crawford    "Pixel Depth",
225*15f2bd95SEwan Crawford    "YUV Pixel"
226*15f2bd95SEwan Crawford };
227*15f2bd95SEwan Crawford 
228*15f2bd95SEwan Crawford const char* RenderScriptRuntime::AllocationDetails::RsDataTypeToString[][4] =
229*15f2bd95SEwan Crawford {
230*15f2bd95SEwan Crawford     {"None", "None", "None", "None"},
231*15f2bd95SEwan Crawford     {"half", "half2", "half3", "half4"},
232*15f2bd95SEwan Crawford     {"float", "float2", "float3", "float4"},
233*15f2bd95SEwan Crawford     {"double", "double2", "double3", "double4"},
234*15f2bd95SEwan Crawford     {"char", "char2", "char3", "char4"},
235*15f2bd95SEwan Crawford     {"short", "short2", "short3", "short4"},
236*15f2bd95SEwan Crawford     {"int", "int2", "int3", "int4"},
237*15f2bd95SEwan Crawford     {"long", "long2", "long3", "long4"},
238*15f2bd95SEwan Crawford     {"uchar", "uchar2", "uchar3", "uchar4"},
239*15f2bd95SEwan Crawford     {"ushort", "ushort2", "ushort3", "ushort4"},
240*15f2bd95SEwan Crawford     {"uint", "uint2", "uint3", "uint4"},
241*15f2bd95SEwan Crawford     {"ulong", "ulong2", "ulong3", "ulong4"},
242*15f2bd95SEwan Crawford     {"bool", "bool2", "bool3", "bool4"}
24378f339d1SEwan Crawford };
24478f339d1SEwan Crawford 
2455ec532a9SColin Riley //------------------------------------------------------------------
2465ec532a9SColin Riley // Static Functions
2475ec532a9SColin Riley //------------------------------------------------------------------
2485ec532a9SColin Riley LanguageRuntime *
2495ec532a9SColin Riley RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType language)
2505ec532a9SColin Riley {
2515ec532a9SColin Riley 
2525ec532a9SColin Riley     if (language == eLanguageTypeExtRenderScript)
2535ec532a9SColin Riley         return new RenderScriptRuntime(process);
2545ec532a9SColin Riley     else
2555ec532a9SColin Riley         return NULL;
2565ec532a9SColin Riley }
2575ec532a9SColin Riley 
25898156583SEwan Crawford // Callback with a module to search for matching symbols.
25998156583SEwan Crawford // We first check that the module contains RS kernels.
26098156583SEwan Crawford // Then look for a symbol which matches our kernel name.
26198156583SEwan Crawford // The breakpoint address is finally set using the address of this symbol.
26298156583SEwan Crawford Searcher::CallbackReturn
26398156583SEwan Crawford RSBreakpointResolver::SearchCallback(SearchFilter &filter,
26498156583SEwan Crawford                                      SymbolContext &context,
26598156583SEwan Crawford                                      Address*,
26698156583SEwan Crawford                                      bool)
26798156583SEwan Crawford {
26898156583SEwan Crawford     ModuleSP module = context.module_sp;
26998156583SEwan Crawford 
27098156583SEwan Crawford     if (!module)
27198156583SEwan Crawford         return Searcher::eCallbackReturnContinue;
27298156583SEwan Crawford 
27398156583SEwan Crawford     // Is this a module containing renderscript kernels?
27498156583SEwan Crawford     if (nullptr == module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData))
27598156583SEwan Crawford         return Searcher::eCallbackReturnContinue;
27698156583SEwan Crawford 
27798156583SEwan Crawford     // Attempt to set a breakpoint on the kernel name symbol within the module library.
27898156583SEwan Crawford     // If it's not found, it's likely debug info is unavailable - try to set a
27998156583SEwan Crawford     // breakpoint on <name>.expand.
28098156583SEwan Crawford 
28198156583SEwan Crawford     const Symbol* kernel_sym = module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode);
28298156583SEwan Crawford     if (!kernel_sym)
28398156583SEwan Crawford     {
28498156583SEwan Crawford         std::string kernel_name_expanded(m_kernel_name.AsCString());
28598156583SEwan Crawford         kernel_name_expanded.append(".expand");
28698156583SEwan Crawford         kernel_sym = module->FindFirstSymbolWithNameAndType(ConstString(kernel_name_expanded.c_str()), eSymbolTypeCode);
28798156583SEwan Crawford     }
28898156583SEwan Crawford 
28998156583SEwan Crawford     if (kernel_sym)
29098156583SEwan Crawford     {
29198156583SEwan Crawford         Address bp_addr = kernel_sym->GetAddress();
29298156583SEwan Crawford         if (filter.AddressPasses(bp_addr))
29398156583SEwan Crawford             m_breakpoint->AddLocation(bp_addr);
29498156583SEwan Crawford     }
29598156583SEwan Crawford 
29698156583SEwan Crawford     return Searcher::eCallbackReturnContinue;
29798156583SEwan Crawford }
29898156583SEwan Crawford 
2995ec532a9SColin Riley void
3005ec532a9SColin Riley RenderScriptRuntime::Initialize()
3015ec532a9SColin Riley {
3024640cde1SColin Riley     PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance, GetCommandObject);
3035ec532a9SColin Riley }
3045ec532a9SColin Riley 
3055ec532a9SColin Riley void
3065ec532a9SColin Riley RenderScriptRuntime::Terminate()
3075ec532a9SColin Riley {
3085ec532a9SColin Riley     PluginManager::UnregisterPlugin(CreateInstance);
3095ec532a9SColin Riley }
3105ec532a9SColin Riley 
3115ec532a9SColin Riley lldb_private::ConstString
3125ec532a9SColin Riley RenderScriptRuntime::GetPluginNameStatic()
3135ec532a9SColin Riley {
3145ec532a9SColin Riley     static ConstString g_name("renderscript");
3155ec532a9SColin Riley     return g_name;
3165ec532a9SColin Riley }
3175ec532a9SColin Riley 
318ef20b08fSColin Riley RenderScriptRuntime::ModuleKind
319ef20b08fSColin Riley RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp)
320ef20b08fSColin Riley {
321ef20b08fSColin Riley     if (module_sp)
322ef20b08fSColin Riley     {
323ef20b08fSColin Riley         // Is this a module containing renderscript kernels?
324ef20b08fSColin Riley         const Symbol *info_sym = module_sp->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
325ef20b08fSColin Riley         if (info_sym)
326ef20b08fSColin Riley         {
327ef20b08fSColin Riley             return eModuleKindKernelObj;
328ef20b08fSColin Riley         }
3294640cde1SColin Riley 
3304640cde1SColin Riley         // Is this the main RS runtime library
3314640cde1SColin Riley         const ConstString rs_lib("libRS.so");
3324640cde1SColin Riley         if (module_sp->GetFileSpec().GetFilename() == rs_lib)
3334640cde1SColin Riley         {
3344640cde1SColin Riley             return eModuleKindLibRS;
3354640cde1SColin Riley         }
3364640cde1SColin Riley 
3374640cde1SColin Riley         const ConstString rs_driverlib("libRSDriver.so");
3384640cde1SColin Riley         if (module_sp->GetFileSpec().GetFilename() == rs_driverlib)
3394640cde1SColin Riley         {
3404640cde1SColin Riley             return eModuleKindDriver;
3414640cde1SColin Riley         }
3424640cde1SColin Riley 
343*15f2bd95SEwan Crawford         const ConstString rs_cpureflib("libRSCpuRef.so");
3444640cde1SColin Riley         if (module_sp->GetFileSpec().GetFilename() == rs_cpureflib)
3454640cde1SColin Riley         {
3464640cde1SColin Riley             return eModuleKindImpl;
3474640cde1SColin Riley         }
3484640cde1SColin Riley 
349ef20b08fSColin Riley     }
350ef20b08fSColin Riley     return eModuleKindIgnored;
351ef20b08fSColin Riley }
352ef20b08fSColin Riley 
353ef20b08fSColin Riley bool
354ef20b08fSColin Riley RenderScriptRuntime::IsRenderScriptModule(const lldb::ModuleSP &module_sp)
355ef20b08fSColin Riley {
356ef20b08fSColin Riley     return GetModuleKind(module_sp) != eModuleKindIgnored;
357ef20b08fSColin Riley }
358ef20b08fSColin Riley 
359ef20b08fSColin Riley 
360ef20b08fSColin Riley void
361ef20b08fSColin Riley RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list )
362ef20b08fSColin Riley {
363ef20b08fSColin Riley     Mutex::Locker locker (module_list.GetMutex ());
364ef20b08fSColin Riley 
365ef20b08fSColin Riley     size_t num_modules = module_list.GetSize();
366ef20b08fSColin Riley     for (size_t i = 0; i < num_modules; i++)
367ef20b08fSColin Riley     {
368ef20b08fSColin Riley         auto mod = module_list.GetModuleAtIndex (i);
369ef20b08fSColin Riley         if (IsRenderScriptModule (mod))
370ef20b08fSColin Riley         {
371ef20b08fSColin Riley             LoadModule(mod);
372ef20b08fSColin Riley         }
373ef20b08fSColin Riley     }
374ef20b08fSColin Riley }
375ef20b08fSColin Riley 
376ef20b08fSColin Riley 
3775ec532a9SColin Riley //------------------------------------------------------------------
3785ec532a9SColin Riley // PluginInterface protocol
3795ec532a9SColin Riley //------------------------------------------------------------------
3805ec532a9SColin Riley lldb_private::ConstString
3815ec532a9SColin Riley RenderScriptRuntime::GetPluginName()
3825ec532a9SColin Riley {
3835ec532a9SColin Riley     return GetPluginNameStatic();
3845ec532a9SColin Riley }
3855ec532a9SColin Riley 
3865ec532a9SColin Riley uint32_t
3875ec532a9SColin Riley RenderScriptRuntime::GetPluginVersion()
3885ec532a9SColin Riley {
3895ec532a9SColin Riley     return 1;
3905ec532a9SColin Riley }
3915ec532a9SColin Riley 
3925ec532a9SColin Riley bool
3935ec532a9SColin Riley RenderScriptRuntime::IsVTableName(const char *name)
3945ec532a9SColin Riley {
3955ec532a9SColin Riley     return false;
3965ec532a9SColin Riley }
3975ec532a9SColin Riley 
3985ec532a9SColin Riley bool
3995ec532a9SColin Riley RenderScriptRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
4000b6003f3SEnrico Granata                                               TypeAndOrName &class_type_or_name, Address &address,
4010b6003f3SEnrico Granata                                               Value::ValueType &value_type)
4025ec532a9SColin Riley {
4035ec532a9SColin Riley     return false;
4045ec532a9SColin Riley }
4055ec532a9SColin Riley 
406c74275bcSEnrico Granata TypeAndOrName
407c74275bcSEnrico Granata RenderScriptRuntime::FixUpDynamicType (const TypeAndOrName& type_and_or_name,
4087eed4877SEnrico Granata                                        ValueObject& static_value)
409c74275bcSEnrico Granata {
410c74275bcSEnrico Granata     return type_and_or_name;
411c74275bcSEnrico Granata }
412c74275bcSEnrico Granata 
4135ec532a9SColin Riley bool
4145ec532a9SColin Riley RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value)
4155ec532a9SColin Riley {
4165ec532a9SColin Riley     return false;
4175ec532a9SColin Riley }
4185ec532a9SColin Riley 
4195ec532a9SColin Riley lldb::BreakpointResolverSP
4205ec532a9SColin Riley RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp)
4215ec532a9SColin Riley {
4225ec532a9SColin Riley     BreakpointResolverSP resolver_sp;
4235ec532a9SColin Riley     return resolver_sp;
4245ec532a9SColin Riley }
4255ec532a9SColin Riley 
4264640cde1SColin Riley 
4274640cde1SColin Riley const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] =
4284640cde1SColin Riley {
4294640cde1SColin Riley     //rsdScript
43082780287SAidan Dodds     {
43182780287SAidan Dodds         "rsdScriptInit", //name
43282780287SAidan Dodds         "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhjj", // symbol name 32 bit
43382780287SAidan Dodds         "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhmj", // symbol name 64 bit
43482780287SAidan Dodds         0, // version
43582780287SAidan Dodds         RenderScriptRuntime::eModuleKindDriver, // type
43682780287SAidan Dodds         &lldb_private::RenderScriptRuntime::CaptureScriptInit1 // handler
43782780287SAidan Dodds     },
43882780287SAidan Dodds     {
43982780287SAidan Dodds         "rsdScriptInvokeForEach", // name
44082780287SAidan Dodds         "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvjPK12RsScriptCall", // symbol name 32bit
44182780287SAidan Dodds         "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvmPK12RsScriptCall", // symbol name 64bit
44282780287SAidan Dodds         0, // version
44382780287SAidan Dodds         RenderScriptRuntime::eModuleKindDriver, // type
44482780287SAidan Dodds         nullptr // handler
44582780287SAidan Dodds     },
44682780287SAidan Dodds     {
44782780287SAidan Dodds         "rsdScriptInvokeForEachMulti", // name
44882780287SAidan Dodds         "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall", // symbol name 32bit
44982780287SAidan Dodds         "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEmPS6_PKvmPK12RsScriptCall", // symbol name 64bit
45082780287SAidan Dodds         0, // version
45182780287SAidan Dodds         RenderScriptRuntime::eModuleKindDriver, // type
45282780287SAidan Dodds         nullptr // handler
45382780287SAidan Dodds     },
45482780287SAidan Dodds     {
45582780287SAidan Dodds         "rsdScriptInvokeFunction", // name
45682780287SAidan Dodds         "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvj", // symbol name 32bit
45782780287SAidan Dodds         "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvm", // symbol name 64bit
45882780287SAidan Dodds         0, // version
45982780287SAidan Dodds         RenderScriptRuntime::eModuleKindDriver, // type
46082780287SAidan Dodds         nullptr // handler
46182780287SAidan Dodds     },
46282780287SAidan Dodds     {
46382780287SAidan Dodds         "rsdScriptSetGlobalVar", // name
46482780287SAidan Dodds         "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvj", // symbol name 32bit
46582780287SAidan Dodds         "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvm", // symbol name 64bit
46682780287SAidan Dodds         0, // version
46782780287SAidan Dodds         RenderScriptRuntime::eModuleKindDriver, // type
46882780287SAidan Dodds         &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar1 // handler
46982780287SAidan Dodds     },
4704640cde1SColin Riley 
4714640cde1SColin Riley     //rsdAllocation
47282780287SAidan Dodds     {
47382780287SAidan Dodds         "rsdAllocationInit", // name
47482780287SAidan Dodds         "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 32bit
47582780287SAidan Dodds         "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 64bit
47682780287SAidan Dodds         0, // version
47782780287SAidan Dodds         RenderScriptRuntime::eModuleKindDriver, // type
47882780287SAidan Dodds         &lldb_private::RenderScriptRuntime::CaptureAllocationInit1 // handler
47982780287SAidan Dodds     },
48082780287SAidan Dodds     {
48182780287SAidan Dodds         "rsdAllocationRead2D", //name
48282780287SAidan Dodds         "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvjj", // symbol name 32bit
48382780287SAidan Dodds         "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvmm", // symbol name 64bit
48482780287SAidan Dodds         0, // version
48582780287SAidan Dodds         RenderScriptRuntime::eModuleKindDriver, // type
48682780287SAidan Dodds         nullptr // handler
48782780287SAidan Dodds     },
4884640cde1SColin Riley };
4894640cde1SColin Riley const size_t RenderScriptRuntime::s_runtimeHookCount = sizeof(s_runtimeHookDefns)/sizeof(s_runtimeHookDefns[0]);
4904640cde1SColin Riley 
4914640cde1SColin Riley 
4924640cde1SColin Riley bool
4934640cde1SColin Riley RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
4944640cde1SColin Riley {
4954640cde1SColin Riley     RuntimeHook* hook_info = (RuntimeHook*)baton;
4964640cde1SColin Riley     ExecutionContext context(ctx->exe_ctx_ref);
4974640cde1SColin Riley 
4984640cde1SColin Riley     RenderScriptRuntime *lang_rt = (RenderScriptRuntime *)context.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
4994640cde1SColin Riley 
5004640cde1SColin Riley     lang_rt->HookCallback(hook_info, context);
5014640cde1SColin Riley 
5024640cde1SColin Riley     return false;
5034640cde1SColin Riley }
5044640cde1SColin Riley 
5054640cde1SColin Riley 
5064640cde1SColin Riley void
5074640cde1SColin Riley RenderScriptRuntime::HookCallback(RuntimeHook* hook_info, ExecutionContext& context)
5084640cde1SColin Riley {
5094640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
5104640cde1SColin Riley 
5114640cde1SColin Riley     if (log)
5124640cde1SColin Riley         log->Printf ("RenderScriptRuntime::HookCallback - '%s' .", hook_info->defn->name);
5134640cde1SColin Riley 
5144640cde1SColin Riley     if (hook_info->defn->grabber)
5154640cde1SColin Riley     {
5164640cde1SColin Riley         (this->*(hook_info->defn->grabber))(hook_info, context);
5174640cde1SColin Riley     }
5184640cde1SColin Riley }
5194640cde1SColin Riley 
5204640cde1SColin Riley 
5214640cde1SColin Riley bool
52282780287SAidan Dodds RenderScriptRuntime::GetArgSimple(ExecutionContext &context, uint32_t arg, uint64_t *data)
5234640cde1SColin Riley {
5244640cde1SColin Riley     if (!data)
5254640cde1SColin Riley         return false;
5264640cde1SColin Riley 
52782780287SAidan Dodds     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
5284640cde1SColin Riley     Error error;
5294640cde1SColin Riley     RegisterContext* reg_ctx = context.GetRegisterContext();
5304640cde1SColin Riley     Process* process = context.GetProcessPtr();
53182780287SAidan Dodds     bool success = false; // return value
5324640cde1SColin Riley 
53382780287SAidan Dodds     if (!context.GetTargetPtr())
53482780287SAidan Dodds     {
53582780287SAidan Dodds         if (log)
53682780287SAidan Dodds             log->Printf("RenderScriptRuntime::GetArgSimple - Invalid target");
53782780287SAidan Dodds 
53882780287SAidan Dodds         return false;
53982780287SAidan Dodds     }
54082780287SAidan Dodds 
54182780287SAidan Dodds     switch (context.GetTargetPtr()->GetArchitecture().GetMachine())
54282780287SAidan Dodds     {
54382780287SAidan Dodds         case llvm::Triple::ArchType::x86:
5444640cde1SColin Riley         {
5454640cde1SColin Riley             uint64_t sp = reg_ctx->GetSP();
5464640cde1SColin Riley             uint32_t offset = (1 + arg) * sizeof(uint32_t);
54782780287SAidan Dodds             uint32_t result = 0;
54882780287SAidan Dodds             process->ReadMemory(sp + offset, &result, sizeof(uint32_t), error);
5494640cde1SColin Riley             if (error.Fail())
5504640cde1SColin Riley             {
5514640cde1SColin Riley                 if (log)
55282780287SAidan Dodds                     log->Printf ("RenderScriptRuntime:: GetArgSimple - error reading X86 stack: %s.", error.AsCString());
5534640cde1SColin Riley             }
55482780287SAidan Dodds             else
5554640cde1SColin Riley             {
55682780287SAidan Dodds                 *data = result;
55782780287SAidan Dodds                 success = true;
55882780287SAidan Dodds             }
55982780287SAidan Dodds 
56082780287SAidan Dodds             break;
56182780287SAidan Dodds         }
56282780287SAidan Dodds         case llvm::Triple::ArchType::arm:
56382780287SAidan Dodds         {
56482780287SAidan Dodds             // arm 32 bit
5654640cde1SColin Riley             if (arg < 4)
5664640cde1SColin Riley             {
5674640cde1SColin Riley                 const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg);
5684640cde1SColin Riley                 RegisterValue rVal;
5694640cde1SColin Riley                 reg_ctx->ReadRegister(rArg, rVal);
5704640cde1SColin Riley                 (*data) = rVal.GetAsUInt32();
57182780287SAidan Dodds                 success = true;
5724640cde1SColin Riley             }
5734640cde1SColin Riley             else
5744640cde1SColin Riley             {
5754640cde1SColin Riley                 uint64_t sp = reg_ctx->GetSP();
5764640cde1SColin Riley                 {
5774640cde1SColin Riley                     uint32_t offset = (arg-4) * sizeof(uint32_t);
5784640cde1SColin Riley                     process->ReadMemory(sp + offset, &data, sizeof(uint32_t), error);
5794640cde1SColin Riley                     if (error.Fail())
5804640cde1SColin Riley                     {
5814640cde1SColin Riley                         if (log)
58282780287SAidan Dodds                             log->Printf ("RenderScriptRuntime:: GetArgSimple - error reading ARM stack: %s.", error.AsCString());
58382780287SAidan Dodds                     }
58482780287SAidan Dodds                     else
58582780287SAidan Dodds                     {
58682780287SAidan Dodds                         success = true;
5874640cde1SColin Riley                     }
5884640cde1SColin Riley                 }
5894640cde1SColin Riley             }
59082780287SAidan Dodds 
59182780287SAidan Dodds             break;
5924640cde1SColin Riley         }
59382780287SAidan Dodds         case llvm::Triple::ArchType::aarch64:
59482780287SAidan Dodds         {
59582780287SAidan Dodds             // arm 64 bit
59682780287SAidan Dodds             // first 8 arguments are in the registers
59782780287SAidan Dodds             if (arg < 8)
59882780287SAidan Dodds             {
59982780287SAidan Dodds                 const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg);
60082780287SAidan Dodds                 RegisterValue rVal;
60182780287SAidan Dodds                 success = reg_ctx->ReadRegister(rArg, rVal);
60282780287SAidan Dodds                 if (success)
60382780287SAidan Dodds                 {
60482780287SAidan Dodds                     *data = rVal.GetAsUInt64();
60582780287SAidan Dodds                 }
60682780287SAidan Dodds                 else
60782780287SAidan Dodds                 {
60882780287SAidan Dodds                     if (log)
60982780287SAidan Dodds                         log->Printf("RenderScriptRuntime::GetArgSimple() - AARCH64 - Error while reading the argument #%d", arg);
61082780287SAidan Dodds                 }
61182780287SAidan Dodds             }
61282780287SAidan Dodds             else
61382780287SAidan Dodds             {
61482780287SAidan Dodds                 // @TODO: need to find the argument in the stack
61582780287SAidan Dodds                 if (log)
61682780287SAidan Dodds                     log->Printf("RenderScriptRuntime::GetArgSimple - AARCH64 - FOR #ARG >= 8 NOT IMPLEMENTED YET. Argument number: %d", arg);
61782780287SAidan Dodds             }
61882780287SAidan Dodds             break;
61982780287SAidan Dodds         }
62082780287SAidan Dodds         default:
62182780287SAidan Dodds         {
62282780287SAidan Dodds             // invalid architecture
62382780287SAidan Dodds             if (log)
62482780287SAidan Dodds                 log->Printf("RenderScriptRuntime::GetArgSimple - Architecture not supported");
62582780287SAidan Dodds 
62682780287SAidan Dodds         }
62782780287SAidan Dodds     }
62882780287SAidan Dodds 
62982780287SAidan Dodds 
63082780287SAidan Dodds     return success;
6314640cde1SColin Riley }
6324640cde1SColin Riley 
6334640cde1SColin Riley void
6344640cde1SColin Riley RenderScriptRuntime::CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context)
6354640cde1SColin Riley {
6364640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
6374640cde1SColin Riley 
6384640cde1SColin Riley     //Context, Script, int, data, length
6394640cde1SColin Riley 
64082780287SAidan Dodds     uint64_t rs_context_u64 = 0U;
64182780287SAidan Dodds     uint64_t rs_script_u64 = 0U;
64282780287SAidan Dodds     uint64_t rs_id_u64 = 0U;
64382780287SAidan Dodds     uint64_t rs_data_u64 = 0U;
64482780287SAidan Dodds     uint64_t rs_length_u64 = 0U;
6454640cde1SColin Riley 
64682780287SAidan Dodds     bool success =
64782780287SAidan Dodds         GetArgSimple(context, 0, &rs_context_u64) &&
64882780287SAidan Dodds         GetArgSimple(context, 1, &rs_script_u64) &&
64982780287SAidan Dodds         GetArgSimple(context, 2, &rs_id_u64) &&
65082780287SAidan Dodds         GetArgSimple(context, 3, &rs_data_u64) &&
65182780287SAidan Dodds         GetArgSimple(context, 4, &rs_length_u64);
6524640cde1SColin Riley 
65382780287SAidan Dodds     if (!success)
65482780287SAidan Dodds     {
65582780287SAidan Dodds         if (log)
65682780287SAidan Dodds             log->Printf("RenderScriptRuntime::CaptureSetGlobalVar1 - Error while reading the function parameters");
65782780287SAidan Dodds         return;
65882780287SAidan Dodds     }
6594640cde1SColin Riley 
6604640cde1SColin Riley     if (log)
6614640cde1SColin Riley     {
6624640cde1SColin Riley         log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 ":%" PRIu64 "bytes.",
66382780287SAidan Dodds                         rs_context_u64, rs_script_u64, rs_id_u64, rs_data_u64, rs_length_u64);
6644640cde1SColin Riley 
66582780287SAidan Dodds         addr_t script_addr =  (addr_t)rs_script_u64;
6664640cde1SColin Riley         if (m_scriptMappings.find( script_addr ) != m_scriptMappings.end())
6674640cde1SColin Riley         {
6684640cde1SColin Riley             auto rsm = m_scriptMappings[script_addr];
66982780287SAidan Dodds             if (rs_id_u64 < rsm->m_globals.size())
6704640cde1SColin Riley             {
67182780287SAidan Dodds                 auto rsg = rsm->m_globals[rs_id_u64];
6724640cde1SColin Riley                 log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - Setting of '%s' within '%s' inferred", rsg.m_name.AsCString(),
6734640cde1SColin Riley                                 rsm->m_module->GetFileSpec().GetFilename().AsCString());
6744640cde1SColin Riley             }
6754640cde1SColin Riley         }
6764640cde1SColin Riley     }
6774640cde1SColin Riley }
6784640cde1SColin Riley 
6794640cde1SColin Riley void
6804640cde1SColin Riley RenderScriptRuntime::CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context)
6814640cde1SColin Riley {
6824640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
6834640cde1SColin Riley 
6844640cde1SColin Riley     //Context, Alloc, bool
6854640cde1SColin Riley 
68682780287SAidan Dodds     uint64_t rs_context_u64 = 0U;
68782780287SAidan Dodds     uint64_t rs_alloc_u64 = 0U;
68882780287SAidan Dodds     uint64_t rs_forceZero_u64 = 0U;
6894640cde1SColin Riley 
69082780287SAidan Dodds     bool success =
69182780287SAidan Dodds         GetArgSimple(context, 0, &rs_context_u64) &&
69282780287SAidan Dodds         GetArgSimple(context, 1, &rs_alloc_u64) &&
69382780287SAidan Dodds         GetArgSimple(context, 2, &rs_forceZero_u64);
69482780287SAidan Dodds     if (!success) // error case
69582780287SAidan Dodds     {
69682780287SAidan Dodds         if (log)
69782780287SAidan Dodds             log->Printf("RenderScriptRuntime::CaptureAllocationInit1 - Error while reading the function parameters");
69882780287SAidan Dodds         return; // abort
69982780287SAidan Dodds     }
7004640cde1SColin Riley 
7014640cde1SColin Riley     if (log)
7024640cde1SColin Riley         log->Printf ("RenderScriptRuntime::CaptureAllocationInit1 - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .",
70382780287SAidan Dodds                         rs_context_u64, rs_alloc_u64, rs_forceZero_u64);
70478f339d1SEwan Crawford 
70578f339d1SEwan Crawford     AllocationDetails* alloc = LookUpAllocation(rs_alloc_u64, true);
70678f339d1SEwan Crawford     if (alloc)
70778f339d1SEwan Crawford         alloc->context = rs_context_u64;
7084640cde1SColin Riley }
7094640cde1SColin Riley 
7104640cde1SColin Riley void
7114640cde1SColin Riley RenderScriptRuntime::CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context)
7124640cde1SColin Riley {
7134640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
7144640cde1SColin Riley 
7154640cde1SColin Riley     //Context, Script, resname Str, cachedir Str
7164640cde1SColin Riley     Error error;
7174640cde1SColin Riley     Process* process = context.GetProcessPtr();
7184640cde1SColin Riley 
71982780287SAidan Dodds     uint64_t rs_context_u64 = 0U;
72082780287SAidan Dodds     uint64_t rs_script_u64 = 0U;
72182780287SAidan Dodds     uint64_t rs_resnameptr_u64 = 0U;
72282780287SAidan Dodds     uint64_t rs_cachedirptr_u64 = 0U;
7234640cde1SColin Riley 
7244640cde1SColin Riley     std::string resname;
7254640cde1SColin Riley     std::string cachedir;
7264640cde1SColin Riley 
72782780287SAidan Dodds     // read the function parameters
72882780287SAidan Dodds     bool success =
72982780287SAidan Dodds         GetArgSimple(context, 0, &rs_context_u64) &&
73082780287SAidan Dodds         GetArgSimple(context, 1, &rs_script_u64) &&
73182780287SAidan Dodds         GetArgSimple(context, 2, &rs_resnameptr_u64) &&
73282780287SAidan Dodds         GetArgSimple(context, 3, &rs_cachedirptr_u64);
7334640cde1SColin Riley 
73482780287SAidan Dodds     if (!success)
73582780287SAidan Dodds     {
73682780287SAidan Dodds         if (log)
73782780287SAidan Dodds             log->Printf("RenderScriptRuntime::CaptureScriptInit1 - Error while reading the function parameters");
73882780287SAidan Dodds         return;
73982780287SAidan Dodds     }
74082780287SAidan Dodds 
74182780287SAidan Dodds     process->ReadCStringFromMemory((lldb::addr_t)rs_resnameptr_u64, resname, error);
7424640cde1SColin Riley     if (error.Fail())
7434640cde1SColin Riley     {
7444640cde1SColin Riley         if (log)
7454640cde1SColin Riley             log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading resname: %s.", error.AsCString());
7464640cde1SColin Riley 
7474640cde1SColin Riley     }
7484640cde1SColin Riley 
74982780287SAidan Dodds     process->ReadCStringFromMemory((lldb::addr_t)rs_cachedirptr_u64, cachedir, error);
7504640cde1SColin Riley     if (error.Fail())
7514640cde1SColin Riley     {
7524640cde1SColin Riley         if (log)
7534640cde1SColin Riley             log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading cachedir: %s.", error.AsCString());
7544640cde1SColin Riley     }
7554640cde1SColin Riley 
7564640cde1SColin Riley     if (log)
7574640cde1SColin Riley         log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .",
75882780287SAidan Dodds                      rs_context_u64, rs_script_u64, resname.c_str(), cachedir.c_str());
7594640cde1SColin Riley 
7604640cde1SColin Riley     if (resname.size() > 0)
7614640cde1SColin Riley     {
7624640cde1SColin Riley         StreamString strm;
7634640cde1SColin Riley         strm.Printf("librs.%s.so", resname.c_str());
7644640cde1SColin Riley 
76578f339d1SEwan Crawford         ScriptDetails* script = LookUpScript(rs_script_u64, true);
76678f339d1SEwan Crawford         if (script)
76778f339d1SEwan Crawford         {
76878f339d1SEwan Crawford             script->type = ScriptDetails::eScriptC;
76978f339d1SEwan Crawford             script->cacheDir = cachedir;
77078f339d1SEwan Crawford             script->resName = resname;
77178f339d1SEwan Crawford             script->scriptDyLib = strm.GetData();
77278f339d1SEwan Crawford             script->context = addr_t(rs_context_u64);
77378f339d1SEwan Crawford         }
7744640cde1SColin Riley 
7754640cde1SColin Riley         if (log)
7764640cde1SColin Riley             log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - '%s' tagged with context 0x%" PRIx64 " and script 0x%" PRIx64 ".",
77782780287SAidan Dodds                          strm.GetData(), rs_context_u64, rs_script_u64);
7784640cde1SColin Riley     }
7794640cde1SColin Riley     else if (log)
7804640cde1SColin Riley     {
7814640cde1SColin Riley         log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - resource name invalid, Script not tagged");
7824640cde1SColin Riley     }
7834640cde1SColin Riley 
7844640cde1SColin Riley }
7854640cde1SColin Riley 
7864640cde1SColin Riley void
7874640cde1SColin Riley RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
7884640cde1SColin Riley {
7894640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
7904640cde1SColin Riley 
7914640cde1SColin Riley     if (!module)
7924640cde1SColin Riley     {
7934640cde1SColin Riley         return;
7944640cde1SColin Riley     }
7954640cde1SColin Riley 
79682780287SAidan Dodds     Target &target = GetProcess()->GetTarget();
79782780287SAidan Dodds     llvm::Triple::ArchType targetArchType = target.GetArchitecture().GetMachine();
79882780287SAidan Dodds 
79982780287SAidan Dodds     if (targetArchType != llvm::Triple::ArchType::x86
80082780287SAidan Dodds         && targetArchType != llvm::Triple::ArchType::arm
80182780287SAidan Dodds         && targetArchType != llvm::Triple::ArchType::aarch64)
8024640cde1SColin Riley     {
8034640cde1SColin Riley         if (log)
8044640cde1SColin Riley             log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to hook runtime. Only X86, ARM supported currently.");
8054640cde1SColin Riley 
8064640cde1SColin Riley         return;
8074640cde1SColin Riley     }
8084640cde1SColin Riley 
80982780287SAidan Dodds     uint32_t archByteSize = target.GetArchitecture().GetAddressByteSize();
8104640cde1SColin Riley 
8114640cde1SColin Riley     for (size_t idx = 0; idx < s_runtimeHookCount; idx++)
8124640cde1SColin Riley     {
8134640cde1SColin Riley         const HookDefn* hook_defn = &s_runtimeHookDefns[idx];
8144640cde1SColin Riley         if (hook_defn->kind != kind) {
8154640cde1SColin Riley             continue;
8164640cde1SColin Riley         }
8174640cde1SColin Riley 
81882780287SAidan Dodds         const char* symbol_name = (archByteSize == 4) ? hook_defn->symbol_name_m32 : hook_defn->symbol_name_m64;
81982780287SAidan Dodds 
82082780287SAidan Dodds         const Symbol *sym = module->FindFirstSymbolWithNameAndType(ConstString(symbol_name), eSymbolTypeCode);
82182780287SAidan Dodds         if (!sym){
82282780287SAidan Dodds             if (log){
82382780287SAidan Dodds                 log->Printf("RenderScriptRuntime::LoadRuntimeHooks - ERROR: Symbol '%s' related to the function %s not found", symbol_name, hook_defn->name);
82482780287SAidan Dodds             }
82582780287SAidan Dodds             continue;
82682780287SAidan Dodds         }
8274640cde1SColin Riley 
828358cf1eaSGreg Clayton         addr_t addr = sym->GetLoadAddress(&target);
8294640cde1SColin Riley         if (addr == LLDB_INVALID_ADDRESS)
8304640cde1SColin Riley         {
8314640cde1SColin Riley             if (log)
8324640cde1SColin Riley                 log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to resolve the address of hook function '%s' with symbol '%s'.",
83382780287SAidan Dodds                              hook_defn->name, symbol_name);
8344640cde1SColin Riley             continue;
8354640cde1SColin Riley         }
83682780287SAidan Dodds         else
83782780287SAidan Dodds         {
83882780287SAidan Dodds             if (log)
83982780287SAidan Dodds                 log->Printf("RenderScriptRuntime::LoadRuntimeHooks - Function %s, address resolved at 0x%" PRIx64, hook_defn->name, addr);
84082780287SAidan Dodds         }
8414640cde1SColin Riley 
8424640cde1SColin Riley         RuntimeHookSP hook(new RuntimeHook());
8434640cde1SColin Riley         hook->address = addr;
8444640cde1SColin Riley         hook->defn = hook_defn;
8454640cde1SColin Riley         hook->bp_sp = target.CreateBreakpoint(addr, true, false);
8464640cde1SColin Riley         hook->bp_sp->SetCallback(HookCallback, hook.get(), true);
8474640cde1SColin Riley         m_runtimeHooks[addr] = hook;
8484640cde1SColin Riley         if (log)
8494640cde1SColin Riley         {
8504640cde1SColin Riley             log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Successfully hooked '%s' in '%s' version %" PRIu64 " at 0x%" PRIx64 ".",
8514640cde1SColin Riley                 hook_defn->name, module->GetFileSpec().GetFilename().AsCString(), (uint64_t)hook_defn->version, (uint64_t)addr);
8524640cde1SColin Riley         }
8534640cde1SColin Riley     }
8544640cde1SColin Riley }
8554640cde1SColin Riley 
8564640cde1SColin Riley void
8574640cde1SColin Riley RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp)
8584640cde1SColin Riley {
8594640cde1SColin Riley     if (!rsmodule_sp)
8604640cde1SColin Riley         return;
8614640cde1SColin Riley 
8624640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
8634640cde1SColin Riley 
8644640cde1SColin Riley     const ModuleSP module = rsmodule_sp->m_module;
8654640cde1SColin Riley     const FileSpec& file = module->GetPlatformFileSpec();
8664640cde1SColin Riley 
86778f339d1SEwan Crawford     // Iterate over all of the scripts that we currently know of.
86878f339d1SEwan Crawford     // Note: We cant push or pop to m_scripts here or it may invalidate rs_script.
8694640cde1SColin Riley     for (const auto & rs_script : m_scripts)
8704640cde1SColin Riley     {
87178f339d1SEwan Crawford         // Extract the expected .so file path for this script.
87278f339d1SEwan Crawford         std::string dylib;
87378f339d1SEwan Crawford         if (!rs_script->scriptDyLib.get(dylib))
87478f339d1SEwan Crawford             continue;
87578f339d1SEwan Crawford 
87678f339d1SEwan Crawford         // Only proceed if the module that has loaded corresponds to this script.
87778f339d1SEwan Crawford         if (file.GetFilename() != ConstString(dylib.c_str()))
87878f339d1SEwan Crawford             continue;
87978f339d1SEwan Crawford 
88078f339d1SEwan Crawford         // Obtain the script address which we use as a key.
88178f339d1SEwan Crawford         lldb::addr_t script;
88278f339d1SEwan Crawford         if (!rs_script->script.get(script))
88378f339d1SEwan Crawford             continue;
88478f339d1SEwan Crawford 
88578f339d1SEwan Crawford         // If we have a script mapping for the current script.
88678f339d1SEwan Crawford         if (m_scriptMappings.find(script) != m_scriptMappings.end())
8874640cde1SColin Riley         {
88878f339d1SEwan Crawford             // if the module we have stored is different to the one we just received.
88978f339d1SEwan Crawford             if (m_scriptMappings[script] != rsmodule_sp)
8904640cde1SColin Riley             {
8914640cde1SColin Riley                 if (log)
8924640cde1SColin Riley                     log->Printf ("RenderScriptRuntime::FixupScriptDetails - Error: script %" PRIx64 " wants reassigned to new rsmodule '%s'.",
89378f339d1SEwan Crawford                                     (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
8944640cde1SColin Riley             }
8954640cde1SColin Riley         }
89678f339d1SEwan Crawford         // We don't have a script mapping for the current script.
8974640cde1SColin Riley         else
8984640cde1SColin Riley         {
89978f339d1SEwan Crawford             // Obtain the script resource name.
90078f339d1SEwan Crawford             std::string resName;
90178f339d1SEwan Crawford             if (rs_script->resName.get(resName))
90278f339d1SEwan Crawford                 // Set the modules resource name.
90378f339d1SEwan Crawford                 rsmodule_sp->m_resname = resName;
90478f339d1SEwan Crawford             // Add Script/Module pair to map.
90578f339d1SEwan Crawford             m_scriptMappings[script] = rsmodule_sp;
9064640cde1SColin Riley             if (log)
9074640cde1SColin Riley                 log->Printf ("RenderScriptRuntime::FixupScriptDetails - script %" PRIx64 " associated with rsmodule '%s'.",
90878f339d1SEwan Crawford                                 (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
9094640cde1SColin Riley         }
9104640cde1SColin Riley     }
9114640cde1SColin Riley }
9124640cde1SColin Riley 
913*15f2bd95SEwan Crawford // Uses the Target API to evaluate the expression passed as a parameter to the function
914*15f2bd95SEwan Crawford // The result of that expression is returned an unsigned 64 bit int, via the result* paramter.
915*15f2bd95SEwan Crawford // Function returns true on success, and false on failure
916*15f2bd95SEwan Crawford bool
917*15f2bd95SEwan Crawford RenderScriptRuntime::EvalRSExpression(const char* expression, StackFrame* frame_ptr, uint64_t* result)
918*15f2bd95SEwan Crawford {
919*15f2bd95SEwan Crawford     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
920*15f2bd95SEwan Crawford     if (log)
921*15f2bd95SEwan Crawford         log->Printf("RenderScriptRuntime::EvalRSExpression(%s)", expression);
922*15f2bd95SEwan Crawford 
923*15f2bd95SEwan Crawford     ValueObjectSP expr_result;
924*15f2bd95SEwan Crawford     // Perform the actual expression evaluation
925*15f2bd95SEwan Crawford     GetProcess()->GetTarget().EvaluateExpression(expression, frame_ptr, expr_result);
926*15f2bd95SEwan Crawford 
927*15f2bd95SEwan Crawford     if (!expr_result)
928*15f2bd95SEwan Crawford     {
929*15f2bd95SEwan Crawford        if (log)
930*15f2bd95SEwan Crawford            log->Printf("RenderScriptRuntime::EvalRSExpression -  Error: Couldn't evaluate expression");
931*15f2bd95SEwan Crawford        return false;
932*15f2bd95SEwan Crawford     }
933*15f2bd95SEwan Crawford 
934*15f2bd95SEwan Crawford     // The result of the expression is invalid
935*15f2bd95SEwan Crawford     if (!expr_result->GetError().Success())
936*15f2bd95SEwan Crawford     {
937*15f2bd95SEwan Crawford         Error err = expr_result->GetError();
938*15f2bd95SEwan Crawford         if (err.GetError() == UserExpression::kNoResult) // Expression returned void, so this is actually a success
939*15f2bd95SEwan Crawford         {
940*15f2bd95SEwan Crawford             if (log)
941*15f2bd95SEwan Crawford                 log->Printf("RenderScriptRuntime::EvalRSExpression - Expression returned void");
942*15f2bd95SEwan Crawford 
943*15f2bd95SEwan Crawford             result = nullptr;
944*15f2bd95SEwan Crawford             return true;
945*15f2bd95SEwan Crawford         }
946*15f2bd95SEwan Crawford 
947*15f2bd95SEwan Crawford         if (log)
948*15f2bd95SEwan Crawford             log->Printf("RenderScriptRuntime::EvalRSExpression - Error evaluating expression result: %s", err.AsCString());
949*15f2bd95SEwan Crawford         return false;
950*15f2bd95SEwan Crawford     }
951*15f2bd95SEwan Crawford 
952*15f2bd95SEwan Crawford     bool success = false;
953*15f2bd95SEwan Crawford     *result = expr_result->GetValueAsUnsigned(0, &success); // We only read the result as an unsigned int.
954*15f2bd95SEwan Crawford 
955*15f2bd95SEwan Crawford     if (!success)
956*15f2bd95SEwan Crawford     {
957*15f2bd95SEwan Crawford        if (log)
958*15f2bd95SEwan Crawford            log->Printf("RenderScriptRuntime::EvalRSExpression -  Error: Couldn't convert expression result to unsigned int");
959*15f2bd95SEwan Crawford        return false;
960*15f2bd95SEwan Crawford     }
961*15f2bd95SEwan Crawford 
962*15f2bd95SEwan Crawford     return true;
963*15f2bd95SEwan Crawford }
964*15f2bd95SEwan Crawford 
965*15f2bd95SEwan Crawford // Used to index expression format strings
966*15f2bd95SEwan Crawford enum ExpressionStrings
967*15f2bd95SEwan Crawford {
968*15f2bd95SEwan Crawford    eExprGetOffsetPtr = 0,
969*15f2bd95SEwan Crawford    eExprAllocGetType,
970*15f2bd95SEwan Crawford    eExprTypeDimX,
971*15f2bd95SEwan Crawford    eExprTypeDimY,
972*15f2bd95SEwan Crawford    eExprTypeDimZ,
973*15f2bd95SEwan Crawford    eExprTypeElemPtr,
974*15f2bd95SEwan Crawford    eExprElementType,
975*15f2bd95SEwan Crawford    eExprElementKind,
976*15f2bd95SEwan Crawford    eExprElementVec
977*15f2bd95SEwan Crawford };
978*15f2bd95SEwan Crawford 
979*15f2bd95SEwan Crawford // Format strings containing the expressions we may need to evaluate.
980*15f2bd95SEwan Crawford const char runtimeExpressions[][256] =
981*15f2bd95SEwan Crawford {
982*15f2bd95SEwan Crawford  // Mangled GetOffsetPointer(Allocation*, xoff, yoff, zoff, lod, cubemap)
983*15f2bd95SEwan Crawford  "(int*)_Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocationCubemapFace(0x%lx, %u, %u, %u, 0, 0)",
984*15f2bd95SEwan Crawford 
985*15f2bd95SEwan Crawford  // Type* rsaAllocationGetType(Context*, Allocation*)
986*15f2bd95SEwan Crawford  "(void*)rsaAllocationGetType(0x%lx, 0x%lx)",
987*15f2bd95SEwan Crawford 
988*15f2bd95SEwan Crawford  // rsaTypeGetNativeData(Context*, Type*, void* typeData, size)
989*15f2bd95SEwan Crawford  // Pack the data in the following way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ;
990*15f2bd95SEwan Crawford  // mHal.state.lodCount; mHal.state.faces; mElement; into typeData
991*15f2bd95SEwan Crawford  // Need to specify 32 or 64 bit for uint_t since this differs between devices
992*15f2bd95SEwan Crawford  "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[0]", // X dim
993*15f2bd95SEwan Crawford  "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[1]", // Y dim
994*15f2bd95SEwan Crawford  "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[2]", // Z dim
995*15f2bd95SEwan Crawford  "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[5]", // Element ptr
996*15f2bd95SEwan Crawford 
997*15f2bd95SEwan Crawford  // rsaElementGetNativeData(Context*, Element*, uint32_t* elemData,size)
998*15f2bd95SEwan Crawford  // Pack mType; mKind; mNormalized; mVectorSize; NumSubElements into elemData
999*15f2bd95SEwan Crawford  "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[0]", // Type
1000*15f2bd95SEwan Crawford  "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[1]", // Kind
1001*15f2bd95SEwan Crawford  "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[3]"  // Vector Size
1002*15f2bd95SEwan Crawford };
1003*15f2bd95SEwan Crawford 
1004*15f2bd95SEwan Crawford // JITs the RS runtime for the internal data pointer of an allocation.
1005*15f2bd95SEwan Crawford // Is passed x,y,z coordinates for the pointer to a specific element.
1006*15f2bd95SEwan Crawford // Then sets the data_ptr member in Allocation with the result.
1007*15f2bd95SEwan Crawford // Returns true on success, false otherwise
1008*15f2bd95SEwan Crawford bool
1009*15f2bd95SEwan Crawford RenderScriptRuntime::JITDataPointer(AllocationDetails* allocation, StackFrame* frame_ptr,
1010*15f2bd95SEwan Crawford                                     unsigned int x, unsigned int y, unsigned int z)
1011*15f2bd95SEwan Crawford {
1012*15f2bd95SEwan Crawford     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1013*15f2bd95SEwan Crawford 
1014*15f2bd95SEwan Crawford     if (!allocation->address.isValid())
1015*15f2bd95SEwan Crawford     {
1016*15f2bd95SEwan Crawford         if (log)
1017*15f2bd95SEwan Crawford             log->Printf("RenderScriptRuntime::JITDataPointer - Failed to find allocation details");
1018*15f2bd95SEwan Crawford         return false;
1019*15f2bd95SEwan Crawford     }
1020*15f2bd95SEwan Crawford 
1021*15f2bd95SEwan Crawford     const char* expr_cstr = runtimeExpressions[eExprGetOffsetPtr];
1022*15f2bd95SEwan Crawford     const int max_expr_size = 512; // Max expression size
1023*15f2bd95SEwan Crawford     char buffer[max_expr_size];
1024*15f2bd95SEwan Crawford 
1025*15f2bd95SEwan Crawford     int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->address.get(), x, y, z);
1026*15f2bd95SEwan Crawford     if (chars_written < 0)
1027*15f2bd95SEwan Crawford     {
1028*15f2bd95SEwan Crawford         if (log)
1029*15f2bd95SEwan Crawford             log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
1030*15f2bd95SEwan Crawford         return false;
1031*15f2bd95SEwan Crawford     }
1032*15f2bd95SEwan Crawford     else if (chars_written >= max_expr_size)
1033*15f2bd95SEwan Crawford     {
1034*15f2bd95SEwan Crawford         if (log)
1035*15f2bd95SEwan Crawford             log->Printf("RenderScriptRuntime::JITDataPointer - Expression too long");
1036*15f2bd95SEwan Crawford         return false;
1037*15f2bd95SEwan Crawford     }
1038*15f2bd95SEwan Crawford 
1039*15f2bd95SEwan Crawford     uint64_t result = 0;
1040*15f2bd95SEwan Crawford     if (!EvalRSExpression(buffer, frame_ptr, &result))
1041*15f2bd95SEwan Crawford         return false;
1042*15f2bd95SEwan Crawford 
1043*15f2bd95SEwan Crawford     addr_t mem_ptr = static_cast<lldb::addr_t>(result);
1044*15f2bd95SEwan Crawford     allocation->data_ptr = mem_ptr;
1045*15f2bd95SEwan Crawford 
1046*15f2bd95SEwan Crawford     return true;
1047*15f2bd95SEwan Crawford }
1048*15f2bd95SEwan Crawford 
1049*15f2bd95SEwan Crawford // JITs the RS runtime for the internal pointer to the RS Type of an allocation
1050*15f2bd95SEwan Crawford // Then sets the type_ptr member in Allocation with the result.
1051*15f2bd95SEwan Crawford // Returns true on success, false otherwise
1052*15f2bd95SEwan Crawford bool
1053*15f2bd95SEwan Crawford RenderScriptRuntime::JITTypePointer(AllocationDetails* allocation, StackFrame* frame_ptr)
1054*15f2bd95SEwan Crawford {
1055*15f2bd95SEwan Crawford     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1056*15f2bd95SEwan Crawford 
1057*15f2bd95SEwan Crawford     if (!allocation->address.isValid() || !allocation->context.isValid())
1058*15f2bd95SEwan Crawford     {
1059*15f2bd95SEwan Crawford         if (log)
1060*15f2bd95SEwan Crawford             log->Printf("RenderScriptRuntime::JITTypePointer - Failed to find allocation details");
1061*15f2bd95SEwan Crawford         return false;
1062*15f2bd95SEwan Crawford     }
1063*15f2bd95SEwan Crawford 
1064*15f2bd95SEwan Crawford     const char* expr_cstr = runtimeExpressions[eExprAllocGetType];
1065*15f2bd95SEwan Crawford     const int max_expr_size = 512; // Max expression size
1066*15f2bd95SEwan Crawford     char buffer[max_expr_size];
1067*15f2bd95SEwan Crawford 
1068*15f2bd95SEwan Crawford     int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->context.get(), *allocation->address.get());
1069*15f2bd95SEwan Crawford     if (chars_written < 0)
1070*15f2bd95SEwan Crawford     {
1071*15f2bd95SEwan Crawford         if (log)
1072*15f2bd95SEwan Crawford             log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
1073*15f2bd95SEwan Crawford         return false;
1074*15f2bd95SEwan Crawford     }
1075*15f2bd95SEwan Crawford     else if (chars_written >= max_expr_size)
1076*15f2bd95SEwan Crawford     {
1077*15f2bd95SEwan Crawford         if (log)
1078*15f2bd95SEwan Crawford             log->Printf("RenderScriptRuntime::JITTypePointer - Expression too long");
1079*15f2bd95SEwan Crawford         return false;
1080*15f2bd95SEwan Crawford     }
1081*15f2bd95SEwan Crawford 
1082*15f2bd95SEwan Crawford     uint64_t result = 0;
1083*15f2bd95SEwan Crawford     if (!EvalRSExpression(buffer, frame_ptr, &result))
1084*15f2bd95SEwan Crawford         return false;
1085*15f2bd95SEwan Crawford 
1086*15f2bd95SEwan Crawford     addr_t type_ptr = static_cast<lldb::addr_t>(result);
1087*15f2bd95SEwan Crawford     allocation->type_ptr = type_ptr;
1088*15f2bd95SEwan Crawford 
1089*15f2bd95SEwan Crawford     return true;
1090*15f2bd95SEwan Crawford }
1091*15f2bd95SEwan Crawford 
1092*15f2bd95SEwan Crawford // JITs the RS runtime for information about the dimensions and type of an allocation
1093*15f2bd95SEwan Crawford // Then sets dimension and element_ptr members in Allocation with the result.
1094*15f2bd95SEwan Crawford // Returns true on success, false otherwise
1095*15f2bd95SEwan Crawford bool
1096*15f2bd95SEwan Crawford RenderScriptRuntime::JITTypePacked(AllocationDetails* allocation, StackFrame* frame_ptr)
1097*15f2bd95SEwan Crawford {
1098*15f2bd95SEwan Crawford     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1099*15f2bd95SEwan Crawford 
1100*15f2bd95SEwan Crawford     if (!allocation->type_ptr.isValid() || !allocation->context.isValid())
1101*15f2bd95SEwan Crawford     {
1102*15f2bd95SEwan Crawford         if (log)
1103*15f2bd95SEwan Crawford             log->Printf("RenderScriptRuntime::JITTypePacked - Failed to find allocation details");
1104*15f2bd95SEwan Crawford         return false;
1105*15f2bd95SEwan Crawford     }
1106*15f2bd95SEwan Crawford 
1107*15f2bd95SEwan Crawford     // Expression is different depending on if device is 32 or 64 bit
1108*15f2bd95SEwan Crawford     uint32_t archByteSize = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize();
1109*15f2bd95SEwan Crawford     const unsigned int bits = archByteSize == 4 ? 32 : 64;
1110*15f2bd95SEwan Crawford 
1111*15f2bd95SEwan Crawford     // We want 4 elements from packed data
1112*15f2bd95SEwan Crawford     const unsigned int num_exprs = 4;
1113*15f2bd95SEwan Crawford     assert(num_exprs == (eExprTypeElemPtr - eExprTypeDimX + 1) && "Invalid number of expressions");
1114*15f2bd95SEwan Crawford 
1115*15f2bd95SEwan Crawford     const int max_expr_size = 512; // Max expression size
1116*15f2bd95SEwan Crawford     char buffer[num_exprs][max_expr_size];
1117*15f2bd95SEwan Crawford     uint64_t results[num_exprs];
1118*15f2bd95SEwan Crawford 
1119*15f2bd95SEwan Crawford     for (unsigned int i = 0; i < num_exprs; ++i)
1120*15f2bd95SEwan Crawford     {
1121*15f2bd95SEwan Crawford         int chars_written = snprintf(buffer[i], max_expr_size, runtimeExpressions[eExprTypeDimX + i], bits,
1122*15f2bd95SEwan Crawford                                      *allocation->context.get(), *allocation->type_ptr.get());
1123*15f2bd95SEwan Crawford         if (chars_written < 0)
1124*15f2bd95SEwan Crawford         {
1125*15f2bd95SEwan Crawford             if (log)
1126*15f2bd95SEwan Crawford                 log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
1127*15f2bd95SEwan Crawford             return false;
1128*15f2bd95SEwan Crawford         }
1129*15f2bd95SEwan Crawford         else if (chars_written >= max_expr_size)
1130*15f2bd95SEwan Crawford         {
1131*15f2bd95SEwan Crawford             if (log)
1132*15f2bd95SEwan Crawford                 log->Printf("RenderScriptRuntime::JITTypePacked - Expression too long");
1133*15f2bd95SEwan Crawford             return false;
1134*15f2bd95SEwan Crawford         }
1135*15f2bd95SEwan Crawford 
1136*15f2bd95SEwan Crawford         // Perform expression evaluation
1137*15f2bd95SEwan Crawford         if (!EvalRSExpression(buffer[i], frame_ptr, &results[i]))
1138*15f2bd95SEwan Crawford             return false;
1139*15f2bd95SEwan Crawford     }
1140*15f2bd95SEwan Crawford 
1141*15f2bd95SEwan Crawford     // Assign results to allocation members
1142*15f2bd95SEwan Crawford     AllocationDetails::Dimension dims;
1143*15f2bd95SEwan Crawford     dims.dim_1 = static_cast<uint32_t>(results[0]);
1144*15f2bd95SEwan Crawford     dims.dim_2 = static_cast<uint32_t>(results[1]);
1145*15f2bd95SEwan Crawford     dims.dim_3 = static_cast<uint32_t>(results[2]);
1146*15f2bd95SEwan Crawford     allocation->dimension = dims;
1147*15f2bd95SEwan Crawford 
1148*15f2bd95SEwan Crawford     addr_t elem_ptr = static_cast<lldb::addr_t>(results[3]);
1149*15f2bd95SEwan Crawford     allocation->element_ptr = elem_ptr;
1150*15f2bd95SEwan Crawford 
1151*15f2bd95SEwan Crawford     if (log)
1152*15f2bd95SEwan Crawford         log->Printf("RenderScriptRuntime::JITTypePacked - dims (%u, %u, %u) Element*: 0x%" PRIx64,
1153*15f2bd95SEwan Crawford                     dims.dim_1, dims.dim_2, dims.dim_3, elem_ptr);
1154*15f2bd95SEwan Crawford 
1155*15f2bd95SEwan Crawford     return true;
1156*15f2bd95SEwan Crawford }
1157*15f2bd95SEwan Crawford 
1158*15f2bd95SEwan Crawford // JITs the RS runtime for information about the Element of an allocation
1159*15f2bd95SEwan Crawford // Then sets type, type_vec_size, and type_kind members in Allocation with the result.
1160*15f2bd95SEwan Crawford // Returns true on success, false otherwise
1161*15f2bd95SEwan Crawford bool
1162*15f2bd95SEwan Crawford RenderScriptRuntime::JITElementPacked(AllocationDetails* allocation, StackFrame* frame_ptr)
1163*15f2bd95SEwan Crawford {
1164*15f2bd95SEwan Crawford     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
1165*15f2bd95SEwan Crawford 
1166*15f2bd95SEwan Crawford     if (!allocation->element_ptr.isValid() || !allocation->context.isValid())
1167*15f2bd95SEwan Crawford     {
1168*15f2bd95SEwan Crawford         if (log)
1169*15f2bd95SEwan Crawford             log->Printf("RenderScriptRuntime::JITElementPacked - Failed to find allocation details");
1170*15f2bd95SEwan Crawford         return false;
1171*15f2bd95SEwan Crawford     }
1172*15f2bd95SEwan Crawford 
1173*15f2bd95SEwan Crawford     // We want 3 elements from packed data
1174*15f2bd95SEwan Crawford     const unsigned int num_exprs = 3;
1175*15f2bd95SEwan Crawford     assert(num_exprs == (eExprElementVec - eExprElementType + 1) && "Invalid number of expressions");
1176*15f2bd95SEwan Crawford 
1177*15f2bd95SEwan Crawford     const int max_expr_size = 512; // Max expression size
1178*15f2bd95SEwan Crawford     char buffer[num_exprs][max_expr_size];
1179*15f2bd95SEwan Crawford     uint64_t results[num_exprs];
1180*15f2bd95SEwan Crawford 
1181*15f2bd95SEwan Crawford     for (unsigned int i = 0; i < num_exprs; i++)
1182*15f2bd95SEwan Crawford     {
1183*15f2bd95SEwan Crawford         int chars_written = snprintf(buffer[i], max_expr_size, runtimeExpressions[eExprElementType + i], *allocation->context.get(), *allocation->element_ptr.get());
1184*15f2bd95SEwan Crawford         if (chars_written < 0)
1185*15f2bd95SEwan Crawford         {
1186*15f2bd95SEwan Crawford             if (log)
1187*15f2bd95SEwan Crawford                 log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()");
1188*15f2bd95SEwan Crawford             return false;
1189*15f2bd95SEwan Crawford         }
1190*15f2bd95SEwan Crawford         else if (chars_written >= max_expr_size)
1191*15f2bd95SEwan Crawford         {
1192*15f2bd95SEwan Crawford             if (log)
1193*15f2bd95SEwan Crawford                 log->Printf("RenderScriptRuntime::JITElementPacked - Expression too long");
1194*15f2bd95SEwan Crawford             return false;
1195*15f2bd95SEwan Crawford         }
1196*15f2bd95SEwan Crawford 
1197*15f2bd95SEwan Crawford         // Perform expression evaluation
1198*15f2bd95SEwan Crawford         if (!EvalRSExpression(buffer[i], frame_ptr, &results[i]))
1199*15f2bd95SEwan Crawford             return false;
1200*15f2bd95SEwan Crawford     }
1201*15f2bd95SEwan Crawford 
1202*15f2bd95SEwan Crawford     // Assign results to allocation members
1203*15f2bd95SEwan Crawford     allocation->type = static_cast<RenderScriptRuntime::AllocationDetails::DataType>(results[0]);
1204*15f2bd95SEwan Crawford     allocation->type_kind = static_cast<RenderScriptRuntime::AllocationDetails::DataKind>(results[1]);
1205*15f2bd95SEwan Crawford     allocation->type_vec_size = static_cast<uint32_t>(results[2]);
1206*15f2bd95SEwan Crawford 
1207*15f2bd95SEwan Crawford     if (log)
1208*15f2bd95SEwan Crawford         log->Printf("RenderScriptRuntime::JITElementPacked - data type %u, pixel type %u, vector size %u",
1209*15f2bd95SEwan Crawford                     *allocation->type.get(), *allocation->type_kind.get(), *allocation->type_vec_size.get());
1210*15f2bd95SEwan Crawford 
1211*15f2bd95SEwan Crawford     return true;
1212*15f2bd95SEwan Crawford }
1213*15f2bd95SEwan Crawford 
1214*15f2bd95SEwan Crawford // JIT all the current runtime info regarding an allocation
1215*15f2bd95SEwan Crawford bool
1216*15f2bd95SEwan Crawford RenderScriptRuntime::RefreshAllocation(AllocationDetails* allocation, StackFrame* frame_ptr)
1217*15f2bd95SEwan Crawford {
1218*15f2bd95SEwan Crawford     // GetOffsetPointer()
1219*15f2bd95SEwan Crawford     if (!JITDataPointer(allocation, frame_ptr))
1220*15f2bd95SEwan Crawford         return false;
1221*15f2bd95SEwan Crawford 
1222*15f2bd95SEwan Crawford     // rsaAllocationGetType()
1223*15f2bd95SEwan Crawford     if (!JITTypePointer(allocation, frame_ptr))
1224*15f2bd95SEwan Crawford         return false;
1225*15f2bd95SEwan Crawford 
1226*15f2bd95SEwan Crawford     // rsaTypeGetNativeData()
1227*15f2bd95SEwan Crawford     if (!JITTypePacked(allocation, frame_ptr))
1228*15f2bd95SEwan Crawford         return false;
1229*15f2bd95SEwan Crawford 
1230*15f2bd95SEwan Crawford     // rsaElementGetNativeData()
1231*15f2bd95SEwan Crawford     if (!JITElementPacked(allocation, frame_ptr))
1232*15f2bd95SEwan Crawford         return false;
1233*15f2bd95SEwan Crawford 
1234*15f2bd95SEwan Crawford     return true;
1235*15f2bd95SEwan Crawford }
1236*15f2bd95SEwan Crawford 
12375ec532a9SColin Riley bool
12385ec532a9SColin Riley RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
12395ec532a9SColin Riley {
12404640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
12414640cde1SColin Riley 
12425ec532a9SColin Riley     if (module_sp)
12435ec532a9SColin Riley     {
12445ec532a9SColin Riley         for (const auto &rs_module : m_rsmodules)
12455ec532a9SColin Riley         {
12464640cde1SColin Riley             if (rs_module->m_module == module_sp)
12477dc7771cSEwan Crawford             {
12487dc7771cSEwan Crawford                 // Check if the user has enabled automatically breaking on
12497dc7771cSEwan Crawford                 // all RS kernels.
12507dc7771cSEwan Crawford                 if (m_breakAllKernels)
12517dc7771cSEwan Crawford                     BreakOnModuleKernels(rs_module);
12527dc7771cSEwan Crawford 
12535ec532a9SColin Riley                 return false;
12545ec532a9SColin Riley             }
12557dc7771cSEwan Crawford         }
1256ef20b08fSColin Riley         bool module_loaded = false;
1257ef20b08fSColin Riley         switch (GetModuleKind(module_sp))
1258ef20b08fSColin Riley         {
1259ef20b08fSColin Riley             case eModuleKindKernelObj:
1260ef20b08fSColin Riley             {
12614640cde1SColin Riley                 RSModuleDescriptorSP module_desc;
12624640cde1SColin Riley                 module_desc.reset(new RSModuleDescriptor(module_sp));
12634640cde1SColin Riley                 if (module_desc->ParseRSInfo())
12645ec532a9SColin Riley                 {
12655ec532a9SColin Riley                     m_rsmodules.push_back(module_desc);
1266ef20b08fSColin Riley                     module_loaded = true;
12675ec532a9SColin Riley                 }
12684640cde1SColin Riley                 if (module_loaded)
12694640cde1SColin Riley                 {
12704640cde1SColin Riley                     FixupScriptDetails(module_desc);
12714640cde1SColin Riley                 }
1272ef20b08fSColin Riley                 break;
1273ef20b08fSColin Riley             }
1274ef20b08fSColin Riley             case eModuleKindDriver:
12754640cde1SColin Riley             {
12764640cde1SColin Riley                 if (!m_libRSDriver)
12774640cde1SColin Riley                 {
12784640cde1SColin Riley                     m_libRSDriver = module_sp;
12794640cde1SColin Riley                     LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver);
12804640cde1SColin Riley                 }
12814640cde1SColin Riley                 break;
12824640cde1SColin Riley             }
1283ef20b08fSColin Riley             case eModuleKindImpl:
12844640cde1SColin Riley             {
12854640cde1SColin Riley                 m_libRSCpuRef = module_sp;
12864640cde1SColin Riley                 break;
12874640cde1SColin Riley             }
1288ef20b08fSColin Riley             case eModuleKindLibRS:
12894640cde1SColin Riley             {
12904640cde1SColin Riley                 if (!m_libRS)
12914640cde1SColin Riley                 {
12924640cde1SColin Riley                     m_libRS = module_sp;
12934640cde1SColin Riley                     static ConstString gDbgPresentStr("gDebuggerPresent");
12944640cde1SColin Riley                     const Symbol* debug_present = m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData);
12954640cde1SColin Riley                     if (debug_present)
12964640cde1SColin Riley                     {
12974640cde1SColin Riley                         Error error;
12984640cde1SColin Riley                         uint32_t flag = 0x00000001U;
12994640cde1SColin Riley                         Target &target = GetProcess()->GetTarget();
1300358cf1eaSGreg Clayton                         addr_t addr = debug_present->GetLoadAddress(&target);
13014640cde1SColin Riley                         GetProcess()->WriteMemory(addr, &flag, sizeof(flag), error);
13024640cde1SColin Riley                         if(error.Success())
13034640cde1SColin Riley                         {
13044640cde1SColin Riley                             if (log)
13054640cde1SColin Riley                                 log->Printf ("RenderScriptRuntime::LoadModule - Debugger present flag set on debugee");
13064640cde1SColin Riley 
13074640cde1SColin Riley                             m_debuggerPresentFlagged = true;
13084640cde1SColin Riley                         }
13094640cde1SColin Riley                         else if (log)
13104640cde1SColin Riley                         {
13114640cde1SColin Riley                             log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags '%s' ", error.AsCString());
13124640cde1SColin Riley                         }
13134640cde1SColin Riley                     }
13144640cde1SColin Riley                     else if (log)
13154640cde1SColin Riley                     {
13164640cde1SColin Riley                         log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags - symbol not found");
13174640cde1SColin Riley                     }
13184640cde1SColin Riley                 }
13194640cde1SColin Riley                 break;
13204640cde1SColin Riley             }
1321ef20b08fSColin Riley             default:
1322ef20b08fSColin Riley                 break;
1323ef20b08fSColin Riley         }
1324ef20b08fSColin Riley         if (module_loaded)
1325ef20b08fSColin Riley             Update();
1326ef20b08fSColin Riley         return module_loaded;
13275ec532a9SColin Riley     }
13285ec532a9SColin Riley     return false;
13295ec532a9SColin Riley }
13305ec532a9SColin Riley 
1331ef20b08fSColin Riley void
1332ef20b08fSColin Riley RenderScriptRuntime::Update()
1333ef20b08fSColin Riley {
1334ef20b08fSColin Riley     if (m_rsmodules.size() > 0)
1335ef20b08fSColin Riley     {
1336ef20b08fSColin Riley         if (!m_initiated)
1337ef20b08fSColin Riley         {
1338ef20b08fSColin Riley             Initiate();
1339ef20b08fSColin Riley         }
1340ef20b08fSColin Riley     }
1341ef20b08fSColin Riley }
1342ef20b08fSColin Riley 
1343ef20b08fSColin Riley 
13445ec532a9SColin Riley // The maximum line length of an .rs.info packet
13455ec532a9SColin Riley #define MAXLINE 500
13465ec532a9SColin Riley 
13475ec532a9SColin Riley // The .rs.info symbol in renderscript modules contains a string which needs to be parsed.
13485ec532a9SColin Riley // The string is basic and is parsed on a line by line basis.
13495ec532a9SColin Riley bool
13505ec532a9SColin Riley RSModuleDescriptor::ParseRSInfo()
13515ec532a9SColin Riley {
13525ec532a9SColin Riley     const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
13535ec532a9SColin Riley     if (info_sym)
13545ec532a9SColin Riley     {
1355358cf1eaSGreg Clayton         const addr_t addr = info_sym->GetAddressRef().GetFileAddress();
13565ec532a9SColin Riley         const addr_t size = info_sym->GetByteSize();
13575ec532a9SColin Riley         const FileSpec fs = m_module->GetFileSpec();
13585ec532a9SColin Riley 
13595ec532a9SColin Riley         DataBufferSP buffer = fs.ReadFileContents(addr, size);
13605ec532a9SColin Riley 
13615ec532a9SColin Riley         if (!buffer)
13625ec532a9SColin Riley             return false;
13635ec532a9SColin Riley 
13645ec532a9SColin Riley         std::string info((const char *)buffer->GetBytes());
13655ec532a9SColin Riley 
13665ec532a9SColin Riley         std::vector<std::string> info_lines;
1367e8433cc1SBruce Mitchener         size_t lpos = info.find('\n');
13685ec532a9SColin Riley         while (lpos != std::string::npos)
13695ec532a9SColin Riley         {
13705ec532a9SColin Riley             info_lines.push_back(info.substr(0, lpos));
13715ec532a9SColin Riley             info = info.substr(lpos + 1);
1372e8433cc1SBruce Mitchener             lpos = info.find('\n');
13735ec532a9SColin Riley         }
13745ec532a9SColin Riley         size_t offset = 0;
13755ec532a9SColin Riley         while (offset < info_lines.size())
13765ec532a9SColin Riley         {
13775ec532a9SColin Riley             std::string line = info_lines[offset];
13785ec532a9SColin Riley             // Parse directives
13795ec532a9SColin Riley             uint32_t numDefns = 0;
13805ec532a9SColin Riley             if (sscanf(line.c_str(), "exportVarCount: %u", &numDefns) == 1)
13815ec532a9SColin Riley             {
13825ec532a9SColin Riley                 while (numDefns--)
13834640cde1SColin Riley                     m_globals.push_back(RSGlobalDescriptor(this, info_lines[++offset].c_str()));
13845ec532a9SColin Riley             }
13855ec532a9SColin Riley             else if (sscanf(line.c_str(), "exportFuncCount: %u", &numDefns) == 1)
13865ec532a9SColin Riley             {
13875ec532a9SColin Riley             }
13885ec532a9SColin Riley             else if (sscanf(line.c_str(), "exportForEachCount: %u", &numDefns) == 1)
13895ec532a9SColin Riley             {
13905ec532a9SColin Riley                 char name[MAXLINE];
13915ec532a9SColin Riley                 while (numDefns--)
13925ec532a9SColin Riley                 {
13935ec532a9SColin Riley                     uint32_t slot = 0;
13945ec532a9SColin Riley                     name[0] = '\0';
13955ec532a9SColin Riley                     if (sscanf(info_lines[++offset].c_str(), "%u - %s", &slot, &name[0]) == 2)
13965ec532a9SColin Riley                     {
13974640cde1SColin Riley                         m_kernels.push_back(RSKernelDescriptor(this, name, slot));
13984640cde1SColin Riley                     }
13994640cde1SColin Riley                 }
14004640cde1SColin Riley             }
14014640cde1SColin Riley             else if (sscanf(line.c_str(), "pragmaCount: %u", &numDefns) == 1)
14024640cde1SColin Riley             {
14034640cde1SColin Riley                 char name[MAXLINE];
14044640cde1SColin Riley                 char value[MAXLINE];
14054640cde1SColin Riley                 while (numDefns--)
14064640cde1SColin Riley                 {
14074640cde1SColin Riley                     name[0] = '\0';
14084640cde1SColin Riley                     value[0] = '\0';
14094640cde1SColin Riley                     if (sscanf(info_lines[++offset].c_str(), "%s - %s", &name[0], &value[0]) != 0
14104640cde1SColin Riley                         && (name[0] != '\0'))
14114640cde1SColin Riley                     {
14124640cde1SColin Riley                         m_pragmas[std::string(name)] = value;
14135ec532a9SColin Riley                     }
14145ec532a9SColin Riley                 }
14155ec532a9SColin Riley             }
14165ec532a9SColin Riley             else if (sscanf(line.c_str(), "objectSlotCount: %u", &numDefns) == 1)
14175ec532a9SColin Riley             {
14185ec532a9SColin Riley             }
14195ec532a9SColin Riley 
14205ec532a9SColin Riley             offset++;
14215ec532a9SColin Riley         }
14225ec532a9SColin Riley         return m_kernels.size() > 0;
14235ec532a9SColin Riley     }
14245ec532a9SColin Riley     return false;
14255ec532a9SColin Riley }
14265ec532a9SColin Riley 
14275ec532a9SColin Riley bool
14285ec532a9SColin Riley RenderScriptRuntime::ProbeModules(const ModuleList module_list)
14295ec532a9SColin Riley {
14305ec532a9SColin Riley     bool rs_found = false;
14315ec532a9SColin Riley     size_t num_modules = module_list.GetSize();
14325ec532a9SColin Riley     for (size_t i = 0; i < num_modules; i++)
14335ec532a9SColin Riley     {
14345ec532a9SColin Riley         auto module = module_list.GetModuleAtIndex(i);
14355ec532a9SColin Riley         rs_found |= LoadModule(module);
14365ec532a9SColin Riley     }
14375ec532a9SColin Riley     return rs_found;
14385ec532a9SColin Riley }
14395ec532a9SColin Riley 
14405ec532a9SColin Riley void
14414640cde1SColin Riley RenderScriptRuntime::Status(Stream &strm) const
14424640cde1SColin Riley {
14434640cde1SColin Riley     if (m_libRS)
14444640cde1SColin Riley     {
14454640cde1SColin Riley         strm.Printf("Runtime Library discovered.");
14464640cde1SColin Riley         strm.EOL();
14474640cde1SColin Riley     }
14484640cde1SColin Riley     if (m_libRSDriver)
14494640cde1SColin Riley     {
14504640cde1SColin Riley         strm.Printf("Runtime Driver discovered.");
14514640cde1SColin Riley         strm.EOL();
14524640cde1SColin Riley     }
14534640cde1SColin Riley     if (m_libRSCpuRef)
14544640cde1SColin Riley     {
14554640cde1SColin Riley         strm.Printf("CPU Reference Implementation discovered.");
14564640cde1SColin Riley         strm.EOL();
14574640cde1SColin Riley     }
14584640cde1SColin Riley 
14594640cde1SColin Riley     if (m_runtimeHooks.size())
14604640cde1SColin Riley     {
14614640cde1SColin Riley         strm.Printf("Runtime functions hooked:");
14624640cde1SColin Riley         strm.EOL();
14634640cde1SColin Riley         for (auto b : m_runtimeHooks)
14644640cde1SColin Riley         {
14654640cde1SColin Riley             strm.Indent(b.second->defn->name);
14664640cde1SColin Riley             strm.EOL();
14674640cde1SColin Riley         }
14684640cde1SColin Riley         strm.EOL();
14694640cde1SColin Riley     }
14704640cde1SColin Riley     else
14714640cde1SColin Riley     {
14724640cde1SColin Riley         strm.Printf("Runtime is not hooked.");
14734640cde1SColin Riley         strm.EOL();
14744640cde1SColin Riley     }
14754640cde1SColin Riley }
14764640cde1SColin Riley 
14774640cde1SColin Riley void
14784640cde1SColin Riley RenderScriptRuntime::DumpContexts(Stream &strm) const
14794640cde1SColin Riley {
14804640cde1SColin Riley     strm.Printf("Inferred RenderScript Contexts:");
14814640cde1SColin Riley     strm.EOL();
14824640cde1SColin Riley     strm.IndentMore();
14834640cde1SColin Riley 
14844640cde1SColin Riley     std::map<addr_t, uint64_t> contextReferences;
14854640cde1SColin Riley 
148678f339d1SEwan Crawford     // Iterate over all of the currently discovered scripts.
148778f339d1SEwan Crawford     // Note: We cant push or pop from m_scripts inside this loop or it may invalidate script.
14884640cde1SColin Riley     for (const auto & script : m_scripts)
14894640cde1SColin Riley     {
149078f339d1SEwan Crawford         if (!script->context.isValid())
149178f339d1SEwan Crawford             continue;
149278f339d1SEwan Crawford         lldb::addr_t context = *script->context;
149378f339d1SEwan Crawford 
149478f339d1SEwan Crawford         if (contextReferences.find(context) != contextReferences.end())
14954640cde1SColin Riley         {
149678f339d1SEwan Crawford             contextReferences[context]++;
14974640cde1SColin Riley         }
14984640cde1SColin Riley         else
14994640cde1SColin Riley         {
150078f339d1SEwan Crawford             contextReferences[context] = 1;
15014640cde1SColin Riley         }
15024640cde1SColin Riley     }
15034640cde1SColin Riley 
15044640cde1SColin Riley     for (const auto& cRef : contextReferences)
15054640cde1SColin Riley     {
15064640cde1SColin Riley         strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances", cRef.first, cRef.second);
15074640cde1SColin Riley         strm.EOL();
15084640cde1SColin Riley     }
15094640cde1SColin Riley     strm.IndentLess();
15104640cde1SColin Riley }
15114640cde1SColin Riley 
15124640cde1SColin Riley void
15134640cde1SColin Riley RenderScriptRuntime::DumpKernels(Stream &strm) const
15144640cde1SColin Riley {
15154640cde1SColin Riley     strm.Printf("RenderScript Kernels:");
15164640cde1SColin Riley     strm.EOL();
15174640cde1SColin Riley     strm.IndentMore();
15184640cde1SColin Riley     for (const auto &module : m_rsmodules)
15194640cde1SColin Riley     {
15204640cde1SColin Riley         strm.Printf("Resource '%s':",module->m_resname.c_str());
15214640cde1SColin Riley         strm.EOL();
15224640cde1SColin Riley         for (const auto &kernel : module->m_kernels)
15234640cde1SColin Riley         {
15244640cde1SColin Riley             strm.Indent(kernel.m_name.AsCString());
15254640cde1SColin Riley             strm.EOL();
15264640cde1SColin Riley         }
15274640cde1SColin Riley     }
15284640cde1SColin Riley     strm.IndentLess();
15294640cde1SColin Riley }
15304640cde1SColin Riley 
1531*15f2bd95SEwan Crawford // Prints infomation regarding all the currently loaded allocations.
1532*15f2bd95SEwan Crawford // These details are gathered by jitting the runtime, which has as latency.
1533*15f2bd95SEwan Crawford void
1534*15f2bd95SEwan Crawford RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame* frame_ptr, bool recompute)
1535*15f2bd95SEwan Crawford {
1536*15f2bd95SEwan Crawford     strm.Printf("RenderScript Allocations:");
1537*15f2bd95SEwan Crawford     strm.EOL();
1538*15f2bd95SEwan Crawford     strm.IndentMore();
1539*15f2bd95SEwan Crawford 
1540*15f2bd95SEwan Crawford     for (auto &alloc : m_allocations)
1541*15f2bd95SEwan Crawford     {
1542*15f2bd95SEwan Crawford         // JIT the allocation info if we haven't done it, or the user forces us to.
1543*15f2bd95SEwan Crawford         bool do_refresh = !alloc->data_ptr.isValid() || recompute;
1544*15f2bd95SEwan Crawford 
1545*15f2bd95SEwan Crawford         // JIT current allocation information
1546*15f2bd95SEwan Crawford         if (do_refresh && !RefreshAllocation(alloc.get(), frame_ptr))
1547*15f2bd95SEwan Crawford         {
1548*15f2bd95SEwan Crawford             strm.Printf("Error: Couldn't evaluate details for allocation %u\n", alloc->id);
1549*15f2bd95SEwan Crawford             continue;
1550*15f2bd95SEwan Crawford         }
1551*15f2bd95SEwan Crawford 
1552*15f2bd95SEwan Crawford         strm.Printf("%u:\n",alloc->id);
1553*15f2bd95SEwan Crawford         strm.IndentMore();
1554*15f2bd95SEwan Crawford 
1555*15f2bd95SEwan Crawford         strm.Indent("Context: ");
1556*15f2bd95SEwan Crawford         if (!alloc->context.isValid())
1557*15f2bd95SEwan Crawford             strm.Printf("unknown\n");
1558*15f2bd95SEwan Crawford         else
1559*15f2bd95SEwan Crawford             strm.Printf("0x%" PRIx64 "\n", *alloc->context.get());
1560*15f2bd95SEwan Crawford 
1561*15f2bd95SEwan Crawford         strm.Indent("Address: ");
1562*15f2bd95SEwan Crawford         if (!alloc->address.isValid())
1563*15f2bd95SEwan Crawford             strm.Printf("unknown\n");
1564*15f2bd95SEwan Crawford         else
1565*15f2bd95SEwan Crawford             strm.Printf("0x%" PRIx64 "\n", *alloc->address.get());
1566*15f2bd95SEwan Crawford 
1567*15f2bd95SEwan Crawford         strm.Indent("Data pointer: ");
1568*15f2bd95SEwan Crawford         if (!alloc->data_ptr.isValid())
1569*15f2bd95SEwan Crawford             strm.Printf("unknown\n");
1570*15f2bd95SEwan Crawford         else
1571*15f2bd95SEwan Crawford             strm.Printf("0x%" PRIx64 "\n", *alloc->data_ptr.get());
1572*15f2bd95SEwan Crawford 
1573*15f2bd95SEwan Crawford         strm.Indent("Dimensions: ");
1574*15f2bd95SEwan Crawford         if (!alloc->dimension.isValid())
1575*15f2bd95SEwan Crawford             strm.Printf("unknown\n");
1576*15f2bd95SEwan Crawford         else
1577*15f2bd95SEwan Crawford             strm.Printf("(%d, %d, %d)\n", alloc->dimension.get()->dim_1,
1578*15f2bd95SEwan Crawford                                           alloc->dimension.get()->dim_2,
1579*15f2bd95SEwan Crawford                                           alloc->dimension.get()->dim_3);
1580*15f2bd95SEwan Crawford 
1581*15f2bd95SEwan Crawford         strm.Indent("Data Type: ");
1582*15f2bd95SEwan Crawford         if (!alloc->type.isValid() || !alloc->type_vec_size.isValid())
1583*15f2bd95SEwan Crawford             strm.Printf("unknown\n");
1584*15f2bd95SEwan Crawford         else
1585*15f2bd95SEwan Crawford         {
1586*15f2bd95SEwan Crawford             const int vector_size = *alloc->type_vec_size.get();
1587*15f2bd95SEwan Crawford             const AllocationDetails::DataType type = *alloc->type.get();
1588*15f2bd95SEwan Crawford 
1589*15f2bd95SEwan Crawford             if (vector_size > 4 || vector_size < 1 ||
1590*15f2bd95SEwan Crawford                 type < AllocationDetails::RS_TYPE_NONE || type > AllocationDetails::RS_TYPE_BOOLEAN)
1591*15f2bd95SEwan Crawford                 strm.Printf("invalid type\n");
1592*15f2bd95SEwan Crawford             else
1593*15f2bd95SEwan Crawford                 strm.Printf("%s\n", AllocationDetails::RsDataTypeToString[static_cast<unsigned int>(type)][vector_size-1]);
1594*15f2bd95SEwan Crawford         }
1595*15f2bd95SEwan Crawford 
1596*15f2bd95SEwan Crawford         strm.Indent("Data Kind: ");
1597*15f2bd95SEwan Crawford         if (!alloc->type_kind.isValid())
1598*15f2bd95SEwan Crawford             strm.Printf("unknown\n");
1599*15f2bd95SEwan Crawford         else
1600*15f2bd95SEwan Crawford         {
1601*15f2bd95SEwan Crawford             const AllocationDetails::DataKind kind = *alloc->type_kind.get();
1602*15f2bd95SEwan Crawford             if (kind < AllocationDetails::RS_KIND_USER || kind > AllocationDetails::RS_KIND_PIXEL_YUV)
1603*15f2bd95SEwan Crawford                 strm.Printf("invalid kind\n");
1604*15f2bd95SEwan Crawford             else
1605*15f2bd95SEwan Crawford                 strm.Printf("%s\n", AllocationDetails::RsDataKindToString[static_cast<unsigned int>(kind)]);
1606*15f2bd95SEwan Crawford         }
1607*15f2bd95SEwan Crawford 
1608*15f2bd95SEwan Crawford         strm.EOL();
1609*15f2bd95SEwan Crawford         strm.IndentLess();
1610*15f2bd95SEwan Crawford     }
1611*15f2bd95SEwan Crawford     strm.IndentLess();
1612*15f2bd95SEwan Crawford }
1613*15f2bd95SEwan Crawford 
16147dc7771cSEwan Crawford // Set breakpoints on every kernel found in RS module
16157dc7771cSEwan Crawford void
16167dc7771cSEwan Crawford RenderScriptRuntime::BreakOnModuleKernels(const RSModuleDescriptorSP rsmodule_sp)
16177dc7771cSEwan Crawford {
16187dc7771cSEwan Crawford     for (const auto &kernel : rsmodule_sp->m_kernels)
16197dc7771cSEwan Crawford     {
16207dc7771cSEwan Crawford         // Don't set breakpoint on 'root' kernel
16217dc7771cSEwan Crawford         if (strcmp(kernel.m_name.AsCString(), "root") == 0)
16227dc7771cSEwan Crawford             continue;
16237dc7771cSEwan Crawford 
16247dc7771cSEwan Crawford         CreateKernelBreakpoint(kernel.m_name);
16257dc7771cSEwan Crawford     }
16267dc7771cSEwan Crawford }
16277dc7771cSEwan Crawford 
16287dc7771cSEwan Crawford // Method is internally called by the 'kernel breakpoint all' command to
16297dc7771cSEwan Crawford // enable or disable breaking on all kernels.
16307dc7771cSEwan Crawford //
16317dc7771cSEwan Crawford // When do_break is true we want to enable this functionality.
16327dc7771cSEwan Crawford // When do_break is false we want to disable it.
16337dc7771cSEwan Crawford void
16347dc7771cSEwan Crawford RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target)
16357dc7771cSEwan Crawford {
163654782db7SEwan Crawford     Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
16377dc7771cSEwan Crawford 
16387dc7771cSEwan Crawford     InitSearchFilter(target);
16397dc7771cSEwan Crawford 
16407dc7771cSEwan Crawford     // Set breakpoints on all the kernels
16417dc7771cSEwan Crawford     if (do_break && !m_breakAllKernels)
16427dc7771cSEwan Crawford     {
16437dc7771cSEwan Crawford         m_breakAllKernels = true;
16447dc7771cSEwan Crawford 
16457dc7771cSEwan Crawford         for (const auto &module : m_rsmodules)
16467dc7771cSEwan Crawford             BreakOnModuleKernels(module);
16477dc7771cSEwan Crawford 
16487dc7771cSEwan Crawford         if (log)
16497dc7771cSEwan Crawford             log->Printf("RenderScriptRuntime::SetBreakAllKernels(True)"
16507dc7771cSEwan Crawford                         "- breakpoints set on all currently loaded kernels");
16517dc7771cSEwan Crawford     }
16527dc7771cSEwan Crawford     else if (!do_break && m_breakAllKernels) // Breakpoints won't be set on any new kernels.
16537dc7771cSEwan Crawford     {
16547dc7771cSEwan Crawford         m_breakAllKernels = false;
16557dc7771cSEwan Crawford 
16567dc7771cSEwan Crawford         if (log)
16577dc7771cSEwan Crawford             log->Printf("RenderScriptRuntime::SetBreakAllKernels(False) - breakpoints no longer automatically set");
16587dc7771cSEwan Crawford     }
16597dc7771cSEwan Crawford }
16607dc7771cSEwan Crawford 
16617dc7771cSEwan Crawford // Given the name of a kernel this function creates a breakpoint using our
16627dc7771cSEwan Crawford // own breakpoint resolver, and returns the Breakpoint shared pointer.
16637dc7771cSEwan Crawford BreakpointSP
16647dc7771cSEwan Crawford RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name)
16657dc7771cSEwan Crawford {
166654782db7SEwan Crawford     Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
16677dc7771cSEwan Crawford 
16687dc7771cSEwan Crawford     if (!m_filtersp)
16697dc7771cSEwan Crawford     {
16707dc7771cSEwan Crawford         if (log)
16717dc7771cSEwan Crawford             log->Printf("RenderScriptRuntime::CreateKernelBreakpoint - Error: No breakpoint search filter set");
16727dc7771cSEwan Crawford         return nullptr;
16737dc7771cSEwan Crawford     }
16747dc7771cSEwan Crawford 
16757dc7771cSEwan Crawford     BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name));
16767dc7771cSEwan Crawford     BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(m_filtersp, resolver_sp, false, false, false);
16777dc7771cSEwan Crawford 
167854782db7SEwan Crawford     // Give RS breakpoints a specific name, so the user can manipulate them as a group.
167954782db7SEwan Crawford     Error err;
168054782db7SEwan Crawford     if (!bp->AddName("RenderScriptKernel", err) && log)
168154782db7SEwan Crawford         log->Printf("RenderScriptRuntime::CreateKernelBreakpoint: Error setting break name, %s", err.AsCString());
168254782db7SEwan Crawford 
16837dc7771cSEwan Crawford     return bp;
16847dc7771cSEwan Crawford }
16857dc7771cSEwan Crawford 
16864640cde1SColin Riley void
168798156583SEwan Crawford RenderScriptRuntime::AttemptBreakpointAtKernelName(Stream &strm, const char* name, Error& error, TargetSP target)
16884640cde1SColin Riley {
16894640cde1SColin Riley     if (!name)
16904640cde1SColin Riley     {
16914640cde1SColin Riley         error.SetErrorString("invalid kernel name");
16924640cde1SColin Riley         return;
16934640cde1SColin Riley     }
16944640cde1SColin Riley 
16957dc7771cSEwan Crawford     InitSearchFilter(target);
169698156583SEwan Crawford 
16974640cde1SColin Riley     ConstString kernel_name(name);
16987dc7771cSEwan Crawford     BreakpointSP bp = CreateKernelBreakpoint(kernel_name);
169998156583SEwan Crawford     if (bp)
170098156583SEwan Crawford         bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false);
17014640cde1SColin Riley 
17024640cde1SColin Riley     return;
17034640cde1SColin Riley }
17044640cde1SColin Riley 
17054640cde1SColin Riley void
17065ec532a9SColin Riley RenderScriptRuntime::DumpModules(Stream &strm) const
17075ec532a9SColin Riley {
17085ec532a9SColin Riley     strm.Printf("RenderScript Modules:");
17095ec532a9SColin Riley     strm.EOL();
17105ec532a9SColin Riley     strm.IndentMore();
17115ec532a9SColin Riley     for (const auto &module : m_rsmodules)
17125ec532a9SColin Riley     {
17134640cde1SColin Riley         module->Dump(strm);
17145ec532a9SColin Riley     }
17155ec532a9SColin Riley     strm.IndentLess();
17165ec532a9SColin Riley }
17175ec532a9SColin Riley 
171878f339d1SEwan Crawford RenderScriptRuntime::ScriptDetails*
171978f339d1SEwan Crawford RenderScriptRuntime::LookUpScript(addr_t address, bool create)
172078f339d1SEwan Crawford {
172178f339d1SEwan Crawford     for (const auto & s : m_scripts)
172278f339d1SEwan Crawford     {
172378f339d1SEwan Crawford         if (s->script.isValid())
172478f339d1SEwan Crawford             if (*s->script == address)
172578f339d1SEwan Crawford                 return s.get();
172678f339d1SEwan Crawford     }
172778f339d1SEwan Crawford     if (create)
172878f339d1SEwan Crawford     {
172978f339d1SEwan Crawford         std::unique_ptr<ScriptDetails> s(new ScriptDetails);
173078f339d1SEwan Crawford         s->script = address;
173178f339d1SEwan Crawford         m_scripts.push_back(std::move(s));
1732d10ca9deSEwan Crawford         return m_scripts.back().get();
173378f339d1SEwan Crawford     }
173478f339d1SEwan Crawford     return nullptr;
173578f339d1SEwan Crawford }
173678f339d1SEwan Crawford 
173778f339d1SEwan Crawford RenderScriptRuntime::AllocationDetails*
173878f339d1SEwan Crawford RenderScriptRuntime::LookUpAllocation(addr_t address, bool create)
173978f339d1SEwan Crawford {
174078f339d1SEwan Crawford     for (const auto & a : m_allocations)
174178f339d1SEwan Crawford     {
174278f339d1SEwan Crawford         if (a->address.isValid())
174378f339d1SEwan Crawford             if (*a->address == address)
174478f339d1SEwan Crawford                 return a.get();
174578f339d1SEwan Crawford     }
174678f339d1SEwan Crawford     if (create)
174778f339d1SEwan Crawford     {
174878f339d1SEwan Crawford         std::unique_ptr<AllocationDetails> a(new AllocationDetails);
174978f339d1SEwan Crawford         a->address = address;
175078f339d1SEwan Crawford         m_allocations.push_back(std::move(a));
1751d10ca9deSEwan Crawford         return m_allocations.back().get();
175278f339d1SEwan Crawford     }
175378f339d1SEwan Crawford     return nullptr;
175478f339d1SEwan Crawford }
175578f339d1SEwan Crawford 
17565ec532a9SColin Riley void
17575ec532a9SColin Riley RSModuleDescriptor::Dump(Stream &strm) const
17585ec532a9SColin Riley {
17595ec532a9SColin Riley     strm.Indent();
17605ec532a9SColin Riley     m_module->GetFileSpec().Dump(&strm);
17614640cde1SColin Riley     if(m_module->GetNumCompileUnits())
17624640cde1SColin Riley     {
17634640cde1SColin Riley         strm.Indent("Debug info loaded.");
17644640cde1SColin Riley     }
17654640cde1SColin Riley     else
17664640cde1SColin Riley     {
17674640cde1SColin Riley         strm.Indent("Debug info does not exist.");
17684640cde1SColin Riley     }
17695ec532a9SColin Riley     strm.EOL();
17705ec532a9SColin Riley     strm.IndentMore();
17715ec532a9SColin Riley     strm.Indent();
1772189598edSColin Riley     strm.Printf("Globals: %" PRIu64, static_cast<uint64_t>(m_globals.size()));
17735ec532a9SColin Riley     strm.EOL();
17745ec532a9SColin Riley     strm.IndentMore();
17755ec532a9SColin Riley     for (const auto &global : m_globals)
17765ec532a9SColin Riley     {
17775ec532a9SColin Riley         global.Dump(strm);
17785ec532a9SColin Riley     }
17795ec532a9SColin Riley     strm.IndentLess();
17805ec532a9SColin Riley     strm.Indent();
1781189598edSColin Riley     strm.Printf("Kernels: %" PRIu64, static_cast<uint64_t>(m_kernels.size()));
17825ec532a9SColin Riley     strm.EOL();
17835ec532a9SColin Riley     strm.IndentMore();
17845ec532a9SColin Riley     for (const auto &kernel : m_kernels)
17855ec532a9SColin Riley     {
17865ec532a9SColin Riley         kernel.Dump(strm);
17875ec532a9SColin Riley     }
17884640cde1SColin Riley     strm.Printf("Pragmas: %"  PRIu64 , static_cast<uint64_t>(m_pragmas.size()));
17894640cde1SColin Riley     strm.EOL();
17904640cde1SColin Riley     strm.IndentMore();
17914640cde1SColin Riley     for (const auto &key_val : m_pragmas)
17924640cde1SColin Riley     {
17934640cde1SColin Riley         strm.Printf("%s: %s", key_val.first.c_str(), key_val.second.c_str());
17944640cde1SColin Riley         strm.EOL();
17954640cde1SColin Riley     }
17965ec532a9SColin Riley     strm.IndentLess(4);
17975ec532a9SColin Riley }
17985ec532a9SColin Riley 
17995ec532a9SColin Riley void
18005ec532a9SColin Riley RSGlobalDescriptor::Dump(Stream &strm) const
18015ec532a9SColin Riley {
18025ec532a9SColin Riley     strm.Indent(m_name.AsCString());
18034640cde1SColin Riley     VariableList var_list;
18044640cde1SColin Riley     m_module->m_module->FindGlobalVariables(m_name, nullptr, true, 1U, var_list);
18054640cde1SColin Riley     if (var_list.GetSize() == 1)
18064640cde1SColin Riley     {
18074640cde1SColin Riley         auto var = var_list.GetVariableAtIndex(0);
18084640cde1SColin Riley         auto type = var->GetType();
18094640cde1SColin Riley         if(type)
18104640cde1SColin Riley         {
18114640cde1SColin Riley             strm.Printf(" - ");
18124640cde1SColin Riley             type->DumpTypeName(&strm);
18134640cde1SColin Riley         }
18144640cde1SColin Riley         else
18154640cde1SColin Riley         {
18164640cde1SColin Riley             strm.Printf(" - Unknown Type");
18174640cde1SColin Riley         }
18184640cde1SColin Riley     }
18194640cde1SColin Riley     else
18204640cde1SColin Riley     {
18214640cde1SColin Riley         strm.Printf(" - variable identified, but not found in binary");
18224640cde1SColin Riley         const Symbol* s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData);
18234640cde1SColin Riley         if (s)
18244640cde1SColin Riley         {
18254640cde1SColin Riley             strm.Printf(" (symbol exists) ");
18264640cde1SColin Riley         }
18274640cde1SColin Riley     }
18284640cde1SColin Riley 
18295ec532a9SColin Riley     strm.EOL();
18305ec532a9SColin Riley }
18315ec532a9SColin Riley 
18325ec532a9SColin Riley void
18335ec532a9SColin Riley RSKernelDescriptor::Dump(Stream &strm) const
18345ec532a9SColin Riley {
18355ec532a9SColin Riley     strm.Indent(m_name.AsCString());
18365ec532a9SColin Riley     strm.EOL();
18375ec532a9SColin Riley }
18385ec532a9SColin Riley 
18395ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed
18405ec532a9SColin Riley {
18415ec532a9SColin Riley   private:
18425ec532a9SColin Riley   public:
18435ec532a9SColin Riley     CommandObjectRenderScriptRuntimeModuleProbe(CommandInterpreter &interpreter)
18445ec532a9SColin Riley         : CommandObjectParsed(interpreter, "renderscript module probe",
18455ec532a9SColin Riley                               "Initiates a Probe of all loaded modules for kernels and other renderscript objects.",
18465ec532a9SColin Riley                               "renderscript module probe",
1847e87764f2SEnrico Granata                               eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBeLaunched)
18485ec532a9SColin Riley     {
18495ec532a9SColin Riley     }
18505ec532a9SColin Riley 
18515ec532a9SColin Riley     ~CommandObjectRenderScriptRuntimeModuleProbe() {}
18525ec532a9SColin Riley 
18535ec532a9SColin Riley     bool
18545ec532a9SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
18555ec532a9SColin Riley     {
18565ec532a9SColin Riley         const size_t argc = command.GetArgumentCount();
18575ec532a9SColin Riley         if (argc == 0)
18585ec532a9SColin Riley         {
18595ec532a9SColin Riley             Target *target = m_exe_ctx.GetTargetPtr();
18605ec532a9SColin Riley             RenderScriptRuntime *runtime =
18615ec532a9SColin Riley                 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
18625ec532a9SColin Riley             auto module_list = target->GetImages();
18635ec532a9SColin Riley             bool new_rs_details = runtime->ProbeModules(module_list);
18645ec532a9SColin Riley             if (new_rs_details)
18655ec532a9SColin Riley             {
18665ec532a9SColin Riley                 result.AppendMessage("New renderscript modules added to runtime model.");
18675ec532a9SColin Riley             }
18685ec532a9SColin Riley             result.SetStatus(eReturnStatusSuccessFinishResult);
18695ec532a9SColin Riley             return true;
18705ec532a9SColin Riley         }
18715ec532a9SColin Riley 
18725ec532a9SColin Riley         result.AppendErrorWithFormat("'%s' takes no arguments", m_cmd_name.c_str());
18735ec532a9SColin Riley         result.SetStatus(eReturnStatusFailed);
18745ec532a9SColin Riley         return false;
18755ec532a9SColin Riley     }
18765ec532a9SColin Riley };
18775ec532a9SColin Riley 
18785ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed
18795ec532a9SColin Riley {
18805ec532a9SColin Riley   private:
18815ec532a9SColin Riley   public:
18825ec532a9SColin Riley     CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter)
18835ec532a9SColin Riley         : CommandObjectParsed(interpreter, "renderscript module dump",
18845ec532a9SColin Riley                               "Dumps renderscript specific information for all modules.", "renderscript module dump",
1885e87764f2SEnrico Granata                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
18865ec532a9SColin Riley     {
18875ec532a9SColin Riley     }
18885ec532a9SColin Riley 
18895ec532a9SColin Riley     ~CommandObjectRenderScriptRuntimeModuleDump() {}
18905ec532a9SColin Riley 
18915ec532a9SColin Riley     bool
18925ec532a9SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
18935ec532a9SColin Riley     {
18945ec532a9SColin Riley         RenderScriptRuntime *runtime =
18955ec532a9SColin Riley             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
18965ec532a9SColin Riley         runtime->DumpModules(result.GetOutputStream());
18975ec532a9SColin Riley         result.SetStatus(eReturnStatusSuccessFinishResult);
18985ec532a9SColin Riley         return true;
18995ec532a9SColin Riley     }
19005ec532a9SColin Riley };
19015ec532a9SColin Riley 
19025ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword
19035ec532a9SColin Riley {
19045ec532a9SColin Riley   private:
19055ec532a9SColin Riley   public:
19065ec532a9SColin Riley     CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter)
19075ec532a9SColin Riley         : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with renderscript modules.",
19085ec532a9SColin Riley                                  NULL)
19095ec532a9SColin Riley     {
19105ec532a9SColin Riley         LoadSubCommand("probe", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleProbe(interpreter)));
19115ec532a9SColin Riley         LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter)));
19125ec532a9SColin Riley     }
19135ec532a9SColin Riley 
19145ec532a9SColin Riley     ~CommandObjectRenderScriptRuntimeModule() {}
19155ec532a9SColin Riley };
19165ec532a9SColin Riley 
19174640cde1SColin Riley class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed
19184640cde1SColin Riley {
19194640cde1SColin Riley   private:
19204640cde1SColin Riley   public:
19214640cde1SColin Riley     CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter)
19224640cde1SColin Riley         : CommandObjectParsed(interpreter, "renderscript kernel list",
19234640cde1SColin Riley                               "Lists renderscript kernel names and associated script resources.", "renderscript kernel list",
19244640cde1SColin Riley                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
19254640cde1SColin Riley     {
19264640cde1SColin Riley     }
19274640cde1SColin Riley 
19284640cde1SColin Riley     ~CommandObjectRenderScriptRuntimeKernelList() {}
19294640cde1SColin Riley 
19304640cde1SColin Riley     bool
19314640cde1SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
19324640cde1SColin Riley     {
19334640cde1SColin Riley         RenderScriptRuntime *runtime =
19344640cde1SColin Riley             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
19354640cde1SColin Riley         runtime->DumpKernels(result.GetOutputStream());
19364640cde1SColin Riley         result.SetStatus(eReturnStatusSuccessFinishResult);
19374640cde1SColin Riley         return true;
19384640cde1SColin Riley     }
19394640cde1SColin Riley };
19404640cde1SColin Riley 
19417dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpointSet : public CommandObjectParsed
19424640cde1SColin Riley {
19434640cde1SColin Riley   private:
19444640cde1SColin Riley   public:
19457dc7771cSEwan Crawford     CommandObjectRenderScriptRuntimeKernelBreakpointSet(CommandInterpreter &interpreter)
19467dc7771cSEwan Crawford         : CommandObjectParsed(interpreter, "renderscript kernel breakpoint set",
19477dc7771cSEwan Crawford                               "Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint set <kernel_name>",
19484640cde1SColin Riley                               eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
19494640cde1SColin Riley     {
19504640cde1SColin Riley     }
19514640cde1SColin Riley 
19527dc7771cSEwan Crawford     ~CommandObjectRenderScriptRuntimeKernelBreakpointSet() {}
19534640cde1SColin Riley 
19544640cde1SColin Riley     bool
19554640cde1SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
19564640cde1SColin Riley     {
19574640cde1SColin Riley         const size_t argc = command.GetArgumentCount();
19584640cde1SColin Riley         if (argc == 1)
19594640cde1SColin Riley         {
19604640cde1SColin Riley             RenderScriptRuntime *runtime =
19614640cde1SColin Riley                 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
19624640cde1SColin Riley 
19634640cde1SColin Riley             Error error;
196498156583SEwan Crawford             runtime->AttemptBreakpointAtKernelName(result.GetOutputStream(), command.GetArgumentAtIndex(0),
196598156583SEwan Crawford                                                    error, m_exe_ctx.GetTargetSP());
19664640cde1SColin Riley 
19674640cde1SColin Riley             if (error.Success())
19684640cde1SColin Riley             {
19694640cde1SColin Riley                 result.AppendMessage("Breakpoint(s) created");
19704640cde1SColin Riley                 result.SetStatus(eReturnStatusSuccessFinishResult);
19714640cde1SColin Riley                 return true;
19724640cde1SColin Riley             }
19734640cde1SColin Riley             result.SetStatus(eReturnStatusFailed);
19744640cde1SColin Riley             result.AppendErrorWithFormat("Error: %s", error.AsCString());
19754640cde1SColin Riley             return false;
19764640cde1SColin Riley         }
19774640cde1SColin Riley 
19784640cde1SColin Riley         result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name", m_cmd_name.c_str());
19794640cde1SColin Riley         result.SetStatus(eReturnStatusFailed);
19804640cde1SColin Riley         return false;
19814640cde1SColin Riley     }
19824640cde1SColin Riley };
19834640cde1SColin Riley 
19847dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpointAll : public CommandObjectParsed
19857dc7771cSEwan Crawford {
19867dc7771cSEwan Crawford   private:
19877dc7771cSEwan Crawford   public:
19887dc7771cSEwan Crawford     CommandObjectRenderScriptRuntimeKernelBreakpointAll(CommandInterpreter &interpreter)
19897dc7771cSEwan Crawford         : CommandObjectParsed(interpreter, "renderscript kernel breakpoint all",
19907dc7771cSEwan Crawford                               "Automatically sets a breakpoint on all renderscript kernels that are or will be loaded.\n"
19917dc7771cSEwan Crawford                               "Disabling option means breakpoints will no longer be set on any kernels loaded in the future, "
19927dc7771cSEwan Crawford                               "but does not remove currently set breakpoints.",
19937dc7771cSEwan Crawford                               "renderscript kernel breakpoint all <enable/disable>",
19947dc7771cSEwan Crawford                               eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
19957dc7771cSEwan Crawford     {
19967dc7771cSEwan Crawford     }
19977dc7771cSEwan Crawford 
19987dc7771cSEwan Crawford     ~CommandObjectRenderScriptRuntimeKernelBreakpointAll() {}
19997dc7771cSEwan Crawford 
20007dc7771cSEwan Crawford     bool
20017dc7771cSEwan Crawford     DoExecute(Args &command, CommandReturnObject &result)
20027dc7771cSEwan Crawford     {
20037dc7771cSEwan Crawford         const size_t argc = command.GetArgumentCount();
20047dc7771cSEwan Crawford         if (argc != 1)
20057dc7771cSEwan Crawford         {
20067dc7771cSEwan Crawford             result.AppendErrorWithFormat("'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str());
20077dc7771cSEwan Crawford             result.SetStatus(eReturnStatusFailed);
20087dc7771cSEwan Crawford             return false;
20097dc7771cSEwan Crawford         }
20107dc7771cSEwan Crawford 
20117dc7771cSEwan Crawford         RenderScriptRuntime *runtime =
20127dc7771cSEwan Crawford           static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
20137dc7771cSEwan Crawford 
20147dc7771cSEwan Crawford         bool do_break = false;
20157dc7771cSEwan Crawford         const char* argument = command.GetArgumentAtIndex(0);
20167dc7771cSEwan Crawford         if (strcmp(argument, "enable") == 0)
20177dc7771cSEwan Crawford         {
20187dc7771cSEwan Crawford             do_break = true;
20197dc7771cSEwan Crawford             result.AppendMessage("Breakpoints will be set on all kernels.");
20207dc7771cSEwan Crawford         }
20217dc7771cSEwan Crawford         else if (strcmp(argument, "disable") == 0)
20227dc7771cSEwan Crawford         {
20237dc7771cSEwan Crawford             do_break = false;
20247dc7771cSEwan Crawford             result.AppendMessage("Breakpoints will not be set on any new kernels.");
20257dc7771cSEwan Crawford         }
20267dc7771cSEwan Crawford         else
20277dc7771cSEwan Crawford         {
20287dc7771cSEwan Crawford             result.AppendErrorWithFormat("Argument must be either 'enable' or 'disable'");
20297dc7771cSEwan Crawford             result.SetStatus(eReturnStatusFailed);
20307dc7771cSEwan Crawford             return false;
20317dc7771cSEwan Crawford         }
20327dc7771cSEwan Crawford 
20337dc7771cSEwan Crawford         runtime->SetBreakAllKernels(do_break, m_exe_ctx.GetTargetSP());
20347dc7771cSEwan Crawford 
20357dc7771cSEwan Crawford         result.SetStatus(eReturnStatusSuccessFinishResult);
20367dc7771cSEwan Crawford         return true;
20377dc7771cSEwan Crawford     }
20387dc7771cSEwan Crawford };
20397dc7771cSEwan Crawford 
20407dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectMultiword
20417dc7771cSEwan Crawford {
20427dc7771cSEwan Crawford   private:
20437dc7771cSEwan Crawford   public:
20447dc7771cSEwan Crawford     CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter)
20457dc7771cSEwan Crawford         : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that generate breakpoints on renderscript kernels.",
20467dc7771cSEwan Crawford                                  nullptr)
20477dc7771cSEwan Crawford     {
20487dc7771cSEwan Crawford         LoadSubCommand("set", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointSet(interpreter)));
20497dc7771cSEwan Crawford         LoadSubCommand("all", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointAll(interpreter)));
20507dc7771cSEwan Crawford     }
20517dc7771cSEwan Crawford 
20527dc7771cSEwan Crawford     ~CommandObjectRenderScriptRuntimeKernelBreakpoint() {}
20537dc7771cSEwan Crawford };
20547dc7771cSEwan Crawford 
20554640cde1SColin Riley class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword
20564640cde1SColin Riley {
20574640cde1SColin Riley   private:
20584640cde1SColin Riley   public:
20594640cde1SColin Riley     CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter)
20604640cde1SColin Riley         : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with renderscript kernels.",
20614640cde1SColin Riley                                  NULL)
20624640cde1SColin Riley     {
20634640cde1SColin Riley         LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(interpreter)));
20644640cde1SColin Riley         LoadSubCommand("breakpoint", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter)));
20654640cde1SColin Riley     }
20664640cde1SColin Riley 
20674640cde1SColin Riley     ~CommandObjectRenderScriptRuntimeKernel() {}
20684640cde1SColin Riley };
20694640cde1SColin Riley 
20704640cde1SColin Riley class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed
20714640cde1SColin Riley {
20724640cde1SColin Riley   private:
20734640cde1SColin Riley   public:
20744640cde1SColin Riley     CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter)
20754640cde1SColin Riley         : CommandObjectParsed(interpreter, "renderscript context dump",
20764640cde1SColin Riley                               "Dumps renderscript context information.", "renderscript context dump",
20774640cde1SColin Riley                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
20784640cde1SColin Riley     {
20794640cde1SColin Riley     }
20804640cde1SColin Riley 
20814640cde1SColin Riley     ~CommandObjectRenderScriptRuntimeContextDump() {}
20824640cde1SColin Riley 
20834640cde1SColin Riley     bool
20844640cde1SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
20854640cde1SColin Riley     {
20864640cde1SColin Riley         RenderScriptRuntime *runtime =
20874640cde1SColin Riley             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
20884640cde1SColin Riley         runtime->DumpContexts(result.GetOutputStream());
20894640cde1SColin Riley         result.SetStatus(eReturnStatusSuccessFinishResult);
20904640cde1SColin Riley         return true;
20914640cde1SColin Riley     }
20924640cde1SColin Riley };
20934640cde1SColin Riley 
20944640cde1SColin Riley class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword
20954640cde1SColin Riley {
20964640cde1SColin Riley   private:
20974640cde1SColin Riley   public:
20984640cde1SColin Riley     CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter)
20994640cde1SColin Riley         : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with renderscript contexts.",
21004640cde1SColin Riley                                  NULL)
21014640cde1SColin Riley     {
21024640cde1SColin Riley         LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(interpreter)));
21034640cde1SColin Riley     }
21044640cde1SColin Riley 
21054640cde1SColin Riley     ~CommandObjectRenderScriptRuntimeContext() {}
21064640cde1SColin Riley };
21074640cde1SColin Riley 
2108*15f2bd95SEwan Crawford class CommandObjectRenderScriptRuntimeAllocationList : public CommandObjectParsed
2109*15f2bd95SEwan Crawford {
2110*15f2bd95SEwan Crawford   public:
2111*15f2bd95SEwan Crawford     CommandObjectRenderScriptRuntimeAllocationList(CommandInterpreter &interpreter)
2112*15f2bd95SEwan Crawford         : CommandObjectParsed(interpreter, "renderscript allocation list",
2113*15f2bd95SEwan Crawford                               "List renderscript allocations and their information.", "renderscript allocation list",
2114*15f2bd95SEwan Crawford                               eCommandRequiresProcess | eCommandProcessMustBeLaunched), m_options(interpreter)
2115*15f2bd95SEwan Crawford     {
2116*15f2bd95SEwan Crawford     }
2117*15f2bd95SEwan Crawford 
2118*15f2bd95SEwan Crawford     virtual Options*
2119*15f2bd95SEwan Crawford     GetOptions()
2120*15f2bd95SEwan Crawford     {
2121*15f2bd95SEwan Crawford         return &m_options;
2122*15f2bd95SEwan Crawford     }
2123*15f2bd95SEwan Crawford 
2124*15f2bd95SEwan Crawford     class CommandOptions : public Options
2125*15f2bd95SEwan Crawford     {
2126*15f2bd95SEwan Crawford       public:
2127*15f2bd95SEwan Crawford         CommandOptions(CommandInterpreter &interpreter) : Options(interpreter), m_refresh(false)
2128*15f2bd95SEwan Crawford         {
2129*15f2bd95SEwan Crawford         }
2130*15f2bd95SEwan Crawford 
2131*15f2bd95SEwan Crawford         virtual
2132*15f2bd95SEwan Crawford         ~CommandOptions()
2133*15f2bd95SEwan Crawford         {
2134*15f2bd95SEwan Crawford         }
2135*15f2bd95SEwan Crawford 
2136*15f2bd95SEwan Crawford         virtual Error
2137*15f2bd95SEwan Crawford         SetOptionValue(uint32_t option_idx, const char *option_arg)
2138*15f2bd95SEwan Crawford         {
2139*15f2bd95SEwan Crawford             Error error;
2140*15f2bd95SEwan Crawford             const int short_option = m_getopt_table[option_idx].val;
2141*15f2bd95SEwan Crawford 
2142*15f2bd95SEwan Crawford             switch (short_option)
2143*15f2bd95SEwan Crawford             {
2144*15f2bd95SEwan Crawford                 case 'r':
2145*15f2bd95SEwan Crawford                     m_refresh = true;
2146*15f2bd95SEwan Crawford                     break;
2147*15f2bd95SEwan Crawford                 default:
2148*15f2bd95SEwan Crawford                     error.SetErrorStringWithFormat("unrecognized option '%c'", short_option);
2149*15f2bd95SEwan Crawford                     break;
2150*15f2bd95SEwan Crawford             }
2151*15f2bd95SEwan Crawford             return error;
2152*15f2bd95SEwan Crawford         }
2153*15f2bd95SEwan Crawford 
2154*15f2bd95SEwan Crawford         void
2155*15f2bd95SEwan Crawford         OptionParsingStarting()
2156*15f2bd95SEwan Crawford         {
2157*15f2bd95SEwan Crawford             m_refresh = false;
2158*15f2bd95SEwan Crawford         }
2159*15f2bd95SEwan Crawford 
2160*15f2bd95SEwan Crawford         const OptionDefinition*
2161*15f2bd95SEwan Crawford         GetDefinitions()
2162*15f2bd95SEwan Crawford         {
2163*15f2bd95SEwan Crawford             return g_option_table;
2164*15f2bd95SEwan Crawford         }
2165*15f2bd95SEwan Crawford 
2166*15f2bd95SEwan Crawford         static OptionDefinition g_option_table[];
2167*15f2bd95SEwan Crawford         bool m_refresh;
2168*15f2bd95SEwan Crawford     };
2169*15f2bd95SEwan Crawford 
2170*15f2bd95SEwan Crawford     ~CommandObjectRenderScriptRuntimeAllocationList() {}
2171*15f2bd95SEwan Crawford 
2172*15f2bd95SEwan Crawford     bool
2173*15f2bd95SEwan Crawford     DoExecute(Args &command, CommandReturnObject &result)
2174*15f2bd95SEwan Crawford     {
2175*15f2bd95SEwan Crawford         RenderScriptRuntime *runtime =
2176*15f2bd95SEwan Crawford           static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
2177*15f2bd95SEwan Crawford         runtime->ListAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr(), m_options.m_refresh);
2178*15f2bd95SEwan Crawford         result.SetStatus(eReturnStatusSuccessFinishResult);
2179*15f2bd95SEwan Crawford         return true;
2180*15f2bd95SEwan Crawford     }
2181*15f2bd95SEwan Crawford 
2182*15f2bd95SEwan Crawford   private:
2183*15f2bd95SEwan Crawford     CommandOptions m_options;
2184*15f2bd95SEwan Crawford };
2185*15f2bd95SEwan Crawford 
2186*15f2bd95SEwan Crawford OptionDefinition
2187*15f2bd95SEwan Crawford CommandObjectRenderScriptRuntimeAllocationList::CommandOptions::g_option_table[] =
2188*15f2bd95SEwan Crawford {
2189*15f2bd95SEwan Crawford     { LLDB_OPT_SET_1, false, "refresh", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,
2190*15f2bd95SEwan Crawford       "Recompute allocation details."},
2191*15f2bd95SEwan Crawford     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2192*15f2bd95SEwan Crawford };
2193*15f2bd95SEwan Crawford 
2194*15f2bd95SEwan Crawford 
2195*15f2bd95SEwan Crawford class CommandObjectRenderScriptRuntimeAllocation : public CommandObjectMultiword
2196*15f2bd95SEwan Crawford {
2197*15f2bd95SEwan Crawford   private:
2198*15f2bd95SEwan Crawford   public:
2199*15f2bd95SEwan Crawford     CommandObjectRenderScriptRuntimeAllocation(CommandInterpreter &interpreter)
2200*15f2bd95SEwan Crawford         : CommandObjectMultiword(interpreter, "renderscript allocation", "Commands that deal with renderscript allocations.",
2201*15f2bd95SEwan Crawford                                  NULL)
2202*15f2bd95SEwan Crawford     {
2203*15f2bd95SEwan Crawford         LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationList(interpreter)));
2204*15f2bd95SEwan Crawford     }
2205*15f2bd95SEwan Crawford 
2206*15f2bd95SEwan Crawford     ~CommandObjectRenderScriptRuntimeAllocation() {}
2207*15f2bd95SEwan Crawford };
2208*15f2bd95SEwan Crawford 
2209*15f2bd95SEwan Crawford 
22104640cde1SColin Riley class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed
22114640cde1SColin Riley {
22124640cde1SColin Riley   private:
22134640cde1SColin Riley   public:
22144640cde1SColin Riley     CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter)
22154640cde1SColin Riley         : CommandObjectParsed(interpreter, "renderscript status",
22164640cde1SColin Riley                               "Displays current renderscript runtime status.", "renderscript status",
22174640cde1SColin Riley                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
22184640cde1SColin Riley     {
22194640cde1SColin Riley     }
22204640cde1SColin Riley 
22214640cde1SColin Riley     ~CommandObjectRenderScriptRuntimeStatus() {}
22224640cde1SColin Riley 
22234640cde1SColin Riley     bool
22244640cde1SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
22254640cde1SColin Riley     {
22264640cde1SColin Riley         RenderScriptRuntime *runtime =
22274640cde1SColin Riley             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
22284640cde1SColin Riley         runtime->Status(result.GetOutputStream());
22294640cde1SColin Riley         result.SetStatus(eReturnStatusSuccessFinishResult);
22304640cde1SColin Riley         return true;
22314640cde1SColin Riley     }
22324640cde1SColin Riley };
22334640cde1SColin Riley 
22345ec532a9SColin Riley class CommandObjectRenderScriptRuntime : public CommandObjectMultiword
22355ec532a9SColin Riley {
22365ec532a9SColin Riley   public:
22375ec532a9SColin Riley     CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter)
22385ec532a9SColin Riley         : CommandObjectMultiword(interpreter, "renderscript", "A set of commands for operating on renderscript.",
22395ec532a9SColin Riley                                  "renderscript <subcommand> [<subcommand-options>]")
22405ec532a9SColin Riley     {
22415ec532a9SColin Riley         LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter)));
22424640cde1SColin Riley         LoadSubCommand("status", CommandObjectSP(new CommandObjectRenderScriptRuntimeStatus(interpreter)));
22434640cde1SColin Riley         LoadSubCommand("kernel", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernel(interpreter)));
22444640cde1SColin Riley         LoadSubCommand("context", CommandObjectSP(new CommandObjectRenderScriptRuntimeContext(interpreter)));
2245*15f2bd95SEwan Crawford         LoadSubCommand("allocation", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocation(interpreter)));
22465ec532a9SColin Riley     }
22475ec532a9SColin Riley 
22485ec532a9SColin Riley     ~CommandObjectRenderScriptRuntime() {}
22495ec532a9SColin Riley };
2250ef20b08fSColin Riley 
2251ef20b08fSColin Riley void
2252ef20b08fSColin Riley RenderScriptRuntime::Initiate()
22535ec532a9SColin Riley {
2254ef20b08fSColin Riley     assert(!m_initiated);
22555ec532a9SColin Riley }
2256ef20b08fSColin Riley 
2257ef20b08fSColin Riley RenderScriptRuntime::RenderScriptRuntime(Process *process)
22587dc7771cSEwan Crawford     : lldb_private::CPPLanguageRuntime(process), m_initiated(false), m_debuggerPresentFlagged(false),
22597dc7771cSEwan Crawford       m_breakAllKernels(false)
2260ef20b08fSColin Riley {
22614640cde1SColin Riley     ModulesDidLoad(process->GetTarget().GetImages());
2262ef20b08fSColin Riley }
22634640cde1SColin Riley 
22644640cde1SColin Riley lldb::CommandObjectSP
22654640cde1SColin Riley RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter& interpreter)
22664640cde1SColin Riley {
22674640cde1SColin Riley     static CommandObjectSP command_object;
22684640cde1SColin Riley     if(!command_object)
22694640cde1SColin Riley     {
22704640cde1SColin Riley         command_object.reset(new CommandObjectRenderScriptRuntime(interpreter));
22714640cde1SColin Riley     }
22724640cde1SColin Riley     return command_object;
22734640cde1SColin Riley }
22744640cde1SColin Riley 
227578f339d1SEwan Crawford RenderScriptRuntime::~RenderScriptRuntime() = default;
2276