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"
284640cde1SColin Riley 
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 
35*78f339d1SEwan Crawford namespace {
36*78f339d1SEwan Crawford 
37*78f339d1SEwan Crawford // The empirical_type adds a basic level of validation to arbitrary data
38*78f339d1SEwan Crawford // allowing us to track if data has been discovered and stored or not.
39*78f339d1SEwan Crawford // An empirical_type will be marked as valid only if it has been explicitly assigned to.
40*78f339d1SEwan Crawford template <typename type_t>
41*78f339d1SEwan Crawford class empirical_type
42*78f339d1SEwan Crawford {
43*78f339d1SEwan Crawford   public:
44*78f339d1SEwan Crawford     // Ctor. Contents is invalid when constructed.
45*78f339d1SEwan Crawford     empirical_type()
46*78f339d1SEwan Crawford         : valid(false)
47*78f339d1SEwan Crawford     {}
48*78f339d1SEwan Crawford 
49*78f339d1SEwan Crawford     // Return true and copy contents to out if valid, else return false.
50*78f339d1SEwan Crawford     bool get(type_t& out) const
51*78f339d1SEwan Crawford     {
52*78f339d1SEwan Crawford         if (valid)
53*78f339d1SEwan Crawford             out = data;
54*78f339d1SEwan Crawford         return valid;
55*78f339d1SEwan Crawford     }
56*78f339d1SEwan Crawford 
57*78f339d1SEwan Crawford     // Return a pointer to the contents or nullptr if it was not valid.
58*78f339d1SEwan Crawford     const type_t* get() const
59*78f339d1SEwan Crawford     {
60*78f339d1SEwan Crawford         return valid ? &data : nullptr;
61*78f339d1SEwan Crawford     }
62*78f339d1SEwan Crawford 
63*78f339d1SEwan Crawford     // Assign data explicitly.
64*78f339d1SEwan Crawford     void set(const type_t in)
65*78f339d1SEwan Crawford     {
66*78f339d1SEwan Crawford         data = in;
67*78f339d1SEwan Crawford         valid = true;
68*78f339d1SEwan Crawford     }
69*78f339d1SEwan Crawford 
70*78f339d1SEwan Crawford     // Mark contents as invalid.
71*78f339d1SEwan Crawford     void invalidate()
72*78f339d1SEwan Crawford     {
73*78f339d1SEwan Crawford         valid = false;
74*78f339d1SEwan Crawford     }
75*78f339d1SEwan Crawford 
76*78f339d1SEwan Crawford     // Returns true if this type contains valid data.
77*78f339d1SEwan Crawford     bool isValid() const
78*78f339d1SEwan Crawford     {
79*78f339d1SEwan Crawford         return valid;
80*78f339d1SEwan Crawford     }
81*78f339d1SEwan Crawford 
82*78f339d1SEwan Crawford     // Assignment operator.
83*78f339d1SEwan Crawford     empirical_type<type_t>& operator = (const type_t in)
84*78f339d1SEwan Crawford     {
85*78f339d1SEwan Crawford         set(in);
86*78f339d1SEwan Crawford         return *this;
87*78f339d1SEwan Crawford     }
88*78f339d1SEwan Crawford 
89*78f339d1SEwan Crawford     // Dereference operator returns contents.
90*78f339d1SEwan Crawford     // Warning: Will assert if not valid so use only when you know data is valid.
91*78f339d1SEwan Crawford     const type_t& operator * () const
92*78f339d1SEwan Crawford     {
93*78f339d1SEwan Crawford         assert(valid);
94*78f339d1SEwan Crawford         return data;
95*78f339d1SEwan Crawford     }
96*78f339d1SEwan Crawford 
97*78f339d1SEwan Crawford   protected:
98*78f339d1SEwan Crawford     bool valid;
99*78f339d1SEwan Crawford     type_t data;
100*78f339d1SEwan Crawford };
101*78f339d1SEwan Crawford 
102*78f339d1SEwan Crawford } // namespace {}
103*78f339d1SEwan Crawford 
104*78f339d1SEwan Crawford // The ScriptDetails class collects data associated with a single script instance.
105*78f339d1SEwan Crawford struct RenderScriptRuntime::ScriptDetails
106*78f339d1SEwan Crawford {
107*78f339d1SEwan Crawford     ~ScriptDetails() {};
108*78f339d1SEwan Crawford 
109*78f339d1SEwan Crawford     enum ScriptType
110*78f339d1SEwan Crawford     {
111*78f339d1SEwan Crawford         eScript,
112*78f339d1SEwan Crawford         eScriptC
113*78f339d1SEwan Crawford     };
114*78f339d1SEwan Crawford 
115*78f339d1SEwan Crawford     // The derived type of the script.
116*78f339d1SEwan Crawford     empirical_type<ScriptType> type;
117*78f339d1SEwan Crawford     // The name of the original source file.
118*78f339d1SEwan Crawford     empirical_type<std::string> resName;
119*78f339d1SEwan Crawford     // Path to script .so file on the device.
120*78f339d1SEwan Crawford     empirical_type<std::string> scriptDyLib;
121*78f339d1SEwan Crawford     // Directory where kernel objects are cached on device.
122*78f339d1SEwan Crawford     empirical_type<std::string> cacheDir;
123*78f339d1SEwan Crawford     // Pointer to the context which owns this script.
124*78f339d1SEwan Crawford     empirical_type<lldb::addr_t> context;
125*78f339d1SEwan Crawford     // Pointer to the script object itself.
126*78f339d1SEwan Crawford     empirical_type<lldb::addr_t> script;
127*78f339d1SEwan Crawford };
128*78f339d1SEwan Crawford 
129*78f339d1SEwan Crawford // This AllocationDetails class collects data associated with a single
130*78f339d1SEwan Crawford // allocation instance.
131*78f339d1SEwan Crawford struct RenderScriptRuntime::AllocationDetails
132*78f339d1SEwan Crawford {
133*78f339d1SEwan Crawford     ~AllocationDetails () {};
134*78f339d1SEwan Crawford 
135*78f339d1SEwan Crawford     enum DataType
136*78f339d1SEwan Crawford     {
137*78f339d1SEwan Crawford         eInt,
138*78f339d1SEwan Crawford     };
139*78f339d1SEwan Crawford 
140*78f339d1SEwan Crawford     enum Dimension
141*78f339d1SEwan Crawford     {
142*78f339d1SEwan Crawford         e1d,
143*78f339d1SEwan Crawford         e2d,
144*78f339d1SEwan Crawford         e3d,
145*78f339d1SEwan Crawford         eCubeMap,
146*78f339d1SEwan Crawford     };
147*78f339d1SEwan Crawford 
148*78f339d1SEwan Crawford     empirical_type<DataType> type;
149*78f339d1SEwan Crawford     empirical_type<Dimension> dimension;
150*78f339d1SEwan Crawford     empirical_type<lldb::addr_t> address;
151*78f339d1SEwan Crawford     empirical_type<lldb::addr_t> dataPtr;
152*78f339d1SEwan Crawford     empirical_type<lldb::addr_t> context;
153*78f339d1SEwan Crawford };
154*78f339d1SEwan Crawford 
1555ec532a9SColin Riley //------------------------------------------------------------------
1565ec532a9SColin Riley // Static Functions
1575ec532a9SColin Riley //------------------------------------------------------------------
1585ec532a9SColin Riley LanguageRuntime *
1595ec532a9SColin Riley RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType language)
1605ec532a9SColin Riley {
1615ec532a9SColin Riley 
1625ec532a9SColin Riley     if (language == eLanguageTypeExtRenderScript)
1635ec532a9SColin Riley         return new RenderScriptRuntime(process);
1645ec532a9SColin Riley     else
1655ec532a9SColin Riley         return NULL;
1665ec532a9SColin Riley }
1675ec532a9SColin Riley 
16898156583SEwan Crawford // Callback with a module to search for matching symbols.
16998156583SEwan Crawford // We first check that the module contains RS kernels.
17098156583SEwan Crawford // Then look for a symbol which matches our kernel name.
17198156583SEwan Crawford // The breakpoint address is finally set using the address of this symbol.
17298156583SEwan Crawford Searcher::CallbackReturn
17398156583SEwan Crawford RSBreakpointResolver::SearchCallback(SearchFilter &filter,
17498156583SEwan Crawford                                      SymbolContext &context,
17598156583SEwan Crawford                                      Address*,
17698156583SEwan Crawford                                      bool)
17798156583SEwan Crawford {
17898156583SEwan Crawford     ModuleSP module = context.module_sp;
17998156583SEwan Crawford 
18098156583SEwan Crawford     if (!module)
18198156583SEwan Crawford         return Searcher::eCallbackReturnContinue;
18298156583SEwan Crawford 
18398156583SEwan Crawford     // Is this a module containing renderscript kernels?
18498156583SEwan Crawford     if (nullptr == module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData))
18598156583SEwan Crawford         return Searcher::eCallbackReturnContinue;
18698156583SEwan Crawford 
18798156583SEwan Crawford     // Attempt to set a breakpoint on the kernel name symbol within the module library.
18898156583SEwan Crawford     // If it's not found, it's likely debug info is unavailable - try to set a
18998156583SEwan Crawford     // breakpoint on <name>.expand.
19098156583SEwan Crawford 
19198156583SEwan Crawford     const Symbol* kernel_sym = module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode);
19298156583SEwan Crawford     if (!kernel_sym)
19398156583SEwan Crawford     {
19498156583SEwan Crawford         std::string kernel_name_expanded(m_kernel_name.AsCString());
19598156583SEwan Crawford         kernel_name_expanded.append(".expand");
19698156583SEwan Crawford         kernel_sym = module->FindFirstSymbolWithNameAndType(ConstString(kernel_name_expanded.c_str()), eSymbolTypeCode);
19798156583SEwan Crawford     }
19898156583SEwan Crawford 
19998156583SEwan Crawford     if (kernel_sym)
20098156583SEwan Crawford     {
20198156583SEwan Crawford         Address bp_addr = kernel_sym->GetAddress();
20298156583SEwan Crawford         if (filter.AddressPasses(bp_addr))
20398156583SEwan Crawford             m_breakpoint->AddLocation(bp_addr);
20498156583SEwan Crawford     }
20598156583SEwan Crawford 
20698156583SEwan Crawford     return Searcher::eCallbackReturnContinue;
20798156583SEwan Crawford }
20898156583SEwan Crawford 
2095ec532a9SColin Riley void
2105ec532a9SColin Riley RenderScriptRuntime::Initialize()
2115ec532a9SColin Riley {
2124640cde1SColin Riley     PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance, GetCommandObject);
2135ec532a9SColin Riley }
2145ec532a9SColin Riley 
2155ec532a9SColin Riley void
2165ec532a9SColin Riley RenderScriptRuntime::Terminate()
2175ec532a9SColin Riley {
2185ec532a9SColin Riley     PluginManager::UnregisterPlugin(CreateInstance);
2195ec532a9SColin Riley }
2205ec532a9SColin Riley 
2215ec532a9SColin Riley lldb_private::ConstString
2225ec532a9SColin Riley RenderScriptRuntime::GetPluginNameStatic()
2235ec532a9SColin Riley {
2245ec532a9SColin Riley     static ConstString g_name("renderscript");
2255ec532a9SColin Riley     return g_name;
2265ec532a9SColin Riley }
2275ec532a9SColin Riley 
228ef20b08fSColin Riley RenderScriptRuntime::ModuleKind
229ef20b08fSColin Riley RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp)
230ef20b08fSColin Riley {
231ef20b08fSColin Riley     if (module_sp)
232ef20b08fSColin Riley     {
233ef20b08fSColin Riley         // Is this a module containing renderscript kernels?
234ef20b08fSColin Riley         const Symbol *info_sym = module_sp->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
235ef20b08fSColin Riley         if (info_sym)
236ef20b08fSColin Riley         {
237ef20b08fSColin Riley             return eModuleKindKernelObj;
238ef20b08fSColin Riley         }
2394640cde1SColin Riley 
2404640cde1SColin Riley         // Is this the main RS runtime library
2414640cde1SColin Riley         const ConstString rs_lib("libRS.so");
2424640cde1SColin Riley         if (module_sp->GetFileSpec().GetFilename() == rs_lib)
2434640cde1SColin Riley         {
2444640cde1SColin Riley             return eModuleKindLibRS;
2454640cde1SColin Riley         }
2464640cde1SColin Riley 
2474640cde1SColin Riley         const ConstString rs_driverlib("libRSDriver.so");
2484640cde1SColin Riley         if (module_sp->GetFileSpec().GetFilename() == rs_driverlib)
2494640cde1SColin Riley         {
2504640cde1SColin Riley             return eModuleKindDriver;
2514640cde1SColin Riley         }
2524640cde1SColin Riley 
2534640cde1SColin Riley         const ConstString rs_cpureflib("libRSCPURef.so");
2544640cde1SColin Riley         if (module_sp->GetFileSpec().GetFilename() == rs_cpureflib)
2554640cde1SColin Riley         {
2564640cde1SColin Riley             return eModuleKindImpl;
2574640cde1SColin Riley         }
2584640cde1SColin Riley 
259ef20b08fSColin Riley     }
260ef20b08fSColin Riley     return eModuleKindIgnored;
261ef20b08fSColin Riley }
262ef20b08fSColin Riley 
263ef20b08fSColin Riley bool
264ef20b08fSColin Riley RenderScriptRuntime::IsRenderScriptModule(const lldb::ModuleSP &module_sp)
265ef20b08fSColin Riley {
266ef20b08fSColin Riley     return GetModuleKind(module_sp) != eModuleKindIgnored;
267ef20b08fSColin Riley }
268ef20b08fSColin Riley 
269ef20b08fSColin Riley 
270ef20b08fSColin Riley void
271ef20b08fSColin Riley RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list )
272ef20b08fSColin Riley {
273ef20b08fSColin Riley     Mutex::Locker locker (module_list.GetMutex ());
274ef20b08fSColin Riley 
275ef20b08fSColin Riley     size_t num_modules = module_list.GetSize();
276ef20b08fSColin Riley     for (size_t i = 0; i < num_modules; i++)
277ef20b08fSColin Riley     {
278ef20b08fSColin Riley         auto mod = module_list.GetModuleAtIndex (i);
279ef20b08fSColin Riley         if (IsRenderScriptModule (mod))
280ef20b08fSColin Riley         {
281ef20b08fSColin Riley             LoadModule(mod);
282ef20b08fSColin Riley         }
283ef20b08fSColin Riley     }
284ef20b08fSColin Riley }
285ef20b08fSColin Riley 
286ef20b08fSColin Riley 
2875ec532a9SColin Riley //------------------------------------------------------------------
2885ec532a9SColin Riley // PluginInterface protocol
2895ec532a9SColin Riley //------------------------------------------------------------------
2905ec532a9SColin Riley lldb_private::ConstString
2915ec532a9SColin Riley RenderScriptRuntime::GetPluginName()
2925ec532a9SColin Riley {
2935ec532a9SColin Riley     return GetPluginNameStatic();
2945ec532a9SColin Riley }
2955ec532a9SColin Riley 
2965ec532a9SColin Riley uint32_t
2975ec532a9SColin Riley RenderScriptRuntime::GetPluginVersion()
2985ec532a9SColin Riley {
2995ec532a9SColin Riley     return 1;
3005ec532a9SColin Riley }
3015ec532a9SColin Riley 
3025ec532a9SColin Riley bool
3035ec532a9SColin Riley RenderScriptRuntime::IsVTableName(const char *name)
3045ec532a9SColin Riley {
3055ec532a9SColin Riley     return false;
3065ec532a9SColin Riley }
3075ec532a9SColin Riley 
3085ec532a9SColin Riley bool
3095ec532a9SColin Riley RenderScriptRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
3100b6003f3SEnrico Granata                                               TypeAndOrName &class_type_or_name, Address &address,
3110b6003f3SEnrico Granata                                               Value::ValueType &value_type)
3125ec532a9SColin Riley {
3135ec532a9SColin Riley     return false;
3145ec532a9SColin Riley }
3155ec532a9SColin Riley 
3165ec532a9SColin Riley bool
3175ec532a9SColin Riley RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value)
3185ec532a9SColin Riley {
3195ec532a9SColin Riley     return false;
3205ec532a9SColin Riley }
3215ec532a9SColin Riley 
3225ec532a9SColin Riley lldb::BreakpointResolverSP
3235ec532a9SColin Riley RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp)
3245ec532a9SColin Riley {
3255ec532a9SColin Riley     BreakpointResolverSP resolver_sp;
3265ec532a9SColin Riley     return resolver_sp;
3275ec532a9SColin Riley }
3285ec532a9SColin Riley 
3294640cde1SColin Riley 
3304640cde1SColin Riley const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] =
3314640cde1SColin Riley {
3324640cde1SColin Riley     //rsdScript
33382780287SAidan Dodds     {
33482780287SAidan Dodds         "rsdScriptInit", //name
33582780287SAidan Dodds         "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhjj", // symbol name 32 bit
33682780287SAidan Dodds         "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhmj", // symbol name 64 bit
33782780287SAidan Dodds         0, // version
33882780287SAidan Dodds         RenderScriptRuntime::eModuleKindDriver, // type
33982780287SAidan Dodds         &lldb_private::RenderScriptRuntime::CaptureScriptInit1 // handler
34082780287SAidan Dodds     },
34182780287SAidan Dodds     {
34282780287SAidan Dodds         "rsdScriptInvokeForEach", // name
34382780287SAidan Dodds         "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvjPK12RsScriptCall", // symbol name 32bit
34482780287SAidan Dodds         "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvmPK12RsScriptCall", // symbol name 64bit
34582780287SAidan Dodds         0, // version
34682780287SAidan Dodds         RenderScriptRuntime::eModuleKindDriver, // type
34782780287SAidan Dodds         nullptr // handler
34882780287SAidan Dodds     },
34982780287SAidan Dodds     {
35082780287SAidan Dodds         "rsdScriptInvokeForEachMulti", // name
35182780287SAidan Dodds         "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall", // symbol name 32bit
35282780287SAidan Dodds         "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEmPS6_PKvmPK12RsScriptCall", // symbol name 64bit
35382780287SAidan Dodds         0, // version
35482780287SAidan Dodds         RenderScriptRuntime::eModuleKindDriver, // type
35582780287SAidan Dodds         nullptr // handler
35682780287SAidan Dodds     },
35782780287SAidan Dodds     {
35882780287SAidan Dodds         "rsdScriptInvokeFunction", // name
35982780287SAidan Dodds         "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvj", // symbol name 32bit
36082780287SAidan Dodds         "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvm", // symbol name 64bit
36182780287SAidan Dodds         0, // version
36282780287SAidan Dodds         RenderScriptRuntime::eModuleKindDriver, // type
36382780287SAidan Dodds         nullptr // handler
36482780287SAidan Dodds     },
36582780287SAidan Dodds     {
36682780287SAidan Dodds         "rsdScriptSetGlobalVar", // name
36782780287SAidan Dodds         "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvj", // symbol name 32bit
36882780287SAidan Dodds         "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvm", // symbol name 64bit
36982780287SAidan Dodds         0, // version
37082780287SAidan Dodds         RenderScriptRuntime::eModuleKindDriver, // type
37182780287SAidan Dodds         &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar1 // handler
37282780287SAidan Dodds     },
3734640cde1SColin Riley 
3744640cde1SColin Riley     //rsdAllocation
37582780287SAidan Dodds     {
37682780287SAidan Dodds         "rsdAllocationInit", // name
37782780287SAidan Dodds         "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 32bit
37882780287SAidan Dodds         "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 64bit
37982780287SAidan Dodds         0, // version
38082780287SAidan Dodds         RenderScriptRuntime::eModuleKindDriver, // type
38182780287SAidan Dodds         &lldb_private::RenderScriptRuntime::CaptureAllocationInit1 // handler
38282780287SAidan Dodds     },
38382780287SAidan Dodds     {
38482780287SAidan Dodds         "rsdAllocationRead2D", //name
38582780287SAidan Dodds         "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvjj", // symbol name 32bit
38682780287SAidan Dodds         "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvmm", // symbol name 64bit
38782780287SAidan Dodds         0, // version
38882780287SAidan Dodds         RenderScriptRuntime::eModuleKindDriver, // type
38982780287SAidan Dodds         nullptr // handler
39082780287SAidan Dodds     },
3914640cde1SColin Riley };
3924640cde1SColin Riley const size_t RenderScriptRuntime::s_runtimeHookCount = sizeof(s_runtimeHookDefns)/sizeof(s_runtimeHookDefns[0]);
3934640cde1SColin Riley 
3944640cde1SColin Riley 
3954640cde1SColin Riley bool
3964640cde1SColin Riley RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
3974640cde1SColin Riley {
3984640cde1SColin Riley     RuntimeHook* hook_info = (RuntimeHook*)baton;
3994640cde1SColin Riley     ExecutionContext context(ctx->exe_ctx_ref);
4004640cde1SColin Riley 
4014640cde1SColin Riley     RenderScriptRuntime *lang_rt = (RenderScriptRuntime *)context.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
4024640cde1SColin Riley 
4034640cde1SColin Riley     lang_rt->HookCallback(hook_info, context);
4044640cde1SColin Riley 
4054640cde1SColin Riley     return false;
4064640cde1SColin Riley }
4074640cde1SColin Riley 
4084640cde1SColin Riley 
4094640cde1SColin Riley void
4104640cde1SColin Riley RenderScriptRuntime::HookCallback(RuntimeHook* hook_info, ExecutionContext& context)
4114640cde1SColin Riley {
4124640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
4134640cde1SColin Riley 
4144640cde1SColin Riley     if (log)
4154640cde1SColin Riley         log->Printf ("RenderScriptRuntime::HookCallback - '%s' .", hook_info->defn->name);
4164640cde1SColin Riley 
4174640cde1SColin Riley     if (hook_info->defn->grabber)
4184640cde1SColin Riley     {
4194640cde1SColin Riley         (this->*(hook_info->defn->grabber))(hook_info, context);
4204640cde1SColin Riley     }
4214640cde1SColin Riley }
4224640cde1SColin Riley 
4234640cde1SColin Riley 
4244640cde1SColin Riley bool
42582780287SAidan Dodds RenderScriptRuntime::GetArgSimple(ExecutionContext &context, uint32_t arg, uint64_t *data)
4264640cde1SColin Riley {
4274640cde1SColin Riley     if (!data)
4284640cde1SColin Riley         return false;
4294640cde1SColin Riley 
43082780287SAidan Dodds     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
4314640cde1SColin Riley     Error error;
4324640cde1SColin Riley     RegisterContext* reg_ctx = context.GetRegisterContext();
4334640cde1SColin Riley     Process* process = context.GetProcessPtr();
43482780287SAidan Dodds     bool success = false; // return value
4354640cde1SColin Riley 
43682780287SAidan Dodds     if (!context.GetTargetPtr())
43782780287SAidan Dodds     {
43882780287SAidan Dodds         if (log)
43982780287SAidan Dodds             log->Printf("RenderScriptRuntime::GetArgSimple - Invalid target");
44082780287SAidan Dodds 
44182780287SAidan Dodds         return false;
44282780287SAidan Dodds     }
44382780287SAidan Dodds 
44482780287SAidan Dodds     switch (context.GetTargetPtr()->GetArchitecture().GetMachine())
44582780287SAidan Dodds     {
44682780287SAidan Dodds         case llvm::Triple::ArchType::x86:
4474640cde1SColin Riley         {
4484640cde1SColin Riley             uint64_t sp = reg_ctx->GetSP();
4494640cde1SColin Riley             uint32_t offset = (1 + arg) * sizeof(uint32_t);
45082780287SAidan Dodds             uint32_t result = 0;
45182780287SAidan Dodds             process->ReadMemory(sp + offset, &result, sizeof(uint32_t), error);
4524640cde1SColin Riley             if (error.Fail())
4534640cde1SColin Riley             {
4544640cde1SColin Riley                 if (log)
45582780287SAidan Dodds                     log->Printf ("RenderScriptRuntime:: GetArgSimple - error reading X86 stack: %s.", error.AsCString());
4564640cde1SColin Riley             }
45782780287SAidan Dodds             else
4584640cde1SColin Riley             {
45982780287SAidan Dodds                 *data = result;
46082780287SAidan Dodds                 success = true;
46182780287SAidan Dodds             }
46282780287SAidan Dodds 
46382780287SAidan Dodds             break;
46482780287SAidan Dodds         }
46582780287SAidan Dodds         case llvm::Triple::ArchType::arm:
46682780287SAidan Dodds         {
46782780287SAidan Dodds             // arm 32 bit
4684640cde1SColin Riley             if (arg < 4)
4694640cde1SColin Riley             {
4704640cde1SColin Riley                 const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg);
4714640cde1SColin Riley                 RegisterValue rVal;
4724640cde1SColin Riley                 reg_ctx->ReadRegister(rArg, rVal);
4734640cde1SColin Riley                 (*data) = rVal.GetAsUInt32();
47482780287SAidan Dodds                 success = true;
4754640cde1SColin Riley             }
4764640cde1SColin Riley             else
4774640cde1SColin Riley             {
4784640cde1SColin Riley                 uint64_t sp = reg_ctx->GetSP();
4794640cde1SColin Riley                 {
4804640cde1SColin Riley                     uint32_t offset = (arg-4) * sizeof(uint32_t);
4814640cde1SColin Riley                     process->ReadMemory(sp + offset, &data, sizeof(uint32_t), error);
4824640cde1SColin Riley                     if (error.Fail())
4834640cde1SColin Riley                     {
4844640cde1SColin Riley                         if (log)
48582780287SAidan Dodds                             log->Printf ("RenderScriptRuntime:: GetArgSimple - error reading ARM stack: %s.", error.AsCString());
48682780287SAidan Dodds                     }
48782780287SAidan Dodds                     else
48882780287SAidan Dodds                     {
48982780287SAidan Dodds                         success = true;
4904640cde1SColin Riley                     }
4914640cde1SColin Riley                 }
4924640cde1SColin Riley             }
49382780287SAidan Dodds 
49482780287SAidan Dodds             break;
4954640cde1SColin Riley         }
49682780287SAidan Dodds         case llvm::Triple::ArchType::aarch64:
49782780287SAidan Dodds         {
49882780287SAidan Dodds             // arm 64 bit
49982780287SAidan Dodds             // first 8 arguments are in the registers
50082780287SAidan Dodds             if (arg < 8)
50182780287SAidan Dodds             {
50282780287SAidan Dodds                 const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg);
50382780287SAidan Dodds                 RegisterValue rVal;
50482780287SAidan Dodds                 success = reg_ctx->ReadRegister(rArg, rVal);
50582780287SAidan Dodds                 if (success)
50682780287SAidan Dodds                 {
50782780287SAidan Dodds                     *data = rVal.GetAsUInt64();
50882780287SAidan Dodds                 }
50982780287SAidan Dodds                 else
51082780287SAidan Dodds                 {
51182780287SAidan Dodds                     if (log)
51282780287SAidan Dodds                         log->Printf("RenderScriptRuntime::GetArgSimple() - AARCH64 - Error while reading the argument #%d", arg);
51382780287SAidan Dodds                 }
51482780287SAidan Dodds             }
51582780287SAidan Dodds             else
51682780287SAidan Dodds             {
51782780287SAidan Dodds                 // @TODO: need to find the argument in the stack
51882780287SAidan Dodds                 if (log)
51982780287SAidan Dodds                     log->Printf("RenderScriptRuntime::GetArgSimple - AARCH64 - FOR #ARG >= 8 NOT IMPLEMENTED YET. Argument number: %d", arg);
52082780287SAidan Dodds             }
52182780287SAidan Dodds             break;
52282780287SAidan Dodds         }
52382780287SAidan Dodds         default:
52482780287SAidan Dodds         {
52582780287SAidan Dodds             // invalid architecture
52682780287SAidan Dodds             if (log)
52782780287SAidan Dodds                 log->Printf("RenderScriptRuntime::GetArgSimple - Architecture not supported");
52882780287SAidan Dodds 
52982780287SAidan Dodds         }
53082780287SAidan Dodds     }
53182780287SAidan Dodds 
53282780287SAidan Dodds 
53382780287SAidan Dodds     return success;
5344640cde1SColin Riley }
5354640cde1SColin Riley 
5364640cde1SColin Riley void
5374640cde1SColin Riley RenderScriptRuntime::CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context)
5384640cde1SColin Riley {
5394640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
5404640cde1SColin Riley 
5414640cde1SColin Riley     //Context, Script, int, data, length
5424640cde1SColin Riley 
54382780287SAidan Dodds     uint64_t rs_context_u64 = 0U;
54482780287SAidan Dodds     uint64_t rs_script_u64 = 0U;
54582780287SAidan Dodds     uint64_t rs_id_u64 = 0U;
54682780287SAidan Dodds     uint64_t rs_data_u64 = 0U;
54782780287SAidan Dodds     uint64_t rs_length_u64 = 0U;
5484640cde1SColin Riley 
54982780287SAidan Dodds     bool success =
55082780287SAidan Dodds         GetArgSimple(context, 0, &rs_context_u64) &&
55182780287SAidan Dodds         GetArgSimple(context, 1, &rs_script_u64) &&
55282780287SAidan Dodds         GetArgSimple(context, 2, &rs_id_u64) &&
55382780287SAidan Dodds         GetArgSimple(context, 3, &rs_data_u64) &&
55482780287SAidan Dodds         GetArgSimple(context, 4, &rs_length_u64);
5554640cde1SColin Riley 
55682780287SAidan Dodds     if (!success)
55782780287SAidan Dodds     {
55882780287SAidan Dodds         if (log)
55982780287SAidan Dodds             log->Printf("RenderScriptRuntime::CaptureSetGlobalVar1 - Error while reading the function parameters");
56082780287SAidan Dodds         return;
56182780287SAidan Dodds     }
5624640cde1SColin Riley 
5634640cde1SColin Riley     if (log)
5644640cde1SColin Riley     {
5654640cde1SColin Riley         log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 ":%" PRIu64 "bytes.",
56682780287SAidan Dodds                         rs_context_u64, rs_script_u64, rs_id_u64, rs_data_u64, rs_length_u64);
5674640cde1SColin Riley 
56882780287SAidan Dodds         addr_t script_addr =  (addr_t)rs_script_u64;
5694640cde1SColin Riley         if (m_scriptMappings.find( script_addr ) != m_scriptMappings.end())
5704640cde1SColin Riley         {
5714640cde1SColin Riley             auto rsm = m_scriptMappings[script_addr];
57282780287SAidan Dodds             if (rs_id_u64 < rsm->m_globals.size())
5734640cde1SColin Riley             {
57482780287SAidan Dodds                 auto rsg = rsm->m_globals[rs_id_u64];
5754640cde1SColin Riley                 log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - Setting of '%s' within '%s' inferred", rsg.m_name.AsCString(),
5764640cde1SColin Riley                                 rsm->m_module->GetFileSpec().GetFilename().AsCString());
5774640cde1SColin Riley             }
5784640cde1SColin Riley         }
5794640cde1SColin Riley     }
5804640cde1SColin Riley }
5814640cde1SColin Riley 
5824640cde1SColin Riley void
5834640cde1SColin Riley RenderScriptRuntime::CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context)
5844640cde1SColin Riley {
5854640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
5864640cde1SColin Riley 
5874640cde1SColin Riley     //Context, Alloc, bool
5884640cde1SColin Riley 
58982780287SAidan Dodds     uint64_t rs_context_u64 = 0U;
59082780287SAidan Dodds     uint64_t rs_alloc_u64 = 0U;
59182780287SAidan Dodds     uint64_t rs_forceZero_u64 = 0U;
5924640cde1SColin Riley 
59382780287SAidan Dodds     bool success =
59482780287SAidan Dodds         GetArgSimple(context, 0, &rs_context_u64) &&
59582780287SAidan Dodds         GetArgSimple(context, 1, &rs_alloc_u64) &&
59682780287SAidan Dodds         GetArgSimple(context, 2, &rs_forceZero_u64);
59782780287SAidan Dodds     if (!success) // error case
59882780287SAidan Dodds     {
59982780287SAidan Dodds         if (log)
60082780287SAidan Dodds             log->Printf("RenderScriptRuntime::CaptureAllocationInit1 - Error while reading the function parameters");
60182780287SAidan Dodds         return; // abort
60282780287SAidan Dodds     }
6034640cde1SColin Riley 
6044640cde1SColin Riley     if (log)
6054640cde1SColin Riley         log->Printf ("RenderScriptRuntime::CaptureAllocationInit1 - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .",
60682780287SAidan Dodds                         rs_context_u64, rs_alloc_u64, rs_forceZero_u64);
607*78f339d1SEwan Crawford 
608*78f339d1SEwan Crawford     AllocationDetails* alloc = LookUpAllocation(rs_alloc_u64, true);
609*78f339d1SEwan Crawford     if (alloc)
610*78f339d1SEwan Crawford         alloc->context = rs_context_u64;
6114640cde1SColin Riley }
6124640cde1SColin Riley 
6134640cde1SColin Riley void
6144640cde1SColin Riley RenderScriptRuntime::CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context)
6154640cde1SColin Riley {
6164640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
6174640cde1SColin Riley 
6184640cde1SColin Riley     //Context, Script, resname Str, cachedir Str
6194640cde1SColin Riley     Error error;
6204640cde1SColin Riley     Process* process = context.GetProcessPtr();
6214640cde1SColin Riley 
62282780287SAidan Dodds     uint64_t rs_context_u64 = 0U;
62382780287SAidan Dodds     uint64_t rs_script_u64 = 0U;
62482780287SAidan Dodds     uint64_t rs_resnameptr_u64 = 0U;
62582780287SAidan Dodds     uint64_t rs_cachedirptr_u64 = 0U;
6264640cde1SColin Riley 
6274640cde1SColin Riley     std::string resname;
6284640cde1SColin Riley     std::string cachedir;
6294640cde1SColin Riley 
63082780287SAidan Dodds     // read the function parameters
63182780287SAidan Dodds     bool success =
63282780287SAidan Dodds         GetArgSimple(context, 0, &rs_context_u64) &&
63382780287SAidan Dodds         GetArgSimple(context, 1, &rs_script_u64) &&
63482780287SAidan Dodds         GetArgSimple(context, 2, &rs_resnameptr_u64) &&
63582780287SAidan Dodds         GetArgSimple(context, 3, &rs_cachedirptr_u64);
6364640cde1SColin Riley 
63782780287SAidan Dodds     if (!success)
63882780287SAidan Dodds     {
63982780287SAidan Dodds         if (log)
64082780287SAidan Dodds             log->Printf("RenderScriptRuntime::CaptureScriptInit1 - Error while reading the function parameters");
64182780287SAidan Dodds         return;
64282780287SAidan Dodds     }
64382780287SAidan Dodds 
64482780287SAidan Dodds     process->ReadCStringFromMemory((lldb::addr_t)rs_resnameptr_u64, resname, error);
6454640cde1SColin Riley     if (error.Fail())
6464640cde1SColin Riley     {
6474640cde1SColin Riley         if (log)
6484640cde1SColin Riley             log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading resname: %s.", error.AsCString());
6494640cde1SColin Riley 
6504640cde1SColin Riley     }
6514640cde1SColin Riley 
65282780287SAidan Dodds     process->ReadCStringFromMemory((lldb::addr_t)rs_cachedirptr_u64, cachedir, error);
6534640cde1SColin Riley     if (error.Fail())
6544640cde1SColin Riley     {
6554640cde1SColin Riley         if (log)
6564640cde1SColin Riley             log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading cachedir: %s.", error.AsCString());
6574640cde1SColin Riley     }
6584640cde1SColin Riley 
6594640cde1SColin Riley     if (log)
6604640cde1SColin Riley         log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .",
66182780287SAidan Dodds                      rs_context_u64, rs_script_u64, resname.c_str(), cachedir.c_str());
6624640cde1SColin Riley 
6634640cde1SColin Riley     if (resname.size() > 0)
6644640cde1SColin Riley     {
6654640cde1SColin Riley         StreamString strm;
6664640cde1SColin Riley         strm.Printf("librs.%s.so", resname.c_str());
6674640cde1SColin Riley 
668*78f339d1SEwan Crawford         ScriptDetails* script = LookUpScript(rs_script_u64, true);
669*78f339d1SEwan Crawford         if (script)
670*78f339d1SEwan Crawford         {
671*78f339d1SEwan Crawford             script->type = ScriptDetails::eScriptC;
672*78f339d1SEwan Crawford             script->cacheDir = cachedir;
673*78f339d1SEwan Crawford             script->resName = resname;
674*78f339d1SEwan Crawford             script->scriptDyLib = strm.GetData();
675*78f339d1SEwan Crawford             script->context = addr_t(rs_context_u64);
676*78f339d1SEwan Crawford         }
6774640cde1SColin Riley 
6784640cde1SColin Riley         if (log)
6794640cde1SColin Riley             log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - '%s' tagged with context 0x%" PRIx64 " and script 0x%" PRIx64 ".",
68082780287SAidan Dodds                          strm.GetData(), rs_context_u64, rs_script_u64);
6814640cde1SColin Riley     }
6824640cde1SColin Riley     else if (log)
6834640cde1SColin Riley     {
6844640cde1SColin Riley         log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - resource name invalid, Script not tagged");
6854640cde1SColin Riley     }
6864640cde1SColin Riley 
6874640cde1SColin Riley }
6884640cde1SColin Riley 
6894640cde1SColin Riley void
6904640cde1SColin Riley RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
6914640cde1SColin Riley {
6924640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
6934640cde1SColin Riley 
6944640cde1SColin Riley     if (!module)
6954640cde1SColin Riley     {
6964640cde1SColin Riley         return;
6974640cde1SColin Riley     }
6984640cde1SColin Riley 
69982780287SAidan Dodds     Target &target = GetProcess()->GetTarget();
70082780287SAidan Dodds     llvm::Triple::ArchType targetArchType = target.GetArchitecture().GetMachine();
70182780287SAidan Dodds 
70282780287SAidan Dodds     if (targetArchType != llvm::Triple::ArchType::x86
70382780287SAidan Dodds         && targetArchType != llvm::Triple::ArchType::arm
70482780287SAidan Dodds         && targetArchType != llvm::Triple::ArchType::aarch64)
7054640cde1SColin Riley     {
7064640cde1SColin Riley         if (log)
7074640cde1SColin Riley             log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to hook runtime. Only X86, ARM supported currently.");
7084640cde1SColin Riley 
7094640cde1SColin Riley         return;
7104640cde1SColin Riley     }
7114640cde1SColin Riley 
71282780287SAidan Dodds     uint32_t archByteSize = target.GetArchitecture().GetAddressByteSize();
7134640cde1SColin Riley 
7144640cde1SColin Riley     for (size_t idx = 0; idx < s_runtimeHookCount; idx++)
7154640cde1SColin Riley     {
7164640cde1SColin Riley         const HookDefn* hook_defn = &s_runtimeHookDefns[idx];
7174640cde1SColin Riley         if (hook_defn->kind != kind) {
7184640cde1SColin Riley             continue;
7194640cde1SColin Riley         }
7204640cde1SColin Riley 
72182780287SAidan Dodds         const char* symbol_name = (archByteSize == 4) ? hook_defn->symbol_name_m32 : hook_defn->symbol_name_m64;
72282780287SAidan Dodds 
72382780287SAidan Dodds         const Symbol *sym = module->FindFirstSymbolWithNameAndType(ConstString(symbol_name), eSymbolTypeCode);
72482780287SAidan Dodds         if (!sym){
72582780287SAidan Dodds             if (log){
72682780287SAidan Dodds                 log->Printf("RenderScriptRuntime::LoadRuntimeHooks - ERROR: Symbol '%s' related to the function %s not found", symbol_name, hook_defn->name);
72782780287SAidan Dodds             }
72882780287SAidan Dodds             continue;
72982780287SAidan Dodds         }
7304640cde1SColin Riley 
731358cf1eaSGreg Clayton         addr_t addr = sym->GetLoadAddress(&target);
7324640cde1SColin Riley         if (addr == LLDB_INVALID_ADDRESS)
7334640cde1SColin Riley         {
7344640cde1SColin Riley             if (log)
7354640cde1SColin Riley                 log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to resolve the address of hook function '%s' with symbol '%s'.",
73682780287SAidan Dodds                              hook_defn->name, symbol_name);
7374640cde1SColin Riley             continue;
7384640cde1SColin Riley         }
73982780287SAidan Dodds         else
74082780287SAidan Dodds         {
74182780287SAidan Dodds             if (log)
74282780287SAidan Dodds                 log->Printf("RenderScriptRuntime::LoadRuntimeHooks - Function %s, address resolved at 0x%" PRIx64, hook_defn->name, addr);
74382780287SAidan Dodds         }
7444640cde1SColin Riley 
7454640cde1SColin Riley         RuntimeHookSP hook(new RuntimeHook());
7464640cde1SColin Riley         hook->address = addr;
7474640cde1SColin Riley         hook->defn = hook_defn;
7484640cde1SColin Riley         hook->bp_sp = target.CreateBreakpoint(addr, true, false);
7494640cde1SColin Riley         hook->bp_sp->SetCallback(HookCallback, hook.get(), true);
7504640cde1SColin Riley         m_runtimeHooks[addr] = hook;
7514640cde1SColin Riley         if (log)
7524640cde1SColin Riley         {
7534640cde1SColin Riley             log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Successfully hooked '%s' in '%s' version %" PRIu64 " at 0x%" PRIx64 ".",
7544640cde1SColin Riley                 hook_defn->name, module->GetFileSpec().GetFilename().AsCString(), (uint64_t)hook_defn->version, (uint64_t)addr);
7554640cde1SColin Riley         }
7564640cde1SColin Riley     }
7574640cde1SColin Riley }
7584640cde1SColin Riley 
7594640cde1SColin Riley void
7604640cde1SColin Riley RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp)
7614640cde1SColin Riley {
7624640cde1SColin Riley     if (!rsmodule_sp)
7634640cde1SColin Riley         return;
7644640cde1SColin Riley 
7654640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
7664640cde1SColin Riley 
7674640cde1SColin Riley     const ModuleSP module = rsmodule_sp->m_module;
7684640cde1SColin Riley     const FileSpec& file = module->GetPlatformFileSpec();
7694640cde1SColin Riley 
770*78f339d1SEwan Crawford     // Iterate over all of the scripts that we currently know of.
771*78f339d1SEwan Crawford     // Note: We cant push or pop to m_scripts here or it may invalidate rs_script.
7724640cde1SColin Riley     for (const auto & rs_script : m_scripts)
7734640cde1SColin Riley     {
774*78f339d1SEwan Crawford         // Extract the expected .so file path for this script.
775*78f339d1SEwan Crawford         std::string dylib;
776*78f339d1SEwan Crawford         if (!rs_script->scriptDyLib.get(dylib))
777*78f339d1SEwan Crawford             continue;
778*78f339d1SEwan Crawford 
779*78f339d1SEwan Crawford         // Only proceed if the module that has loaded corresponds to this script.
780*78f339d1SEwan Crawford         if (file.GetFilename() != ConstString(dylib.c_str()))
781*78f339d1SEwan Crawford             continue;
782*78f339d1SEwan Crawford 
783*78f339d1SEwan Crawford         // Obtain the script address which we use as a key.
784*78f339d1SEwan Crawford         lldb::addr_t script;
785*78f339d1SEwan Crawford         if (!rs_script->script.get(script))
786*78f339d1SEwan Crawford             continue;
787*78f339d1SEwan Crawford 
788*78f339d1SEwan Crawford         // If we have a script mapping for the current script.
789*78f339d1SEwan Crawford         if (m_scriptMappings.find(script) != m_scriptMappings.end())
7904640cde1SColin Riley         {
791*78f339d1SEwan Crawford             // if the module we have stored is different to the one we just received.
792*78f339d1SEwan Crawford             if (m_scriptMappings[script] != rsmodule_sp)
7934640cde1SColin Riley             {
7944640cde1SColin Riley                 if (log)
7954640cde1SColin Riley                     log->Printf ("RenderScriptRuntime::FixupScriptDetails - Error: script %" PRIx64 " wants reassigned to new rsmodule '%s'.",
796*78f339d1SEwan Crawford                                     (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
7974640cde1SColin Riley             }
7984640cde1SColin Riley         }
799*78f339d1SEwan Crawford         // We don't have a script mapping for the current script.
8004640cde1SColin Riley         else
8014640cde1SColin Riley         {
802*78f339d1SEwan Crawford             // Obtain the script resource name.
803*78f339d1SEwan Crawford             std::string resName;
804*78f339d1SEwan Crawford             if (rs_script->resName.get(resName))
805*78f339d1SEwan Crawford                 // Set the modules resource name.
806*78f339d1SEwan Crawford                 rsmodule_sp->m_resname = resName;
807*78f339d1SEwan Crawford             // Add Script/Module pair to map.
808*78f339d1SEwan Crawford             m_scriptMappings[script] = rsmodule_sp;
8094640cde1SColin Riley             if (log)
8104640cde1SColin Riley                 log->Printf ("RenderScriptRuntime::FixupScriptDetails - script %" PRIx64 " associated with rsmodule '%s'.",
811*78f339d1SEwan Crawford                                 (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
8124640cde1SColin Riley         }
8134640cde1SColin Riley     }
8144640cde1SColin Riley }
8154640cde1SColin Riley 
8165ec532a9SColin Riley bool
8175ec532a9SColin Riley RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
8185ec532a9SColin Riley {
8194640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
8204640cde1SColin Riley 
8215ec532a9SColin Riley     if (module_sp)
8225ec532a9SColin Riley     {
8235ec532a9SColin Riley         for (const auto &rs_module : m_rsmodules)
8245ec532a9SColin Riley         {
8254640cde1SColin Riley             if (rs_module->m_module == module_sp)
8267dc7771cSEwan Crawford             {
8277dc7771cSEwan Crawford                 // Check if the user has enabled automatically breaking on
8287dc7771cSEwan Crawford                 // all RS kernels.
8297dc7771cSEwan Crawford                 if (m_breakAllKernels)
8307dc7771cSEwan Crawford                     BreakOnModuleKernels(rs_module);
8317dc7771cSEwan Crawford 
8325ec532a9SColin Riley                 return false;
8335ec532a9SColin Riley             }
8347dc7771cSEwan Crawford         }
835ef20b08fSColin Riley         bool module_loaded = false;
836ef20b08fSColin Riley         switch (GetModuleKind(module_sp))
837ef20b08fSColin Riley         {
838ef20b08fSColin Riley             case eModuleKindKernelObj:
839ef20b08fSColin Riley             {
8404640cde1SColin Riley                 RSModuleDescriptorSP module_desc;
8414640cde1SColin Riley                 module_desc.reset(new RSModuleDescriptor(module_sp));
8424640cde1SColin Riley                 if (module_desc->ParseRSInfo())
8435ec532a9SColin Riley                 {
8445ec532a9SColin Riley                     m_rsmodules.push_back(module_desc);
845ef20b08fSColin Riley                     module_loaded = true;
8465ec532a9SColin Riley                 }
8474640cde1SColin Riley                 if (module_loaded)
8484640cde1SColin Riley                 {
8494640cde1SColin Riley                     FixupScriptDetails(module_desc);
8504640cde1SColin Riley                 }
851ef20b08fSColin Riley                 break;
852ef20b08fSColin Riley             }
853ef20b08fSColin Riley             case eModuleKindDriver:
8544640cde1SColin Riley             {
8554640cde1SColin Riley                 if (!m_libRSDriver)
8564640cde1SColin Riley                 {
8574640cde1SColin Riley                     m_libRSDriver = module_sp;
8584640cde1SColin Riley                     LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver);
8594640cde1SColin Riley                 }
8604640cde1SColin Riley                 break;
8614640cde1SColin Riley             }
862ef20b08fSColin Riley             case eModuleKindImpl:
8634640cde1SColin Riley             {
8644640cde1SColin Riley                 m_libRSCpuRef = module_sp;
8654640cde1SColin Riley                 break;
8664640cde1SColin Riley             }
867ef20b08fSColin Riley             case eModuleKindLibRS:
8684640cde1SColin Riley             {
8694640cde1SColin Riley                 if (!m_libRS)
8704640cde1SColin Riley                 {
8714640cde1SColin Riley                     m_libRS = module_sp;
8724640cde1SColin Riley                     static ConstString gDbgPresentStr("gDebuggerPresent");
8734640cde1SColin Riley                     const Symbol* debug_present = m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData);
8744640cde1SColin Riley                     if (debug_present)
8754640cde1SColin Riley                     {
8764640cde1SColin Riley                         Error error;
8774640cde1SColin Riley                         uint32_t flag = 0x00000001U;
8784640cde1SColin Riley                         Target &target = GetProcess()->GetTarget();
879358cf1eaSGreg Clayton                         addr_t addr = debug_present->GetLoadAddress(&target);
8804640cde1SColin Riley                         GetProcess()->WriteMemory(addr, &flag, sizeof(flag), error);
8814640cde1SColin Riley                         if(error.Success())
8824640cde1SColin Riley                         {
8834640cde1SColin Riley                             if (log)
8844640cde1SColin Riley                                 log->Printf ("RenderScriptRuntime::LoadModule - Debugger present flag set on debugee");
8854640cde1SColin Riley 
8864640cde1SColin Riley                             m_debuggerPresentFlagged = true;
8874640cde1SColin Riley                         }
8884640cde1SColin Riley                         else if (log)
8894640cde1SColin Riley                         {
8904640cde1SColin Riley                             log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags '%s' ", error.AsCString());
8914640cde1SColin Riley                         }
8924640cde1SColin Riley                     }
8934640cde1SColin Riley                     else if (log)
8944640cde1SColin Riley                     {
8954640cde1SColin Riley                         log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags - symbol not found");
8964640cde1SColin Riley                     }
8974640cde1SColin Riley                 }
8984640cde1SColin Riley                 break;
8994640cde1SColin Riley             }
900ef20b08fSColin Riley             default:
901ef20b08fSColin Riley                 break;
902ef20b08fSColin Riley         }
903ef20b08fSColin Riley         if (module_loaded)
904ef20b08fSColin Riley             Update();
905ef20b08fSColin Riley         return module_loaded;
9065ec532a9SColin Riley     }
9075ec532a9SColin Riley     return false;
9085ec532a9SColin Riley }
9095ec532a9SColin Riley 
910ef20b08fSColin Riley void
911ef20b08fSColin Riley RenderScriptRuntime::Update()
912ef20b08fSColin Riley {
913ef20b08fSColin Riley     if (m_rsmodules.size() > 0)
914ef20b08fSColin Riley     {
915ef20b08fSColin Riley         if (!m_initiated)
916ef20b08fSColin Riley         {
917ef20b08fSColin Riley             Initiate();
918ef20b08fSColin Riley         }
919ef20b08fSColin Riley     }
920ef20b08fSColin Riley }
921ef20b08fSColin Riley 
922ef20b08fSColin Riley 
9235ec532a9SColin Riley // The maximum line length of an .rs.info packet
9245ec532a9SColin Riley #define MAXLINE 500
9255ec532a9SColin Riley 
9265ec532a9SColin Riley // The .rs.info symbol in renderscript modules contains a string which needs to be parsed.
9275ec532a9SColin Riley // The string is basic and is parsed on a line by line basis.
9285ec532a9SColin Riley bool
9295ec532a9SColin Riley RSModuleDescriptor::ParseRSInfo()
9305ec532a9SColin Riley {
9315ec532a9SColin Riley     const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
9325ec532a9SColin Riley     if (info_sym)
9335ec532a9SColin Riley     {
934358cf1eaSGreg Clayton         const addr_t addr = info_sym->GetAddressRef().GetFileAddress();
9355ec532a9SColin Riley         const addr_t size = info_sym->GetByteSize();
9365ec532a9SColin Riley         const FileSpec fs = m_module->GetFileSpec();
9375ec532a9SColin Riley 
9385ec532a9SColin Riley         DataBufferSP buffer = fs.ReadFileContents(addr, size);
9395ec532a9SColin Riley 
9405ec532a9SColin Riley         if (!buffer)
9415ec532a9SColin Riley             return false;
9425ec532a9SColin Riley 
9435ec532a9SColin Riley         std::string info((const char *)buffer->GetBytes());
9445ec532a9SColin Riley 
9455ec532a9SColin Riley         std::vector<std::string> info_lines;
946e8433cc1SBruce Mitchener         size_t lpos = info.find('\n');
9475ec532a9SColin Riley         while (lpos != std::string::npos)
9485ec532a9SColin Riley         {
9495ec532a9SColin Riley             info_lines.push_back(info.substr(0, lpos));
9505ec532a9SColin Riley             info = info.substr(lpos + 1);
951e8433cc1SBruce Mitchener             lpos = info.find('\n');
9525ec532a9SColin Riley         }
9535ec532a9SColin Riley         size_t offset = 0;
9545ec532a9SColin Riley         while (offset < info_lines.size())
9555ec532a9SColin Riley         {
9565ec532a9SColin Riley             std::string line = info_lines[offset];
9575ec532a9SColin Riley             // Parse directives
9585ec532a9SColin Riley             uint32_t numDefns = 0;
9595ec532a9SColin Riley             if (sscanf(line.c_str(), "exportVarCount: %u", &numDefns) == 1)
9605ec532a9SColin Riley             {
9615ec532a9SColin Riley                 while (numDefns--)
9624640cde1SColin Riley                     m_globals.push_back(RSGlobalDescriptor(this, info_lines[++offset].c_str()));
9635ec532a9SColin Riley             }
9645ec532a9SColin Riley             else if (sscanf(line.c_str(), "exportFuncCount: %u", &numDefns) == 1)
9655ec532a9SColin Riley             {
9665ec532a9SColin Riley             }
9675ec532a9SColin Riley             else if (sscanf(line.c_str(), "exportForEachCount: %u", &numDefns) == 1)
9685ec532a9SColin Riley             {
9695ec532a9SColin Riley                 char name[MAXLINE];
9705ec532a9SColin Riley                 while (numDefns--)
9715ec532a9SColin Riley                 {
9725ec532a9SColin Riley                     uint32_t slot = 0;
9735ec532a9SColin Riley                     name[0] = '\0';
9745ec532a9SColin Riley                     if (sscanf(info_lines[++offset].c_str(), "%u - %s", &slot, &name[0]) == 2)
9755ec532a9SColin Riley                     {
9764640cde1SColin Riley                         m_kernels.push_back(RSKernelDescriptor(this, name, slot));
9774640cde1SColin Riley                     }
9784640cde1SColin Riley                 }
9794640cde1SColin Riley             }
9804640cde1SColin Riley             else if (sscanf(line.c_str(), "pragmaCount: %u", &numDefns) == 1)
9814640cde1SColin Riley             {
9824640cde1SColin Riley                 char name[MAXLINE];
9834640cde1SColin Riley                 char value[MAXLINE];
9844640cde1SColin Riley                 while (numDefns--)
9854640cde1SColin Riley                 {
9864640cde1SColin Riley                     name[0] = '\0';
9874640cde1SColin Riley                     value[0] = '\0';
9884640cde1SColin Riley                     if (sscanf(info_lines[++offset].c_str(), "%s - %s", &name[0], &value[0]) != 0
9894640cde1SColin Riley                         && (name[0] != '\0'))
9904640cde1SColin Riley                     {
9914640cde1SColin Riley                         m_pragmas[std::string(name)] = value;
9925ec532a9SColin Riley                     }
9935ec532a9SColin Riley                 }
9945ec532a9SColin Riley             }
9955ec532a9SColin Riley             else if (sscanf(line.c_str(), "objectSlotCount: %u", &numDefns) == 1)
9965ec532a9SColin Riley             {
9975ec532a9SColin Riley             }
9985ec532a9SColin Riley 
9995ec532a9SColin Riley             offset++;
10005ec532a9SColin Riley         }
10015ec532a9SColin Riley         return m_kernels.size() > 0;
10025ec532a9SColin Riley     }
10035ec532a9SColin Riley     return false;
10045ec532a9SColin Riley }
10055ec532a9SColin Riley 
10065ec532a9SColin Riley bool
10075ec532a9SColin Riley RenderScriptRuntime::ProbeModules(const ModuleList module_list)
10085ec532a9SColin Riley {
10095ec532a9SColin Riley     bool rs_found = false;
10105ec532a9SColin Riley     size_t num_modules = module_list.GetSize();
10115ec532a9SColin Riley     for (size_t i = 0; i < num_modules; i++)
10125ec532a9SColin Riley     {
10135ec532a9SColin Riley         auto module = module_list.GetModuleAtIndex(i);
10145ec532a9SColin Riley         rs_found |= LoadModule(module);
10155ec532a9SColin Riley     }
10165ec532a9SColin Riley     return rs_found;
10175ec532a9SColin Riley }
10185ec532a9SColin Riley 
10195ec532a9SColin Riley void
10204640cde1SColin Riley RenderScriptRuntime::Status(Stream &strm) const
10214640cde1SColin Riley {
10224640cde1SColin Riley     if (m_libRS)
10234640cde1SColin Riley     {
10244640cde1SColin Riley         strm.Printf("Runtime Library discovered.");
10254640cde1SColin Riley         strm.EOL();
10264640cde1SColin Riley     }
10274640cde1SColin Riley     if (m_libRSDriver)
10284640cde1SColin Riley     {
10294640cde1SColin Riley         strm.Printf("Runtime Driver discovered.");
10304640cde1SColin Riley         strm.EOL();
10314640cde1SColin Riley     }
10324640cde1SColin Riley     if (m_libRSCpuRef)
10334640cde1SColin Riley     {
10344640cde1SColin Riley         strm.Printf("CPU Reference Implementation discovered.");
10354640cde1SColin Riley         strm.EOL();
10364640cde1SColin Riley     }
10374640cde1SColin Riley 
10384640cde1SColin Riley     if (m_runtimeHooks.size())
10394640cde1SColin Riley     {
10404640cde1SColin Riley         strm.Printf("Runtime functions hooked:");
10414640cde1SColin Riley         strm.EOL();
10424640cde1SColin Riley         for (auto b : m_runtimeHooks)
10434640cde1SColin Riley         {
10444640cde1SColin Riley             strm.Indent(b.second->defn->name);
10454640cde1SColin Riley             strm.EOL();
10464640cde1SColin Riley         }
10474640cde1SColin Riley         strm.EOL();
10484640cde1SColin Riley     }
10494640cde1SColin Riley     else
10504640cde1SColin Riley     {
10514640cde1SColin Riley         strm.Printf("Runtime is not hooked.");
10524640cde1SColin Riley         strm.EOL();
10534640cde1SColin Riley     }
10544640cde1SColin Riley }
10554640cde1SColin Riley 
10564640cde1SColin Riley void
10574640cde1SColin Riley RenderScriptRuntime::DumpContexts(Stream &strm) const
10584640cde1SColin Riley {
10594640cde1SColin Riley     strm.Printf("Inferred RenderScript Contexts:");
10604640cde1SColin Riley     strm.EOL();
10614640cde1SColin Riley     strm.IndentMore();
10624640cde1SColin Riley 
10634640cde1SColin Riley     std::map<addr_t, uint64_t> contextReferences;
10644640cde1SColin Riley 
1065*78f339d1SEwan Crawford     // Iterate over all of the currently discovered scripts.
1066*78f339d1SEwan Crawford     // Note: We cant push or pop from m_scripts inside this loop or it may invalidate script.
10674640cde1SColin Riley     for (const auto & script : m_scripts)
10684640cde1SColin Riley     {
1069*78f339d1SEwan Crawford         if (!script->context.isValid())
1070*78f339d1SEwan Crawford             continue;
1071*78f339d1SEwan Crawford         lldb::addr_t context = *script->context;
1072*78f339d1SEwan Crawford 
1073*78f339d1SEwan Crawford         if (contextReferences.find(context) != contextReferences.end())
10744640cde1SColin Riley         {
1075*78f339d1SEwan Crawford             contextReferences[context]++;
10764640cde1SColin Riley         }
10774640cde1SColin Riley         else
10784640cde1SColin Riley         {
1079*78f339d1SEwan Crawford             contextReferences[context] = 1;
10804640cde1SColin Riley         }
10814640cde1SColin Riley     }
10824640cde1SColin Riley 
10834640cde1SColin Riley     for (const auto& cRef : contextReferences)
10844640cde1SColin Riley     {
10854640cde1SColin Riley         strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances", cRef.first, cRef.second);
10864640cde1SColin Riley         strm.EOL();
10874640cde1SColin Riley     }
10884640cde1SColin Riley     strm.IndentLess();
10894640cde1SColin Riley }
10904640cde1SColin Riley 
10914640cde1SColin Riley void
10924640cde1SColin Riley RenderScriptRuntime::DumpKernels(Stream &strm) const
10934640cde1SColin Riley {
10944640cde1SColin Riley     strm.Printf("RenderScript Kernels:");
10954640cde1SColin Riley     strm.EOL();
10964640cde1SColin Riley     strm.IndentMore();
10974640cde1SColin Riley     for (const auto &module : m_rsmodules)
10984640cde1SColin Riley     {
10994640cde1SColin Riley         strm.Printf("Resource '%s':",module->m_resname.c_str());
11004640cde1SColin Riley         strm.EOL();
11014640cde1SColin Riley         for (const auto &kernel : module->m_kernels)
11024640cde1SColin Riley         {
11034640cde1SColin Riley             strm.Indent(kernel.m_name.AsCString());
11044640cde1SColin Riley             strm.EOL();
11054640cde1SColin Riley         }
11064640cde1SColin Riley     }
11074640cde1SColin Riley     strm.IndentLess();
11084640cde1SColin Riley }
11094640cde1SColin Riley 
11107dc7771cSEwan Crawford // Set breakpoints on every kernel found in RS module
11117dc7771cSEwan Crawford void
11127dc7771cSEwan Crawford RenderScriptRuntime::BreakOnModuleKernels(const RSModuleDescriptorSP rsmodule_sp)
11137dc7771cSEwan Crawford {
11147dc7771cSEwan Crawford     for (const auto &kernel : rsmodule_sp->m_kernels)
11157dc7771cSEwan Crawford     {
11167dc7771cSEwan Crawford         // Don't set breakpoint on 'root' kernel
11177dc7771cSEwan Crawford         if (strcmp(kernel.m_name.AsCString(), "root") == 0)
11187dc7771cSEwan Crawford             continue;
11197dc7771cSEwan Crawford 
11207dc7771cSEwan Crawford         CreateKernelBreakpoint(kernel.m_name);
11217dc7771cSEwan Crawford     }
11227dc7771cSEwan Crawford }
11237dc7771cSEwan Crawford 
11247dc7771cSEwan Crawford // Method is internally called by the 'kernel breakpoint all' command to
11257dc7771cSEwan Crawford // enable or disable breaking on all kernels.
11267dc7771cSEwan Crawford //
11277dc7771cSEwan Crawford // When do_break is true we want to enable this functionality.
11287dc7771cSEwan Crawford // When do_break is false we want to disable it.
11297dc7771cSEwan Crawford void
11307dc7771cSEwan Crawford RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target)
11317dc7771cSEwan Crawford {
113254782db7SEwan Crawford     Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
11337dc7771cSEwan Crawford 
11347dc7771cSEwan Crawford     InitSearchFilter(target);
11357dc7771cSEwan Crawford 
11367dc7771cSEwan Crawford     // Set breakpoints on all the kernels
11377dc7771cSEwan Crawford     if (do_break && !m_breakAllKernels)
11387dc7771cSEwan Crawford     {
11397dc7771cSEwan Crawford         m_breakAllKernels = true;
11407dc7771cSEwan Crawford 
11417dc7771cSEwan Crawford         for (const auto &module : m_rsmodules)
11427dc7771cSEwan Crawford             BreakOnModuleKernels(module);
11437dc7771cSEwan Crawford 
11447dc7771cSEwan Crawford         if (log)
11457dc7771cSEwan Crawford             log->Printf("RenderScriptRuntime::SetBreakAllKernels(True)"
11467dc7771cSEwan Crawford                         "- breakpoints set on all currently loaded kernels");
11477dc7771cSEwan Crawford     }
11487dc7771cSEwan Crawford     else if (!do_break && m_breakAllKernels) // Breakpoints won't be set on any new kernels.
11497dc7771cSEwan Crawford     {
11507dc7771cSEwan Crawford         m_breakAllKernels = false;
11517dc7771cSEwan Crawford 
11527dc7771cSEwan Crawford         if (log)
11537dc7771cSEwan Crawford             log->Printf("RenderScriptRuntime::SetBreakAllKernels(False) - breakpoints no longer automatically set");
11547dc7771cSEwan Crawford     }
11557dc7771cSEwan Crawford }
11567dc7771cSEwan Crawford 
11577dc7771cSEwan Crawford // Given the name of a kernel this function creates a breakpoint using our
11587dc7771cSEwan Crawford // own breakpoint resolver, and returns the Breakpoint shared pointer.
11597dc7771cSEwan Crawford BreakpointSP
11607dc7771cSEwan Crawford RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name)
11617dc7771cSEwan Crawford {
116254782db7SEwan Crawford     Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
11637dc7771cSEwan Crawford 
11647dc7771cSEwan Crawford     if (!m_filtersp)
11657dc7771cSEwan Crawford     {
11667dc7771cSEwan Crawford         if (log)
11677dc7771cSEwan Crawford             log->Printf("RenderScriptRuntime::CreateKernelBreakpoint - Error: No breakpoint search filter set");
11687dc7771cSEwan Crawford         return nullptr;
11697dc7771cSEwan Crawford     }
11707dc7771cSEwan Crawford 
11717dc7771cSEwan Crawford     BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name));
11727dc7771cSEwan Crawford     BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(m_filtersp, resolver_sp, false, false, false);
11737dc7771cSEwan Crawford 
117454782db7SEwan Crawford     // Give RS breakpoints a specific name, so the user can manipulate them as a group.
117554782db7SEwan Crawford     Error err;
117654782db7SEwan Crawford     if (!bp->AddName("RenderScriptKernel", err) && log)
117754782db7SEwan Crawford         log->Printf("RenderScriptRuntime::CreateKernelBreakpoint: Error setting break name, %s", err.AsCString());
117854782db7SEwan Crawford 
11797dc7771cSEwan Crawford     return bp;
11807dc7771cSEwan Crawford }
11817dc7771cSEwan Crawford 
11824640cde1SColin Riley void
118398156583SEwan Crawford RenderScriptRuntime::AttemptBreakpointAtKernelName(Stream &strm, const char* name, Error& error, TargetSP target)
11844640cde1SColin Riley {
11854640cde1SColin Riley     if (!name)
11864640cde1SColin Riley     {
11874640cde1SColin Riley         error.SetErrorString("invalid kernel name");
11884640cde1SColin Riley         return;
11894640cde1SColin Riley     }
11904640cde1SColin Riley 
11917dc7771cSEwan Crawford     InitSearchFilter(target);
119298156583SEwan Crawford 
11934640cde1SColin Riley     ConstString kernel_name(name);
11947dc7771cSEwan Crawford     BreakpointSP bp = CreateKernelBreakpoint(kernel_name);
119598156583SEwan Crawford     if (bp)
119698156583SEwan Crawford         bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false);
11974640cde1SColin Riley 
11984640cde1SColin Riley     return;
11994640cde1SColin Riley }
12004640cde1SColin Riley 
12014640cde1SColin Riley void
12025ec532a9SColin Riley RenderScriptRuntime::DumpModules(Stream &strm) const
12035ec532a9SColin Riley {
12045ec532a9SColin Riley     strm.Printf("RenderScript Modules:");
12055ec532a9SColin Riley     strm.EOL();
12065ec532a9SColin Riley     strm.IndentMore();
12075ec532a9SColin Riley     for (const auto &module : m_rsmodules)
12085ec532a9SColin Riley     {
12094640cde1SColin Riley         module->Dump(strm);
12105ec532a9SColin Riley     }
12115ec532a9SColin Riley     strm.IndentLess();
12125ec532a9SColin Riley }
12135ec532a9SColin Riley 
1214*78f339d1SEwan Crawford RenderScriptRuntime::ScriptDetails*
1215*78f339d1SEwan Crawford RenderScriptRuntime::LookUpScript(addr_t address, bool create)
1216*78f339d1SEwan Crawford {
1217*78f339d1SEwan Crawford     for (const auto & s : m_scripts)
1218*78f339d1SEwan Crawford     {
1219*78f339d1SEwan Crawford         if (s->script.isValid())
1220*78f339d1SEwan Crawford             if (*s->script == address)
1221*78f339d1SEwan Crawford                 return s.get();
1222*78f339d1SEwan Crawford     }
1223*78f339d1SEwan Crawford     if (create)
1224*78f339d1SEwan Crawford     {
1225*78f339d1SEwan Crawford         std::unique_ptr<ScriptDetails> s(new ScriptDetails);
1226*78f339d1SEwan Crawford         s->script = address;
1227*78f339d1SEwan Crawford         m_scripts.push_back(std::move(s));
1228*78f339d1SEwan Crawford         return s.get();
1229*78f339d1SEwan Crawford     }
1230*78f339d1SEwan Crawford     return nullptr;
1231*78f339d1SEwan Crawford }
1232*78f339d1SEwan Crawford 
1233*78f339d1SEwan Crawford RenderScriptRuntime::AllocationDetails*
1234*78f339d1SEwan Crawford RenderScriptRuntime::LookUpAllocation(addr_t address, bool create)
1235*78f339d1SEwan Crawford {
1236*78f339d1SEwan Crawford     for (const auto & a : m_allocations)
1237*78f339d1SEwan Crawford     {
1238*78f339d1SEwan Crawford         if (a->address.isValid())
1239*78f339d1SEwan Crawford             if (*a->address == address)
1240*78f339d1SEwan Crawford                 return a.get();
1241*78f339d1SEwan Crawford     }
1242*78f339d1SEwan Crawford     if (create)
1243*78f339d1SEwan Crawford     {
1244*78f339d1SEwan Crawford         std::unique_ptr<AllocationDetails> a(new AllocationDetails);
1245*78f339d1SEwan Crawford         a->address = address;
1246*78f339d1SEwan Crawford         m_allocations.push_back(std::move(a));
1247*78f339d1SEwan Crawford         return a.get();
1248*78f339d1SEwan Crawford     }
1249*78f339d1SEwan Crawford     return nullptr;
1250*78f339d1SEwan Crawford }
1251*78f339d1SEwan Crawford 
12525ec532a9SColin Riley void
12535ec532a9SColin Riley RSModuleDescriptor::Dump(Stream &strm) const
12545ec532a9SColin Riley {
12555ec532a9SColin Riley     strm.Indent();
12565ec532a9SColin Riley     m_module->GetFileSpec().Dump(&strm);
12574640cde1SColin Riley     m_module->ParseAllDebugSymbols();
12584640cde1SColin Riley     if(m_module->GetNumCompileUnits())
12594640cde1SColin Riley     {
12604640cde1SColin Riley         strm.Indent("Debug info loaded.");
12614640cde1SColin Riley     }
12624640cde1SColin Riley     else
12634640cde1SColin Riley     {
12644640cde1SColin Riley         strm.Indent("Debug info does not exist.");
12654640cde1SColin Riley     }
12665ec532a9SColin Riley     strm.EOL();
12675ec532a9SColin Riley     strm.IndentMore();
12685ec532a9SColin Riley     strm.Indent();
1269189598edSColin Riley     strm.Printf("Globals: %" PRIu64, static_cast<uint64_t>(m_globals.size()));
12705ec532a9SColin Riley     strm.EOL();
12715ec532a9SColin Riley     strm.IndentMore();
12725ec532a9SColin Riley     for (const auto &global : m_globals)
12735ec532a9SColin Riley     {
12745ec532a9SColin Riley         global.Dump(strm);
12755ec532a9SColin Riley     }
12765ec532a9SColin Riley     strm.IndentLess();
12775ec532a9SColin Riley     strm.Indent();
1278189598edSColin Riley     strm.Printf("Kernels: %" PRIu64, static_cast<uint64_t>(m_kernels.size()));
12795ec532a9SColin Riley     strm.EOL();
12805ec532a9SColin Riley     strm.IndentMore();
12815ec532a9SColin Riley     for (const auto &kernel : m_kernels)
12825ec532a9SColin Riley     {
12835ec532a9SColin Riley         kernel.Dump(strm);
12845ec532a9SColin Riley     }
12854640cde1SColin Riley     strm.Printf("Pragmas: %"  PRIu64 , static_cast<uint64_t>(m_pragmas.size()));
12864640cde1SColin Riley     strm.EOL();
12874640cde1SColin Riley     strm.IndentMore();
12884640cde1SColin Riley     for (const auto &key_val : m_pragmas)
12894640cde1SColin Riley     {
12904640cde1SColin Riley         strm.Printf("%s: %s", key_val.first.c_str(), key_val.second.c_str());
12914640cde1SColin Riley         strm.EOL();
12924640cde1SColin Riley     }
12935ec532a9SColin Riley     strm.IndentLess(4);
12945ec532a9SColin Riley }
12955ec532a9SColin Riley 
12965ec532a9SColin Riley void
12975ec532a9SColin Riley RSGlobalDescriptor::Dump(Stream &strm) const
12985ec532a9SColin Riley {
12995ec532a9SColin Riley     strm.Indent(m_name.AsCString());
13004640cde1SColin Riley     VariableList var_list;
13014640cde1SColin Riley     m_module->m_module->FindGlobalVariables(m_name, nullptr, true, 1U, var_list);
13024640cde1SColin Riley     if (var_list.GetSize() == 1)
13034640cde1SColin Riley     {
13044640cde1SColin Riley         auto var = var_list.GetVariableAtIndex(0);
13054640cde1SColin Riley         auto type = var->GetType();
13064640cde1SColin Riley         if(type)
13074640cde1SColin Riley         {
13084640cde1SColin Riley             strm.Printf(" - ");
13094640cde1SColin Riley             type->DumpTypeName(&strm);
13104640cde1SColin Riley         }
13114640cde1SColin Riley         else
13124640cde1SColin Riley         {
13134640cde1SColin Riley             strm.Printf(" - Unknown Type");
13144640cde1SColin Riley         }
13154640cde1SColin Riley     }
13164640cde1SColin Riley     else
13174640cde1SColin Riley     {
13184640cde1SColin Riley         strm.Printf(" - variable identified, but not found in binary");
13194640cde1SColin Riley         const Symbol* s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData);
13204640cde1SColin Riley         if (s)
13214640cde1SColin Riley         {
13224640cde1SColin Riley             strm.Printf(" (symbol exists) ");
13234640cde1SColin Riley         }
13244640cde1SColin Riley     }
13254640cde1SColin Riley 
13265ec532a9SColin Riley     strm.EOL();
13275ec532a9SColin Riley }
13285ec532a9SColin Riley 
13295ec532a9SColin Riley void
13305ec532a9SColin Riley RSKernelDescriptor::Dump(Stream &strm) const
13315ec532a9SColin Riley {
13325ec532a9SColin Riley     strm.Indent(m_name.AsCString());
13335ec532a9SColin Riley     strm.EOL();
13345ec532a9SColin Riley }
13355ec532a9SColin Riley 
13365ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed
13375ec532a9SColin Riley {
13385ec532a9SColin Riley   private:
13395ec532a9SColin Riley   public:
13405ec532a9SColin Riley     CommandObjectRenderScriptRuntimeModuleProbe(CommandInterpreter &interpreter)
13415ec532a9SColin Riley         : CommandObjectParsed(interpreter, "renderscript module probe",
13425ec532a9SColin Riley                               "Initiates a Probe of all loaded modules for kernels and other renderscript objects.",
13435ec532a9SColin Riley                               "renderscript module probe",
1344e87764f2SEnrico Granata                               eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBeLaunched)
13455ec532a9SColin Riley     {
13465ec532a9SColin Riley     }
13475ec532a9SColin Riley 
13485ec532a9SColin Riley     ~CommandObjectRenderScriptRuntimeModuleProbe() {}
13495ec532a9SColin Riley 
13505ec532a9SColin Riley     bool
13515ec532a9SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
13525ec532a9SColin Riley     {
13535ec532a9SColin Riley         const size_t argc = command.GetArgumentCount();
13545ec532a9SColin Riley         if (argc == 0)
13555ec532a9SColin Riley         {
13565ec532a9SColin Riley             Target *target = m_exe_ctx.GetTargetPtr();
13575ec532a9SColin Riley             RenderScriptRuntime *runtime =
13585ec532a9SColin Riley                 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
13595ec532a9SColin Riley             auto module_list = target->GetImages();
13605ec532a9SColin Riley             bool new_rs_details = runtime->ProbeModules(module_list);
13615ec532a9SColin Riley             if (new_rs_details)
13625ec532a9SColin Riley             {
13635ec532a9SColin Riley                 result.AppendMessage("New renderscript modules added to runtime model.");
13645ec532a9SColin Riley             }
13655ec532a9SColin Riley             result.SetStatus(eReturnStatusSuccessFinishResult);
13665ec532a9SColin Riley             return true;
13675ec532a9SColin Riley         }
13685ec532a9SColin Riley 
13695ec532a9SColin Riley         result.AppendErrorWithFormat("'%s' takes no arguments", m_cmd_name.c_str());
13705ec532a9SColin Riley         result.SetStatus(eReturnStatusFailed);
13715ec532a9SColin Riley         return false;
13725ec532a9SColin Riley     }
13735ec532a9SColin Riley };
13745ec532a9SColin Riley 
13755ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed
13765ec532a9SColin Riley {
13775ec532a9SColin Riley   private:
13785ec532a9SColin Riley   public:
13795ec532a9SColin Riley     CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter)
13805ec532a9SColin Riley         : CommandObjectParsed(interpreter, "renderscript module dump",
13815ec532a9SColin Riley                               "Dumps renderscript specific information for all modules.", "renderscript module dump",
1382e87764f2SEnrico Granata                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
13835ec532a9SColin Riley     {
13845ec532a9SColin Riley     }
13855ec532a9SColin Riley 
13865ec532a9SColin Riley     ~CommandObjectRenderScriptRuntimeModuleDump() {}
13875ec532a9SColin Riley 
13885ec532a9SColin Riley     bool
13895ec532a9SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
13905ec532a9SColin Riley     {
13915ec532a9SColin Riley         RenderScriptRuntime *runtime =
13925ec532a9SColin Riley             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
13935ec532a9SColin Riley         runtime->DumpModules(result.GetOutputStream());
13945ec532a9SColin Riley         result.SetStatus(eReturnStatusSuccessFinishResult);
13955ec532a9SColin Riley         return true;
13965ec532a9SColin Riley     }
13975ec532a9SColin Riley };
13985ec532a9SColin Riley 
13995ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword
14005ec532a9SColin Riley {
14015ec532a9SColin Riley   private:
14025ec532a9SColin Riley   public:
14035ec532a9SColin Riley     CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter)
14045ec532a9SColin Riley         : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with renderscript modules.",
14055ec532a9SColin Riley                                  NULL)
14065ec532a9SColin Riley     {
14075ec532a9SColin Riley         LoadSubCommand("probe", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleProbe(interpreter)));
14085ec532a9SColin Riley         LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter)));
14095ec532a9SColin Riley     }
14105ec532a9SColin Riley 
14115ec532a9SColin Riley     ~CommandObjectRenderScriptRuntimeModule() {}
14125ec532a9SColin Riley };
14135ec532a9SColin Riley 
14144640cde1SColin Riley class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed
14154640cde1SColin Riley {
14164640cde1SColin Riley   private:
14174640cde1SColin Riley   public:
14184640cde1SColin Riley     CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter)
14194640cde1SColin Riley         : CommandObjectParsed(interpreter, "renderscript kernel list",
14204640cde1SColin Riley                               "Lists renderscript kernel names and associated script resources.", "renderscript kernel list",
14214640cde1SColin Riley                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
14224640cde1SColin Riley     {
14234640cde1SColin Riley     }
14244640cde1SColin Riley 
14254640cde1SColin Riley     ~CommandObjectRenderScriptRuntimeKernelList() {}
14264640cde1SColin Riley 
14274640cde1SColin Riley     bool
14284640cde1SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
14294640cde1SColin Riley     {
14304640cde1SColin Riley         RenderScriptRuntime *runtime =
14314640cde1SColin Riley             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
14324640cde1SColin Riley         runtime->DumpKernels(result.GetOutputStream());
14334640cde1SColin Riley         result.SetStatus(eReturnStatusSuccessFinishResult);
14344640cde1SColin Riley         return true;
14354640cde1SColin Riley     }
14364640cde1SColin Riley };
14374640cde1SColin Riley 
14387dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpointSet : public CommandObjectParsed
14394640cde1SColin Riley {
14404640cde1SColin Riley   private:
14414640cde1SColin Riley   public:
14427dc7771cSEwan Crawford     CommandObjectRenderScriptRuntimeKernelBreakpointSet(CommandInterpreter &interpreter)
14437dc7771cSEwan Crawford         : CommandObjectParsed(interpreter, "renderscript kernel breakpoint set",
14447dc7771cSEwan Crawford                               "Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint set <kernel_name>",
14454640cde1SColin Riley                               eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
14464640cde1SColin Riley     {
14474640cde1SColin Riley     }
14484640cde1SColin Riley 
14497dc7771cSEwan Crawford     ~CommandObjectRenderScriptRuntimeKernelBreakpointSet() {}
14504640cde1SColin Riley 
14514640cde1SColin Riley     bool
14524640cde1SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
14534640cde1SColin Riley     {
14544640cde1SColin Riley         const size_t argc = command.GetArgumentCount();
14554640cde1SColin Riley         if (argc == 1)
14564640cde1SColin Riley         {
14574640cde1SColin Riley             RenderScriptRuntime *runtime =
14584640cde1SColin Riley                 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
14594640cde1SColin Riley 
14604640cde1SColin Riley             Error error;
146198156583SEwan Crawford             runtime->AttemptBreakpointAtKernelName(result.GetOutputStream(), command.GetArgumentAtIndex(0),
146298156583SEwan Crawford                                                    error, m_exe_ctx.GetTargetSP());
14634640cde1SColin Riley 
14644640cde1SColin Riley             if (error.Success())
14654640cde1SColin Riley             {
14664640cde1SColin Riley                 result.AppendMessage("Breakpoint(s) created");
14674640cde1SColin Riley                 result.SetStatus(eReturnStatusSuccessFinishResult);
14684640cde1SColin Riley                 return true;
14694640cde1SColin Riley             }
14704640cde1SColin Riley             result.SetStatus(eReturnStatusFailed);
14714640cde1SColin Riley             result.AppendErrorWithFormat("Error: %s", error.AsCString());
14724640cde1SColin Riley             return false;
14734640cde1SColin Riley         }
14744640cde1SColin Riley 
14754640cde1SColin Riley         result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name", m_cmd_name.c_str());
14764640cde1SColin Riley         result.SetStatus(eReturnStatusFailed);
14774640cde1SColin Riley         return false;
14784640cde1SColin Riley     }
14794640cde1SColin Riley };
14804640cde1SColin Riley 
14817dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpointAll : public CommandObjectParsed
14827dc7771cSEwan Crawford {
14837dc7771cSEwan Crawford   private:
14847dc7771cSEwan Crawford   public:
14857dc7771cSEwan Crawford     CommandObjectRenderScriptRuntimeKernelBreakpointAll(CommandInterpreter &interpreter)
14867dc7771cSEwan Crawford         : CommandObjectParsed(interpreter, "renderscript kernel breakpoint all",
14877dc7771cSEwan Crawford                               "Automatically sets a breakpoint on all renderscript kernels that are or will be loaded.\n"
14887dc7771cSEwan Crawford                               "Disabling option means breakpoints will no longer be set on any kernels loaded in the future, "
14897dc7771cSEwan Crawford                               "but does not remove currently set breakpoints.",
14907dc7771cSEwan Crawford                               "renderscript kernel breakpoint all <enable/disable>",
14917dc7771cSEwan Crawford                               eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
14927dc7771cSEwan Crawford     {
14937dc7771cSEwan Crawford     }
14947dc7771cSEwan Crawford 
14957dc7771cSEwan Crawford     ~CommandObjectRenderScriptRuntimeKernelBreakpointAll() {}
14967dc7771cSEwan Crawford 
14977dc7771cSEwan Crawford     bool
14987dc7771cSEwan Crawford     DoExecute(Args &command, CommandReturnObject &result)
14997dc7771cSEwan Crawford     {
15007dc7771cSEwan Crawford         const size_t argc = command.GetArgumentCount();
15017dc7771cSEwan Crawford         if (argc != 1)
15027dc7771cSEwan Crawford         {
15037dc7771cSEwan Crawford             result.AppendErrorWithFormat("'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str());
15047dc7771cSEwan Crawford             result.SetStatus(eReturnStatusFailed);
15057dc7771cSEwan Crawford             return false;
15067dc7771cSEwan Crawford         }
15077dc7771cSEwan Crawford 
15087dc7771cSEwan Crawford         RenderScriptRuntime *runtime =
15097dc7771cSEwan Crawford           static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
15107dc7771cSEwan Crawford 
15117dc7771cSEwan Crawford         bool do_break = false;
15127dc7771cSEwan Crawford         const char* argument = command.GetArgumentAtIndex(0);
15137dc7771cSEwan Crawford         if (strcmp(argument, "enable") == 0)
15147dc7771cSEwan Crawford         {
15157dc7771cSEwan Crawford             do_break = true;
15167dc7771cSEwan Crawford             result.AppendMessage("Breakpoints will be set on all kernels.");
15177dc7771cSEwan Crawford         }
15187dc7771cSEwan Crawford         else if (strcmp(argument, "disable") == 0)
15197dc7771cSEwan Crawford         {
15207dc7771cSEwan Crawford             do_break = false;
15217dc7771cSEwan Crawford             result.AppendMessage("Breakpoints will not be set on any new kernels.");
15227dc7771cSEwan Crawford         }
15237dc7771cSEwan Crawford         else
15247dc7771cSEwan Crawford         {
15257dc7771cSEwan Crawford             result.AppendErrorWithFormat("Argument must be either 'enable' or 'disable'");
15267dc7771cSEwan Crawford             result.SetStatus(eReturnStatusFailed);
15277dc7771cSEwan Crawford             return false;
15287dc7771cSEwan Crawford         }
15297dc7771cSEwan Crawford 
15307dc7771cSEwan Crawford         runtime->SetBreakAllKernels(do_break, m_exe_ctx.GetTargetSP());
15317dc7771cSEwan Crawford 
15327dc7771cSEwan Crawford         result.SetStatus(eReturnStatusSuccessFinishResult);
15337dc7771cSEwan Crawford         return true;
15347dc7771cSEwan Crawford     }
15357dc7771cSEwan Crawford };
15367dc7771cSEwan Crawford 
15377dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectMultiword
15387dc7771cSEwan Crawford {
15397dc7771cSEwan Crawford   private:
15407dc7771cSEwan Crawford   public:
15417dc7771cSEwan Crawford     CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter)
15427dc7771cSEwan Crawford         : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that generate breakpoints on renderscript kernels.",
15437dc7771cSEwan Crawford                                  nullptr)
15447dc7771cSEwan Crawford     {
15457dc7771cSEwan Crawford         LoadSubCommand("set", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointSet(interpreter)));
15467dc7771cSEwan Crawford         LoadSubCommand("all", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointAll(interpreter)));
15477dc7771cSEwan Crawford     }
15487dc7771cSEwan Crawford 
15497dc7771cSEwan Crawford     ~CommandObjectRenderScriptRuntimeKernelBreakpoint() {}
15507dc7771cSEwan Crawford };
15517dc7771cSEwan Crawford 
15524640cde1SColin Riley class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword
15534640cde1SColin Riley {
15544640cde1SColin Riley   private:
15554640cde1SColin Riley   public:
15564640cde1SColin Riley     CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter)
15574640cde1SColin Riley         : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with renderscript kernels.",
15584640cde1SColin Riley                                  NULL)
15594640cde1SColin Riley     {
15604640cde1SColin Riley         LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(interpreter)));
15614640cde1SColin Riley         LoadSubCommand("breakpoint", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter)));
15624640cde1SColin Riley     }
15634640cde1SColin Riley 
15644640cde1SColin Riley     ~CommandObjectRenderScriptRuntimeKernel() {}
15654640cde1SColin Riley };
15664640cde1SColin Riley 
15674640cde1SColin Riley class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed
15684640cde1SColin Riley {
15694640cde1SColin Riley   private:
15704640cde1SColin Riley   public:
15714640cde1SColin Riley     CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter)
15724640cde1SColin Riley         : CommandObjectParsed(interpreter, "renderscript context dump",
15734640cde1SColin Riley                               "Dumps renderscript context information.", "renderscript context dump",
15744640cde1SColin Riley                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
15754640cde1SColin Riley     {
15764640cde1SColin Riley     }
15774640cde1SColin Riley 
15784640cde1SColin Riley     ~CommandObjectRenderScriptRuntimeContextDump() {}
15794640cde1SColin Riley 
15804640cde1SColin Riley     bool
15814640cde1SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
15824640cde1SColin Riley     {
15834640cde1SColin Riley         RenderScriptRuntime *runtime =
15844640cde1SColin Riley             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
15854640cde1SColin Riley         runtime->DumpContexts(result.GetOutputStream());
15864640cde1SColin Riley         result.SetStatus(eReturnStatusSuccessFinishResult);
15874640cde1SColin Riley         return true;
15884640cde1SColin Riley     }
15894640cde1SColin Riley };
15904640cde1SColin Riley 
15914640cde1SColin Riley class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword
15924640cde1SColin Riley {
15934640cde1SColin Riley   private:
15944640cde1SColin Riley   public:
15954640cde1SColin Riley     CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter)
15964640cde1SColin Riley         : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with renderscript contexts.",
15974640cde1SColin Riley                                  NULL)
15984640cde1SColin Riley     {
15994640cde1SColin Riley         LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(interpreter)));
16004640cde1SColin Riley     }
16014640cde1SColin Riley 
16024640cde1SColin Riley     ~CommandObjectRenderScriptRuntimeContext() {}
16034640cde1SColin Riley };
16044640cde1SColin Riley 
16054640cde1SColin Riley class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed
16064640cde1SColin Riley {
16074640cde1SColin Riley   private:
16084640cde1SColin Riley   public:
16094640cde1SColin Riley     CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter)
16104640cde1SColin Riley         : CommandObjectParsed(interpreter, "renderscript status",
16114640cde1SColin Riley                               "Displays current renderscript runtime status.", "renderscript status",
16124640cde1SColin Riley                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
16134640cde1SColin Riley     {
16144640cde1SColin Riley     }
16154640cde1SColin Riley 
16164640cde1SColin Riley     ~CommandObjectRenderScriptRuntimeStatus() {}
16174640cde1SColin Riley 
16184640cde1SColin Riley     bool
16194640cde1SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
16204640cde1SColin Riley     {
16214640cde1SColin Riley         RenderScriptRuntime *runtime =
16224640cde1SColin Riley             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
16234640cde1SColin Riley         runtime->Status(result.GetOutputStream());
16244640cde1SColin Riley         result.SetStatus(eReturnStatusSuccessFinishResult);
16254640cde1SColin Riley         return true;
16264640cde1SColin Riley     }
16274640cde1SColin Riley };
16284640cde1SColin Riley 
16295ec532a9SColin Riley class CommandObjectRenderScriptRuntime : public CommandObjectMultiword
16305ec532a9SColin Riley {
16315ec532a9SColin Riley   public:
16325ec532a9SColin Riley     CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter)
16335ec532a9SColin Riley         : CommandObjectMultiword(interpreter, "renderscript", "A set of commands for operating on renderscript.",
16345ec532a9SColin Riley                                  "renderscript <subcommand> [<subcommand-options>]")
16355ec532a9SColin Riley     {
16365ec532a9SColin Riley         LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter)));
16374640cde1SColin Riley         LoadSubCommand("status", CommandObjectSP(new CommandObjectRenderScriptRuntimeStatus(interpreter)));
16384640cde1SColin Riley         LoadSubCommand("kernel", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernel(interpreter)));
16394640cde1SColin Riley         LoadSubCommand("context", CommandObjectSP(new CommandObjectRenderScriptRuntimeContext(interpreter)));
16405ec532a9SColin Riley     }
16415ec532a9SColin Riley 
16425ec532a9SColin Riley     ~CommandObjectRenderScriptRuntime() {}
16435ec532a9SColin Riley };
1644ef20b08fSColin Riley 
1645ef20b08fSColin Riley void
1646ef20b08fSColin Riley RenderScriptRuntime::Initiate()
16475ec532a9SColin Riley {
1648ef20b08fSColin Riley     assert(!m_initiated);
16495ec532a9SColin Riley }
1650ef20b08fSColin Riley 
1651ef20b08fSColin Riley RenderScriptRuntime::RenderScriptRuntime(Process *process)
16527dc7771cSEwan Crawford     : lldb_private::CPPLanguageRuntime(process), m_initiated(false), m_debuggerPresentFlagged(false),
16537dc7771cSEwan Crawford       m_breakAllKernels(false)
1654ef20b08fSColin Riley {
16554640cde1SColin Riley     ModulesDidLoad(process->GetTarget().GetImages());
1656ef20b08fSColin Riley }
16574640cde1SColin Riley 
16584640cde1SColin Riley lldb::CommandObjectSP
16594640cde1SColin Riley RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter& interpreter)
16604640cde1SColin Riley {
16614640cde1SColin Riley     static CommandObjectSP command_object;
16624640cde1SColin Riley     if(!command_object)
16634640cde1SColin Riley     {
16644640cde1SColin Riley         command_object.reset(new CommandObjectRenderScriptRuntime(interpreter));
16654640cde1SColin Riley     }
16664640cde1SColin Riley     return command_object;
16674640cde1SColin Riley }
16684640cde1SColin Riley 
1669*78f339d1SEwan Crawford RenderScriptRuntime::~RenderScriptRuntime() = default;
1670