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 3578f339d1SEwan Crawford namespace { 3678f339d1SEwan Crawford 3778f339d1SEwan Crawford // The empirical_type adds a basic level of validation to arbitrary data 3878f339d1SEwan Crawford // allowing us to track if data has been discovered and stored or not. 3978f339d1SEwan Crawford // An empirical_type will be marked as valid only if it has been explicitly assigned to. 4078f339d1SEwan Crawford template <typename type_t> 4178f339d1SEwan Crawford class empirical_type 4278f339d1SEwan Crawford { 4378f339d1SEwan Crawford public: 4478f339d1SEwan Crawford // Ctor. Contents is invalid when constructed. 4578f339d1SEwan Crawford empirical_type() 4678f339d1SEwan Crawford : valid(false) 4778f339d1SEwan Crawford {} 4878f339d1SEwan Crawford 4978f339d1SEwan Crawford // Return true and copy contents to out if valid, else return false. 5078f339d1SEwan Crawford bool get(type_t& out) const 5178f339d1SEwan Crawford { 5278f339d1SEwan Crawford if (valid) 5378f339d1SEwan Crawford out = data; 5478f339d1SEwan Crawford return valid; 5578f339d1SEwan Crawford } 5678f339d1SEwan Crawford 5778f339d1SEwan Crawford // Return a pointer to the contents or nullptr if it was not valid. 5878f339d1SEwan Crawford const type_t* get() const 5978f339d1SEwan Crawford { 6078f339d1SEwan Crawford return valid ? &data : nullptr; 6178f339d1SEwan Crawford } 6278f339d1SEwan Crawford 6378f339d1SEwan Crawford // Assign data explicitly. 6478f339d1SEwan Crawford void set(const type_t in) 6578f339d1SEwan Crawford { 6678f339d1SEwan Crawford data = in; 6778f339d1SEwan Crawford valid = true; 6878f339d1SEwan Crawford } 6978f339d1SEwan Crawford 7078f339d1SEwan Crawford // Mark contents as invalid. 7178f339d1SEwan Crawford void invalidate() 7278f339d1SEwan Crawford { 7378f339d1SEwan Crawford valid = false; 7478f339d1SEwan Crawford } 7578f339d1SEwan Crawford 7678f339d1SEwan Crawford // Returns true if this type contains valid data. 7778f339d1SEwan Crawford bool isValid() const 7878f339d1SEwan Crawford { 7978f339d1SEwan Crawford return valid; 8078f339d1SEwan Crawford } 8178f339d1SEwan Crawford 8278f339d1SEwan Crawford // Assignment operator. 8378f339d1SEwan Crawford empirical_type<type_t>& operator = (const type_t in) 8478f339d1SEwan Crawford { 8578f339d1SEwan Crawford set(in); 8678f339d1SEwan Crawford return *this; 8778f339d1SEwan Crawford } 8878f339d1SEwan Crawford 8978f339d1SEwan Crawford // Dereference operator returns contents. 9078f339d1SEwan Crawford // Warning: Will assert if not valid so use only when you know data is valid. 9178f339d1SEwan Crawford const type_t& operator * () const 9278f339d1SEwan Crawford { 9378f339d1SEwan Crawford assert(valid); 9478f339d1SEwan Crawford return data; 9578f339d1SEwan Crawford } 9678f339d1SEwan Crawford 9778f339d1SEwan Crawford protected: 9878f339d1SEwan Crawford bool valid; 9978f339d1SEwan Crawford type_t data; 10078f339d1SEwan Crawford }; 10178f339d1SEwan Crawford 10278f339d1SEwan Crawford } // namespace {} 10378f339d1SEwan Crawford 10478f339d1SEwan Crawford // The ScriptDetails class collects data associated with a single script instance. 10578f339d1SEwan Crawford struct RenderScriptRuntime::ScriptDetails 10678f339d1SEwan Crawford { 10778f339d1SEwan Crawford ~ScriptDetails() {}; 10878f339d1SEwan Crawford 10978f339d1SEwan Crawford enum ScriptType 11078f339d1SEwan Crawford { 11178f339d1SEwan Crawford eScript, 11278f339d1SEwan Crawford eScriptC 11378f339d1SEwan Crawford }; 11478f339d1SEwan Crawford 11578f339d1SEwan Crawford // The derived type of the script. 11678f339d1SEwan Crawford empirical_type<ScriptType> type; 11778f339d1SEwan Crawford // The name of the original source file. 11878f339d1SEwan Crawford empirical_type<std::string> resName; 11978f339d1SEwan Crawford // Path to script .so file on the device. 12078f339d1SEwan Crawford empirical_type<std::string> scriptDyLib; 12178f339d1SEwan Crawford // Directory where kernel objects are cached on device. 12278f339d1SEwan Crawford empirical_type<std::string> cacheDir; 12378f339d1SEwan Crawford // Pointer to the context which owns this script. 12478f339d1SEwan Crawford empirical_type<lldb::addr_t> context; 12578f339d1SEwan Crawford // Pointer to the script object itself. 12678f339d1SEwan Crawford empirical_type<lldb::addr_t> script; 12778f339d1SEwan Crawford }; 12878f339d1SEwan Crawford 12978f339d1SEwan Crawford // This AllocationDetails class collects data associated with a single 13078f339d1SEwan Crawford // allocation instance. 13178f339d1SEwan Crawford struct RenderScriptRuntime::AllocationDetails 13278f339d1SEwan Crawford { 13378f339d1SEwan Crawford ~AllocationDetails () {}; 13478f339d1SEwan Crawford 13578f339d1SEwan Crawford enum DataType 13678f339d1SEwan Crawford { 13778f339d1SEwan Crawford eInt, 13878f339d1SEwan Crawford }; 13978f339d1SEwan Crawford 14078f339d1SEwan Crawford enum Dimension 14178f339d1SEwan Crawford { 14278f339d1SEwan Crawford e1d, 14378f339d1SEwan Crawford e2d, 14478f339d1SEwan Crawford e3d, 14578f339d1SEwan Crawford eCubeMap, 14678f339d1SEwan Crawford }; 14778f339d1SEwan Crawford 14878f339d1SEwan Crawford empirical_type<DataType> type; 14978f339d1SEwan Crawford empirical_type<Dimension> dimension; 15078f339d1SEwan Crawford empirical_type<lldb::addr_t> address; 15178f339d1SEwan Crawford empirical_type<lldb::addr_t> dataPtr; 15278f339d1SEwan Crawford empirical_type<lldb::addr_t> context; 15378f339d1SEwan Crawford }; 15478f339d1SEwan 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 316*c74275bcSEnrico Granata TypeAndOrName 317*c74275bcSEnrico Granata RenderScriptRuntime::FixUpDynamicType(const TypeAndOrName& type_and_or_name, 318*c74275bcSEnrico Granata const CompilerType& static_type) 319*c74275bcSEnrico Granata { 320*c74275bcSEnrico Granata return type_and_or_name; 321*c74275bcSEnrico Granata } 322*c74275bcSEnrico Granata 3235ec532a9SColin Riley bool 3245ec532a9SColin Riley RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value) 3255ec532a9SColin Riley { 3265ec532a9SColin Riley return false; 3275ec532a9SColin Riley } 3285ec532a9SColin Riley 3295ec532a9SColin Riley lldb::BreakpointResolverSP 3305ec532a9SColin Riley RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) 3315ec532a9SColin Riley { 3325ec532a9SColin Riley BreakpointResolverSP resolver_sp; 3335ec532a9SColin Riley return resolver_sp; 3345ec532a9SColin Riley } 3355ec532a9SColin Riley 3364640cde1SColin Riley 3374640cde1SColin Riley const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] = 3384640cde1SColin Riley { 3394640cde1SColin Riley //rsdScript 34082780287SAidan Dodds { 34182780287SAidan Dodds "rsdScriptInit", //name 34282780287SAidan Dodds "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhjj", // symbol name 32 bit 34382780287SAidan Dodds "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhmj", // symbol name 64 bit 34482780287SAidan Dodds 0, // version 34582780287SAidan Dodds RenderScriptRuntime::eModuleKindDriver, // type 34682780287SAidan Dodds &lldb_private::RenderScriptRuntime::CaptureScriptInit1 // handler 34782780287SAidan Dodds }, 34882780287SAidan Dodds { 34982780287SAidan Dodds "rsdScriptInvokeForEach", // name 35082780287SAidan Dodds "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvjPK12RsScriptCall", // symbol name 32bit 35182780287SAidan Dodds "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvmPK12RsScriptCall", // symbol name 64bit 35282780287SAidan Dodds 0, // version 35382780287SAidan Dodds RenderScriptRuntime::eModuleKindDriver, // type 35482780287SAidan Dodds nullptr // handler 35582780287SAidan Dodds }, 35682780287SAidan Dodds { 35782780287SAidan Dodds "rsdScriptInvokeForEachMulti", // name 35882780287SAidan Dodds "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall", // symbol name 32bit 35982780287SAidan Dodds "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEmPS6_PKvmPK12RsScriptCall", // symbol name 64bit 36082780287SAidan Dodds 0, // version 36182780287SAidan Dodds RenderScriptRuntime::eModuleKindDriver, // type 36282780287SAidan Dodds nullptr // handler 36382780287SAidan Dodds }, 36482780287SAidan Dodds { 36582780287SAidan Dodds "rsdScriptInvokeFunction", // name 36682780287SAidan Dodds "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvj", // symbol name 32bit 36782780287SAidan Dodds "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvm", // symbol name 64bit 36882780287SAidan Dodds 0, // version 36982780287SAidan Dodds RenderScriptRuntime::eModuleKindDriver, // type 37082780287SAidan Dodds nullptr // handler 37182780287SAidan Dodds }, 37282780287SAidan Dodds { 37382780287SAidan Dodds "rsdScriptSetGlobalVar", // name 37482780287SAidan Dodds "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvj", // symbol name 32bit 37582780287SAidan Dodds "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvm", // symbol name 64bit 37682780287SAidan Dodds 0, // version 37782780287SAidan Dodds RenderScriptRuntime::eModuleKindDriver, // type 37882780287SAidan Dodds &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar1 // handler 37982780287SAidan Dodds }, 3804640cde1SColin Riley 3814640cde1SColin Riley //rsdAllocation 38282780287SAidan Dodds { 38382780287SAidan Dodds "rsdAllocationInit", // name 38482780287SAidan Dodds "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 32bit 38582780287SAidan Dodds "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 64bit 38682780287SAidan Dodds 0, // version 38782780287SAidan Dodds RenderScriptRuntime::eModuleKindDriver, // type 38882780287SAidan Dodds &lldb_private::RenderScriptRuntime::CaptureAllocationInit1 // handler 38982780287SAidan Dodds }, 39082780287SAidan Dodds { 39182780287SAidan Dodds "rsdAllocationRead2D", //name 39282780287SAidan Dodds "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvjj", // symbol name 32bit 39382780287SAidan Dodds "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvmm", // symbol name 64bit 39482780287SAidan Dodds 0, // version 39582780287SAidan Dodds RenderScriptRuntime::eModuleKindDriver, // type 39682780287SAidan Dodds nullptr // handler 39782780287SAidan Dodds }, 3984640cde1SColin Riley }; 3994640cde1SColin Riley const size_t RenderScriptRuntime::s_runtimeHookCount = sizeof(s_runtimeHookDefns)/sizeof(s_runtimeHookDefns[0]); 4004640cde1SColin Riley 4014640cde1SColin Riley 4024640cde1SColin Riley bool 4034640cde1SColin Riley RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, lldb::user_id_t break_loc_id) 4044640cde1SColin Riley { 4054640cde1SColin Riley RuntimeHook* hook_info = (RuntimeHook*)baton; 4064640cde1SColin Riley ExecutionContext context(ctx->exe_ctx_ref); 4074640cde1SColin Riley 4084640cde1SColin Riley RenderScriptRuntime *lang_rt = (RenderScriptRuntime *)context.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 4094640cde1SColin Riley 4104640cde1SColin Riley lang_rt->HookCallback(hook_info, context); 4114640cde1SColin Riley 4124640cde1SColin Riley return false; 4134640cde1SColin Riley } 4144640cde1SColin Riley 4154640cde1SColin Riley 4164640cde1SColin Riley void 4174640cde1SColin Riley RenderScriptRuntime::HookCallback(RuntimeHook* hook_info, ExecutionContext& context) 4184640cde1SColin Riley { 4194640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 4204640cde1SColin Riley 4214640cde1SColin Riley if (log) 4224640cde1SColin Riley log->Printf ("RenderScriptRuntime::HookCallback - '%s' .", hook_info->defn->name); 4234640cde1SColin Riley 4244640cde1SColin Riley if (hook_info->defn->grabber) 4254640cde1SColin Riley { 4264640cde1SColin Riley (this->*(hook_info->defn->grabber))(hook_info, context); 4274640cde1SColin Riley } 4284640cde1SColin Riley } 4294640cde1SColin Riley 4304640cde1SColin Riley 4314640cde1SColin Riley bool 43282780287SAidan Dodds RenderScriptRuntime::GetArgSimple(ExecutionContext &context, uint32_t arg, uint64_t *data) 4334640cde1SColin Riley { 4344640cde1SColin Riley if (!data) 4354640cde1SColin Riley return false; 4364640cde1SColin Riley 43782780287SAidan Dodds Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 4384640cde1SColin Riley Error error; 4394640cde1SColin Riley RegisterContext* reg_ctx = context.GetRegisterContext(); 4404640cde1SColin Riley Process* process = context.GetProcessPtr(); 44182780287SAidan Dodds bool success = false; // return value 4424640cde1SColin Riley 44382780287SAidan Dodds if (!context.GetTargetPtr()) 44482780287SAidan Dodds { 44582780287SAidan Dodds if (log) 44682780287SAidan Dodds log->Printf("RenderScriptRuntime::GetArgSimple - Invalid target"); 44782780287SAidan Dodds 44882780287SAidan Dodds return false; 44982780287SAidan Dodds } 45082780287SAidan Dodds 45182780287SAidan Dodds switch (context.GetTargetPtr()->GetArchitecture().GetMachine()) 45282780287SAidan Dodds { 45382780287SAidan Dodds case llvm::Triple::ArchType::x86: 4544640cde1SColin Riley { 4554640cde1SColin Riley uint64_t sp = reg_ctx->GetSP(); 4564640cde1SColin Riley uint32_t offset = (1 + arg) * sizeof(uint32_t); 45782780287SAidan Dodds uint32_t result = 0; 45882780287SAidan Dodds process->ReadMemory(sp + offset, &result, sizeof(uint32_t), error); 4594640cde1SColin Riley if (error.Fail()) 4604640cde1SColin Riley { 4614640cde1SColin Riley if (log) 46282780287SAidan Dodds log->Printf ("RenderScriptRuntime:: GetArgSimple - error reading X86 stack: %s.", error.AsCString()); 4634640cde1SColin Riley } 46482780287SAidan Dodds else 4654640cde1SColin Riley { 46682780287SAidan Dodds *data = result; 46782780287SAidan Dodds success = true; 46882780287SAidan Dodds } 46982780287SAidan Dodds 47082780287SAidan Dodds break; 47182780287SAidan Dodds } 47282780287SAidan Dodds case llvm::Triple::ArchType::arm: 47382780287SAidan Dodds { 47482780287SAidan Dodds // arm 32 bit 4754640cde1SColin Riley if (arg < 4) 4764640cde1SColin Riley { 4774640cde1SColin Riley const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg); 4784640cde1SColin Riley RegisterValue rVal; 4794640cde1SColin Riley reg_ctx->ReadRegister(rArg, rVal); 4804640cde1SColin Riley (*data) = rVal.GetAsUInt32(); 48182780287SAidan Dodds success = true; 4824640cde1SColin Riley } 4834640cde1SColin Riley else 4844640cde1SColin Riley { 4854640cde1SColin Riley uint64_t sp = reg_ctx->GetSP(); 4864640cde1SColin Riley { 4874640cde1SColin Riley uint32_t offset = (arg-4) * sizeof(uint32_t); 4884640cde1SColin Riley process->ReadMemory(sp + offset, &data, sizeof(uint32_t), error); 4894640cde1SColin Riley if (error.Fail()) 4904640cde1SColin Riley { 4914640cde1SColin Riley if (log) 49282780287SAidan Dodds log->Printf ("RenderScriptRuntime:: GetArgSimple - error reading ARM stack: %s.", error.AsCString()); 49382780287SAidan Dodds } 49482780287SAidan Dodds else 49582780287SAidan Dodds { 49682780287SAidan Dodds success = true; 4974640cde1SColin Riley } 4984640cde1SColin Riley } 4994640cde1SColin Riley } 50082780287SAidan Dodds 50182780287SAidan Dodds break; 5024640cde1SColin Riley } 50382780287SAidan Dodds case llvm::Triple::ArchType::aarch64: 50482780287SAidan Dodds { 50582780287SAidan Dodds // arm 64 bit 50682780287SAidan Dodds // first 8 arguments are in the registers 50782780287SAidan Dodds if (arg < 8) 50882780287SAidan Dodds { 50982780287SAidan Dodds const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg); 51082780287SAidan Dodds RegisterValue rVal; 51182780287SAidan Dodds success = reg_ctx->ReadRegister(rArg, rVal); 51282780287SAidan Dodds if (success) 51382780287SAidan Dodds { 51482780287SAidan Dodds *data = rVal.GetAsUInt64(); 51582780287SAidan Dodds } 51682780287SAidan Dodds else 51782780287SAidan Dodds { 51882780287SAidan Dodds if (log) 51982780287SAidan Dodds log->Printf("RenderScriptRuntime::GetArgSimple() - AARCH64 - Error while reading the argument #%d", arg); 52082780287SAidan Dodds } 52182780287SAidan Dodds } 52282780287SAidan Dodds else 52382780287SAidan Dodds { 52482780287SAidan Dodds // @TODO: need to find the argument in the stack 52582780287SAidan Dodds if (log) 52682780287SAidan Dodds log->Printf("RenderScriptRuntime::GetArgSimple - AARCH64 - FOR #ARG >= 8 NOT IMPLEMENTED YET. Argument number: %d", arg); 52782780287SAidan Dodds } 52882780287SAidan Dodds break; 52982780287SAidan Dodds } 53082780287SAidan Dodds default: 53182780287SAidan Dodds { 53282780287SAidan Dodds // invalid architecture 53382780287SAidan Dodds if (log) 53482780287SAidan Dodds log->Printf("RenderScriptRuntime::GetArgSimple - Architecture not supported"); 53582780287SAidan Dodds 53682780287SAidan Dodds } 53782780287SAidan Dodds } 53882780287SAidan Dodds 53982780287SAidan Dodds 54082780287SAidan Dodds return success; 5414640cde1SColin Riley } 5424640cde1SColin Riley 5434640cde1SColin Riley void 5444640cde1SColin Riley RenderScriptRuntime::CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context) 5454640cde1SColin Riley { 5464640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 5474640cde1SColin Riley 5484640cde1SColin Riley //Context, Script, int, data, length 5494640cde1SColin Riley 55082780287SAidan Dodds uint64_t rs_context_u64 = 0U; 55182780287SAidan Dodds uint64_t rs_script_u64 = 0U; 55282780287SAidan Dodds uint64_t rs_id_u64 = 0U; 55382780287SAidan Dodds uint64_t rs_data_u64 = 0U; 55482780287SAidan Dodds uint64_t rs_length_u64 = 0U; 5554640cde1SColin Riley 55682780287SAidan Dodds bool success = 55782780287SAidan Dodds GetArgSimple(context, 0, &rs_context_u64) && 55882780287SAidan Dodds GetArgSimple(context, 1, &rs_script_u64) && 55982780287SAidan Dodds GetArgSimple(context, 2, &rs_id_u64) && 56082780287SAidan Dodds GetArgSimple(context, 3, &rs_data_u64) && 56182780287SAidan Dodds GetArgSimple(context, 4, &rs_length_u64); 5624640cde1SColin Riley 56382780287SAidan Dodds if (!success) 56482780287SAidan Dodds { 56582780287SAidan Dodds if (log) 56682780287SAidan Dodds log->Printf("RenderScriptRuntime::CaptureSetGlobalVar1 - Error while reading the function parameters"); 56782780287SAidan Dodds return; 56882780287SAidan Dodds } 5694640cde1SColin Riley 5704640cde1SColin Riley if (log) 5714640cde1SColin Riley { 5724640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 ":%" PRIu64 "bytes.", 57382780287SAidan Dodds rs_context_u64, rs_script_u64, rs_id_u64, rs_data_u64, rs_length_u64); 5744640cde1SColin Riley 57582780287SAidan Dodds addr_t script_addr = (addr_t)rs_script_u64; 5764640cde1SColin Riley if (m_scriptMappings.find( script_addr ) != m_scriptMappings.end()) 5774640cde1SColin Riley { 5784640cde1SColin Riley auto rsm = m_scriptMappings[script_addr]; 57982780287SAidan Dodds if (rs_id_u64 < rsm->m_globals.size()) 5804640cde1SColin Riley { 58182780287SAidan Dodds auto rsg = rsm->m_globals[rs_id_u64]; 5824640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - Setting of '%s' within '%s' inferred", rsg.m_name.AsCString(), 5834640cde1SColin Riley rsm->m_module->GetFileSpec().GetFilename().AsCString()); 5844640cde1SColin Riley } 5854640cde1SColin Riley } 5864640cde1SColin Riley } 5874640cde1SColin Riley } 5884640cde1SColin Riley 5894640cde1SColin Riley void 5904640cde1SColin Riley RenderScriptRuntime::CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context) 5914640cde1SColin Riley { 5924640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 5934640cde1SColin Riley 5944640cde1SColin Riley //Context, Alloc, bool 5954640cde1SColin Riley 59682780287SAidan Dodds uint64_t rs_context_u64 = 0U; 59782780287SAidan Dodds uint64_t rs_alloc_u64 = 0U; 59882780287SAidan Dodds uint64_t rs_forceZero_u64 = 0U; 5994640cde1SColin Riley 60082780287SAidan Dodds bool success = 60182780287SAidan Dodds GetArgSimple(context, 0, &rs_context_u64) && 60282780287SAidan Dodds GetArgSimple(context, 1, &rs_alloc_u64) && 60382780287SAidan Dodds GetArgSimple(context, 2, &rs_forceZero_u64); 60482780287SAidan Dodds if (!success) // error case 60582780287SAidan Dodds { 60682780287SAidan Dodds if (log) 60782780287SAidan Dodds log->Printf("RenderScriptRuntime::CaptureAllocationInit1 - Error while reading the function parameters"); 60882780287SAidan Dodds return; // abort 60982780287SAidan Dodds } 6104640cde1SColin Riley 6114640cde1SColin Riley if (log) 6124640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureAllocationInit1 - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .", 61382780287SAidan Dodds rs_context_u64, rs_alloc_u64, rs_forceZero_u64); 61478f339d1SEwan Crawford 61578f339d1SEwan Crawford AllocationDetails* alloc = LookUpAllocation(rs_alloc_u64, true); 61678f339d1SEwan Crawford if (alloc) 61778f339d1SEwan Crawford alloc->context = rs_context_u64; 6184640cde1SColin Riley } 6194640cde1SColin Riley 6204640cde1SColin Riley void 6214640cde1SColin Riley RenderScriptRuntime::CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context) 6224640cde1SColin Riley { 6234640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 6244640cde1SColin Riley 6254640cde1SColin Riley //Context, Script, resname Str, cachedir Str 6264640cde1SColin Riley Error error; 6274640cde1SColin Riley Process* process = context.GetProcessPtr(); 6284640cde1SColin Riley 62982780287SAidan Dodds uint64_t rs_context_u64 = 0U; 63082780287SAidan Dodds uint64_t rs_script_u64 = 0U; 63182780287SAidan Dodds uint64_t rs_resnameptr_u64 = 0U; 63282780287SAidan Dodds uint64_t rs_cachedirptr_u64 = 0U; 6334640cde1SColin Riley 6344640cde1SColin Riley std::string resname; 6354640cde1SColin Riley std::string cachedir; 6364640cde1SColin Riley 63782780287SAidan Dodds // read the function parameters 63882780287SAidan Dodds bool success = 63982780287SAidan Dodds GetArgSimple(context, 0, &rs_context_u64) && 64082780287SAidan Dodds GetArgSimple(context, 1, &rs_script_u64) && 64182780287SAidan Dodds GetArgSimple(context, 2, &rs_resnameptr_u64) && 64282780287SAidan Dodds GetArgSimple(context, 3, &rs_cachedirptr_u64); 6434640cde1SColin Riley 64482780287SAidan Dodds if (!success) 64582780287SAidan Dodds { 64682780287SAidan Dodds if (log) 64782780287SAidan Dodds log->Printf("RenderScriptRuntime::CaptureScriptInit1 - Error while reading the function parameters"); 64882780287SAidan Dodds return; 64982780287SAidan Dodds } 65082780287SAidan Dodds 65182780287SAidan Dodds process->ReadCStringFromMemory((lldb::addr_t)rs_resnameptr_u64, resname, error); 6524640cde1SColin Riley if (error.Fail()) 6534640cde1SColin Riley { 6544640cde1SColin Riley if (log) 6554640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading resname: %s.", error.AsCString()); 6564640cde1SColin Riley 6574640cde1SColin Riley } 6584640cde1SColin Riley 65982780287SAidan Dodds process->ReadCStringFromMemory((lldb::addr_t)rs_cachedirptr_u64, cachedir, error); 6604640cde1SColin Riley if (error.Fail()) 6614640cde1SColin Riley { 6624640cde1SColin Riley if (log) 6634640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading cachedir: %s.", error.AsCString()); 6644640cde1SColin Riley } 6654640cde1SColin Riley 6664640cde1SColin Riley if (log) 6674640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .", 66882780287SAidan Dodds rs_context_u64, rs_script_u64, resname.c_str(), cachedir.c_str()); 6694640cde1SColin Riley 6704640cde1SColin Riley if (resname.size() > 0) 6714640cde1SColin Riley { 6724640cde1SColin Riley StreamString strm; 6734640cde1SColin Riley strm.Printf("librs.%s.so", resname.c_str()); 6744640cde1SColin Riley 67578f339d1SEwan Crawford ScriptDetails* script = LookUpScript(rs_script_u64, true); 67678f339d1SEwan Crawford if (script) 67778f339d1SEwan Crawford { 67878f339d1SEwan Crawford script->type = ScriptDetails::eScriptC; 67978f339d1SEwan Crawford script->cacheDir = cachedir; 68078f339d1SEwan Crawford script->resName = resname; 68178f339d1SEwan Crawford script->scriptDyLib = strm.GetData(); 68278f339d1SEwan Crawford script->context = addr_t(rs_context_u64); 68378f339d1SEwan Crawford } 6844640cde1SColin Riley 6854640cde1SColin Riley if (log) 6864640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - '%s' tagged with context 0x%" PRIx64 " and script 0x%" PRIx64 ".", 68782780287SAidan Dodds strm.GetData(), rs_context_u64, rs_script_u64); 6884640cde1SColin Riley } 6894640cde1SColin Riley else if (log) 6904640cde1SColin Riley { 6914640cde1SColin Riley log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - resource name invalid, Script not tagged"); 6924640cde1SColin Riley } 6934640cde1SColin Riley 6944640cde1SColin Riley } 6954640cde1SColin Riley 6964640cde1SColin Riley void 6974640cde1SColin Riley RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind) 6984640cde1SColin Riley { 6994640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 7004640cde1SColin Riley 7014640cde1SColin Riley if (!module) 7024640cde1SColin Riley { 7034640cde1SColin Riley return; 7044640cde1SColin Riley } 7054640cde1SColin Riley 70682780287SAidan Dodds Target &target = GetProcess()->GetTarget(); 70782780287SAidan Dodds llvm::Triple::ArchType targetArchType = target.GetArchitecture().GetMachine(); 70882780287SAidan Dodds 70982780287SAidan Dodds if (targetArchType != llvm::Triple::ArchType::x86 71082780287SAidan Dodds && targetArchType != llvm::Triple::ArchType::arm 71182780287SAidan Dodds && targetArchType != llvm::Triple::ArchType::aarch64) 7124640cde1SColin Riley { 7134640cde1SColin Riley if (log) 7144640cde1SColin Riley log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to hook runtime. Only X86, ARM supported currently."); 7154640cde1SColin Riley 7164640cde1SColin Riley return; 7174640cde1SColin Riley } 7184640cde1SColin Riley 71982780287SAidan Dodds uint32_t archByteSize = target.GetArchitecture().GetAddressByteSize(); 7204640cde1SColin Riley 7214640cde1SColin Riley for (size_t idx = 0; idx < s_runtimeHookCount; idx++) 7224640cde1SColin Riley { 7234640cde1SColin Riley const HookDefn* hook_defn = &s_runtimeHookDefns[idx]; 7244640cde1SColin Riley if (hook_defn->kind != kind) { 7254640cde1SColin Riley continue; 7264640cde1SColin Riley } 7274640cde1SColin Riley 72882780287SAidan Dodds const char* symbol_name = (archByteSize == 4) ? hook_defn->symbol_name_m32 : hook_defn->symbol_name_m64; 72982780287SAidan Dodds 73082780287SAidan Dodds const Symbol *sym = module->FindFirstSymbolWithNameAndType(ConstString(symbol_name), eSymbolTypeCode); 73182780287SAidan Dodds if (!sym){ 73282780287SAidan Dodds if (log){ 73382780287SAidan Dodds log->Printf("RenderScriptRuntime::LoadRuntimeHooks - ERROR: Symbol '%s' related to the function %s not found", symbol_name, hook_defn->name); 73482780287SAidan Dodds } 73582780287SAidan Dodds continue; 73682780287SAidan Dodds } 7374640cde1SColin Riley 738358cf1eaSGreg Clayton addr_t addr = sym->GetLoadAddress(&target); 7394640cde1SColin Riley if (addr == LLDB_INVALID_ADDRESS) 7404640cde1SColin Riley { 7414640cde1SColin Riley if (log) 7424640cde1SColin Riley log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to resolve the address of hook function '%s' with symbol '%s'.", 74382780287SAidan Dodds hook_defn->name, symbol_name); 7444640cde1SColin Riley continue; 7454640cde1SColin Riley } 74682780287SAidan Dodds else 74782780287SAidan Dodds { 74882780287SAidan Dodds if (log) 74982780287SAidan Dodds log->Printf("RenderScriptRuntime::LoadRuntimeHooks - Function %s, address resolved at 0x%" PRIx64, hook_defn->name, addr); 75082780287SAidan Dodds } 7514640cde1SColin Riley 7524640cde1SColin Riley RuntimeHookSP hook(new RuntimeHook()); 7534640cde1SColin Riley hook->address = addr; 7544640cde1SColin Riley hook->defn = hook_defn; 7554640cde1SColin Riley hook->bp_sp = target.CreateBreakpoint(addr, true, false); 7564640cde1SColin Riley hook->bp_sp->SetCallback(HookCallback, hook.get(), true); 7574640cde1SColin Riley m_runtimeHooks[addr] = hook; 7584640cde1SColin Riley if (log) 7594640cde1SColin Riley { 7604640cde1SColin Riley log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Successfully hooked '%s' in '%s' version %" PRIu64 " at 0x%" PRIx64 ".", 7614640cde1SColin Riley hook_defn->name, module->GetFileSpec().GetFilename().AsCString(), (uint64_t)hook_defn->version, (uint64_t)addr); 7624640cde1SColin Riley } 7634640cde1SColin Riley } 7644640cde1SColin Riley } 7654640cde1SColin Riley 7664640cde1SColin Riley void 7674640cde1SColin Riley RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp) 7684640cde1SColin Riley { 7694640cde1SColin Riley if (!rsmodule_sp) 7704640cde1SColin Riley return; 7714640cde1SColin Riley 7724640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 7734640cde1SColin Riley 7744640cde1SColin Riley const ModuleSP module = rsmodule_sp->m_module; 7754640cde1SColin Riley const FileSpec& file = module->GetPlatformFileSpec(); 7764640cde1SColin Riley 77778f339d1SEwan Crawford // Iterate over all of the scripts that we currently know of. 77878f339d1SEwan Crawford // Note: We cant push or pop to m_scripts here or it may invalidate rs_script. 7794640cde1SColin Riley for (const auto & rs_script : m_scripts) 7804640cde1SColin Riley { 78178f339d1SEwan Crawford // Extract the expected .so file path for this script. 78278f339d1SEwan Crawford std::string dylib; 78378f339d1SEwan Crawford if (!rs_script->scriptDyLib.get(dylib)) 78478f339d1SEwan Crawford continue; 78578f339d1SEwan Crawford 78678f339d1SEwan Crawford // Only proceed if the module that has loaded corresponds to this script. 78778f339d1SEwan Crawford if (file.GetFilename() != ConstString(dylib.c_str())) 78878f339d1SEwan Crawford continue; 78978f339d1SEwan Crawford 79078f339d1SEwan Crawford // Obtain the script address which we use as a key. 79178f339d1SEwan Crawford lldb::addr_t script; 79278f339d1SEwan Crawford if (!rs_script->script.get(script)) 79378f339d1SEwan Crawford continue; 79478f339d1SEwan Crawford 79578f339d1SEwan Crawford // If we have a script mapping for the current script. 79678f339d1SEwan Crawford if (m_scriptMappings.find(script) != m_scriptMappings.end()) 7974640cde1SColin Riley { 79878f339d1SEwan Crawford // if the module we have stored is different to the one we just received. 79978f339d1SEwan Crawford if (m_scriptMappings[script] != rsmodule_sp) 8004640cde1SColin Riley { 8014640cde1SColin Riley if (log) 8024640cde1SColin Riley log->Printf ("RenderScriptRuntime::FixupScriptDetails - Error: script %" PRIx64 " wants reassigned to new rsmodule '%s'.", 80378f339d1SEwan Crawford (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString()); 8044640cde1SColin Riley } 8054640cde1SColin Riley } 80678f339d1SEwan Crawford // We don't have a script mapping for the current script. 8074640cde1SColin Riley else 8084640cde1SColin Riley { 80978f339d1SEwan Crawford // Obtain the script resource name. 81078f339d1SEwan Crawford std::string resName; 81178f339d1SEwan Crawford if (rs_script->resName.get(resName)) 81278f339d1SEwan Crawford // Set the modules resource name. 81378f339d1SEwan Crawford rsmodule_sp->m_resname = resName; 81478f339d1SEwan Crawford // Add Script/Module pair to map. 81578f339d1SEwan Crawford m_scriptMappings[script] = rsmodule_sp; 8164640cde1SColin Riley if (log) 8174640cde1SColin Riley log->Printf ("RenderScriptRuntime::FixupScriptDetails - script %" PRIx64 " associated with rsmodule '%s'.", 81878f339d1SEwan Crawford (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString()); 8194640cde1SColin Riley } 8204640cde1SColin Riley } 8214640cde1SColin Riley } 8224640cde1SColin Riley 8235ec532a9SColin Riley bool 8245ec532a9SColin Riley RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp) 8255ec532a9SColin Riley { 8264640cde1SColin Riley Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 8274640cde1SColin Riley 8285ec532a9SColin Riley if (module_sp) 8295ec532a9SColin Riley { 8305ec532a9SColin Riley for (const auto &rs_module : m_rsmodules) 8315ec532a9SColin Riley { 8324640cde1SColin Riley if (rs_module->m_module == module_sp) 8337dc7771cSEwan Crawford { 8347dc7771cSEwan Crawford // Check if the user has enabled automatically breaking on 8357dc7771cSEwan Crawford // all RS kernels. 8367dc7771cSEwan Crawford if (m_breakAllKernels) 8377dc7771cSEwan Crawford BreakOnModuleKernels(rs_module); 8387dc7771cSEwan Crawford 8395ec532a9SColin Riley return false; 8405ec532a9SColin Riley } 8417dc7771cSEwan Crawford } 842ef20b08fSColin Riley bool module_loaded = false; 843ef20b08fSColin Riley switch (GetModuleKind(module_sp)) 844ef20b08fSColin Riley { 845ef20b08fSColin Riley case eModuleKindKernelObj: 846ef20b08fSColin Riley { 8474640cde1SColin Riley RSModuleDescriptorSP module_desc; 8484640cde1SColin Riley module_desc.reset(new RSModuleDescriptor(module_sp)); 8494640cde1SColin Riley if (module_desc->ParseRSInfo()) 8505ec532a9SColin Riley { 8515ec532a9SColin Riley m_rsmodules.push_back(module_desc); 852ef20b08fSColin Riley module_loaded = true; 8535ec532a9SColin Riley } 8544640cde1SColin Riley if (module_loaded) 8554640cde1SColin Riley { 8564640cde1SColin Riley FixupScriptDetails(module_desc); 8574640cde1SColin Riley } 858ef20b08fSColin Riley break; 859ef20b08fSColin Riley } 860ef20b08fSColin Riley case eModuleKindDriver: 8614640cde1SColin Riley { 8624640cde1SColin Riley if (!m_libRSDriver) 8634640cde1SColin Riley { 8644640cde1SColin Riley m_libRSDriver = module_sp; 8654640cde1SColin Riley LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver); 8664640cde1SColin Riley } 8674640cde1SColin Riley break; 8684640cde1SColin Riley } 869ef20b08fSColin Riley case eModuleKindImpl: 8704640cde1SColin Riley { 8714640cde1SColin Riley m_libRSCpuRef = module_sp; 8724640cde1SColin Riley break; 8734640cde1SColin Riley } 874ef20b08fSColin Riley case eModuleKindLibRS: 8754640cde1SColin Riley { 8764640cde1SColin Riley if (!m_libRS) 8774640cde1SColin Riley { 8784640cde1SColin Riley m_libRS = module_sp; 8794640cde1SColin Riley static ConstString gDbgPresentStr("gDebuggerPresent"); 8804640cde1SColin Riley const Symbol* debug_present = m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData); 8814640cde1SColin Riley if (debug_present) 8824640cde1SColin Riley { 8834640cde1SColin Riley Error error; 8844640cde1SColin Riley uint32_t flag = 0x00000001U; 8854640cde1SColin Riley Target &target = GetProcess()->GetTarget(); 886358cf1eaSGreg Clayton addr_t addr = debug_present->GetLoadAddress(&target); 8874640cde1SColin Riley GetProcess()->WriteMemory(addr, &flag, sizeof(flag), error); 8884640cde1SColin Riley if(error.Success()) 8894640cde1SColin Riley { 8904640cde1SColin Riley if (log) 8914640cde1SColin Riley log->Printf ("RenderScriptRuntime::LoadModule - Debugger present flag set on debugee"); 8924640cde1SColin Riley 8934640cde1SColin Riley m_debuggerPresentFlagged = true; 8944640cde1SColin Riley } 8954640cde1SColin Riley else if (log) 8964640cde1SColin Riley { 8974640cde1SColin Riley log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags '%s' ", error.AsCString()); 8984640cde1SColin Riley } 8994640cde1SColin Riley } 9004640cde1SColin Riley else if (log) 9014640cde1SColin Riley { 9024640cde1SColin Riley log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags - symbol not found"); 9034640cde1SColin Riley } 9044640cde1SColin Riley } 9054640cde1SColin Riley break; 9064640cde1SColin Riley } 907ef20b08fSColin Riley default: 908ef20b08fSColin Riley break; 909ef20b08fSColin Riley } 910ef20b08fSColin Riley if (module_loaded) 911ef20b08fSColin Riley Update(); 912ef20b08fSColin Riley return module_loaded; 9135ec532a9SColin Riley } 9145ec532a9SColin Riley return false; 9155ec532a9SColin Riley } 9165ec532a9SColin Riley 917ef20b08fSColin Riley void 918ef20b08fSColin Riley RenderScriptRuntime::Update() 919ef20b08fSColin Riley { 920ef20b08fSColin Riley if (m_rsmodules.size() > 0) 921ef20b08fSColin Riley { 922ef20b08fSColin Riley if (!m_initiated) 923ef20b08fSColin Riley { 924ef20b08fSColin Riley Initiate(); 925ef20b08fSColin Riley } 926ef20b08fSColin Riley } 927ef20b08fSColin Riley } 928ef20b08fSColin Riley 929ef20b08fSColin Riley 9305ec532a9SColin Riley // The maximum line length of an .rs.info packet 9315ec532a9SColin Riley #define MAXLINE 500 9325ec532a9SColin Riley 9335ec532a9SColin Riley // The .rs.info symbol in renderscript modules contains a string which needs to be parsed. 9345ec532a9SColin Riley // The string is basic and is parsed on a line by line basis. 9355ec532a9SColin Riley bool 9365ec532a9SColin Riley RSModuleDescriptor::ParseRSInfo() 9375ec532a9SColin Riley { 9385ec532a9SColin Riley const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData); 9395ec532a9SColin Riley if (info_sym) 9405ec532a9SColin Riley { 941358cf1eaSGreg Clayton const addr_t addr = info_sym->GetAddressRef().GetFileAddress(); 9425ec532a9SColin Riley const addr_t size = info_sym->GetByteSize(); 9435ec532a9SColin Riley const FileSpec fs = m_module->GetFileSpec(); 9445ec532a9SColin Riley 9455ec532a9SColin Riley DataBufferSP buffer = fs.ReadFileContents(addr, size); 9465ec532a9SColin Riley 9475ec532a9SColin Riley if (!buffer) 9485ec532a9SColin Riley return false; 9495ec532a9SColin Riley 9505ec532a9SColin Riley std::string info((const char *)buffer->GetBytes()); 9515ec532a9SColin Riley 9525ec532a9SColin Riley std::vector<std::string> info_lines; 953e8433cc1SBruce Mitchener size_t lpos = info.find('\n'); 9545ec532a9SColin Riley while (lpos != std::string::npos) 9555ec532a9SColin Riley { 9565ec532a9SColin Riley info_lines.push_back(info.substr(0, lpos)); 9575ec532a9SColin Riley info = info.substr(lpos + 1); 958e8433cc1SBruce Mitchener lpos = info.find('\n'); 9595ec532a9SColin Riley } 9605ec532a9SColin Riley size_t offset = 0; 9615ec532a9SColin Riley while (offset < info_lines.size()) 9625ec532a9SColin Riley { 9635ec532a9SColin Riley std::string line = info_lines[offset]; 9645ec532a9SColin Riley // Parse directives 9655ec532a9SColin Riley uint32_t numDefns = 0; 9665ec532a9SColin Riley if (sscanf(line.c_str(), "exportVarCount: %u", &numDefns) == 1) 9675ec532a9SColin Riley { 9685ec532a9SColin Riley while (numDefns--) 9694640cde1SColin Riley m_globals.push_back(RSGlobalDescriptor(this, info_lines[++offset].c_str())); 9705ec532a9SColin Riley } 9715ec532a9SColin Riley else if (sscanf(line.c_str(), "exportFuncCount: %u", &numDefns) == 1) 9725ec532a9SColin Riley { 9735ec532a9SColin Riley } 9745ec532a9SColin Riley else if (sscanf(line.c_str(), "exportForEachCount: %u", &numDefns) == 1) 9755ec532a9SColin Riley { 9765ec532a9SColin Riley char name[MAXLINE]; 9775ec532a9SColin Riley while (numDefns--) 9785ec532a9SColin Riley { 9795ec532a9SColin Riley uint32_t slot = 0; 9805ec532a9SColin Riley name[0] = '\0'; 9815ec532a9SColin Riley if (sscanf(info_lines[++offset].c_str(), "%u - %s", &slot, &name[0]) == 2) 9825ec532a9SColin Riley { 9834640cde1SColin Riley m_kernels.push_back(RSKernelDescriptor(this, name, slot)); 9844640cde1SColin Riley } 9854640cde1SColin Riley } 9864640cde1SColin Riley } 9874640cde1SColin Riley else if (sscanf(line.c_str(), "pragmaCount: %u", &numDefns) == 1) 9884640cde1SColin Riley { 9894640cde1SColin Riley char name[MAXLINE]; 9904640cde1SColin Riley char value[MAXLINE]; 9914640cde1SColin Riley while (numDefns--) 9924640cde1SColin Riley { 9934640cde1SColin Riley name[0] = '\0'; 9944640cde1SColin Riley value[0] = '\0'; 9954640cde1SColin Riley if (sscanf(info_lines[++offset].c_str(), "%s - %s", &name[0], &value[0]) != 0 9964640cde1SColin Riley && (name[0] != '\0')) 9974640cde1SColin Riley { 9984640cde1SColin Riley m_pragmas[std::string(name)] = value; 9995ec532a9SColin Riley } 10005ec532a9SColin Riley } 10015ec532a9SColin Riley } 10025ec532a9SColin Riley else if (sscanf(line.c_str(), "objectSlotCount: %u", &numDefns) == 1) 10035ec532a9SColin Riley { 10045ec532a9SColin Riley } 10055ec532a9SColin Riley 10065ec532a9SColin Riley offset++; 10075ec532a9SColin Riley } 10085ec532a9SColin Riley return m_kernels.size() > 0; 10095ec532a9SColin Riley } 10105ec532a9SColin Riley return false; 10115ec532a9SColin Riley } 10125ec532a9SColin Riley 10135ec532a9SColin Riley bool 10145ec532a9SColin Riley RenderScriptRuntime::ProbeModules(const ModuleList module_list) 10155ec532a9SColin Riley { 10165ec532a9SColin Riley bool rs_found = false; 10175ec532a9SColin Riley size_t num_modules = module_list.GetSize(); 10185ec532a9SColin Riley for (size_t i = 0; i < num_modules; i++) 10195ec532a9SColin Riley { 10205ec532a9SColin Riley auto module = module_list.GetModuleAtIndex(i); 10215ec532a9SColin Riley rs_found |= LoadModule(module); 10225ec532a9SColin Riley } 10235ec532a9SColin Riley return rs_found; 10245ec532a9SColin Riley } 10255ec532a9SColin Riley 10265ec532a9SColin Riley void 10274640cde1SColin Riley RenderScriptRuntime::Status(Stream &strm) const 10284640cde1SColin Riley { 10294640cde1SColin Riley if (m_libRS) 10304640cde1SColin Riley { 10314640cde1SColin Riley strm.Printf("Runtime Library discovered."); 10324640cde1SColin Riley strm.EOL(); 10334640cde1SColin Riley } 10344640cde1SColin Riley if (m_libRSDriver) 10354640cde1SColin Riley { 10364640cde1SColin Riley strm.Printf("Runtime Driver discovered."); 10374640cde1SColin Riley strm.EOL(); 10384640cde1SColin Riley } 10394640cde1SColin Riley if (m_libRSCpuRef) 10404640cde1SColin Riley { 10414640cde1SColin Riley strm.Printf("CPU Reference Implementation discovered."); 10424640cde1SColin Riley strm.EOL(); 10434640cde1SColin Riley } 10444640cde1SColin Riley 10454640cde1SColin Riley if (m_runtimeHooks.size()) 10464640cde1SColin Riley { 10474640cde1SColin Riley strm.Printf("Runtime functions hooked:"); 10484640cde1SColin Riley strm.EOL(); 10494640cde1SColin Riley for (auto b : m_runtimeHooks) 10504640cde1SColin Riley { 10514640cde1SColin Riley strm.Indent(b.second->defn->name); 10524640cde1SColin Riley strm.EOL(); 10534640cde1SColin Riley } 10544640cde1SColin Riley strm.EOL(); 10554640cde1SColin Riley } 10564640cde1SColin Riley else 10574640cde1SColin Riley { 10584640cde1SColin Riley strm.Printf("Runtime is not hooked."); 10594640cde1SColin Riley strm.EOL(); 10604640cde1SColin Riley } 10614640cde1SColin Riley } 10624640cde1SColin Riley 10634640cde1SColin Riley void 10644640cde1SColin Riley RenderScriptRuntime::DumpContexts(Stream &strm) const 10654640cde1SColin Riley { 10664640cde1SColin Riley strm.Printf("Inferred RenderScript Contexts:"); 10674640cde1SColin Riley strm.EOL(); 10684640cde1SColin Riley strm.IndentMore(); 10694640cde1SColin Riley 10704640cde1SColin Riley std::map<addr_t, uint64_t> contextReferences; 10714640cde1SColin Riley 107278f339d1SEwan Crawford // Iterate over all of the currently discovered scripts. 107378f339d1SEwan Crawford // Note: We cant push or pop from m_scripts inside this loop or it may invalidate script. 10744640cde1SColin Riley for (const auto & script : m_scripts) 10754640cde1SColin Riley { 107678f339d1SEwan Crawford if (!script->context.isValid()) 107778f339d1SEwan Crawford continue; 107878f339d1SEwan Crawford lldb::addr_t context = *script->context; 107978f339d1SEwan Crawford 108078f339d1SEwan Crawford if (contextReferences.find(context) != contextReferences.end()) 10814640cde1SColin Riley { 108278f339d1SEwan Crawford contextReferences[context]++; 10834640cde1SColin Riley } 10844640cde1SColin Riley else 10854640cde1SColin Riley { 108678f339d1SEwan Crawford contextReferences[context] = 1; 10874640cde1SColin Riley } 10884640cde1SColin Riley } 10894640cde1SColin Riley 10904640cde1SColin Riley for (const auto& cRef : contextReferences) 10914640cde1SColin Riley { 10924640cde1SColin Riley strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances", cRef.first, cRef.second); 10934640cde1SColin Riley strm.EOL(); 10944640cde1SColin Riley } 10954640cde1SColin Riley strm.IndentLess(); 10964640cde1SColin Riley } 10974640cde1SColin Riley 10984640cde1SColin Riley void 10994640cde1SColin Riley RenderScriptRuntime::DumpKernels(Stream &strm) const 11004640cde1SColin Riley { 11014640cde1SColin Riley strm.Printf("RenderScript Kernels:"); 11024640cde1SColin Riley strm.EOL(); 11034640cde1SColin Riley strm.IndentMore(); 11044640cde1SColin Riley for (const auto &module : m_rsmodules) 11054640cde1SColin Riley { 11064640cde1SColin Riley strm.Printf("Resource '%s':",module->m_resname.c_str()); 11074640cde1SColin Riley strm.EOL(); 11084640cde1SColin Riley for (const auto &kernel : module->m_kernels) 11094640cde1SColin Riley { 11104640cde1SColin Riley strm.Indent(kernel.m_name.AsCString()); 11114640cde1SColin Riley strm.EOL(); 11124640cde1SColin Riley } 11134640cde1SColin Riley } 11144640cde1SColin Riley strm.IndentLess(); 11154640cde1SColin Riley } 11164640cde1SColin Riley 11177dc7771cSEwan Crawford // Set breakpoints on every kernel found in RS module 11187dc7771cSEwan Crawford void 11197dc7771cSEwan Crawford RenderScriptRuntime::BreakOnModuleKernels(const RSModuleDescriptorSP rsmodule_sp) 11207dc7771cSEwan Crawford { 11217dc7771cSEwan Crawford for (const auto &kernel : rsmodule_sp->m_kernels) 11227dc7771cSEwan Crawford { 11237dc7771cSEwan Crawford // Don't set breakpoint on 'root' kernel 11247dc7771cSEwan Crawford if (strcmp(kernel.m_name.AsCString(), "root") == 0) 11257dc7771cSEwan Crawford continue; 11267dc7771cSEwan Crawford 11277dc7771cSEwan Crawford CreateKernelBreakpoint(kernel.m_name); 11287dc7771cSEwan Crawford } 11297dc7771cSEwan Crawford } 11307dc7771cSEwan Crawford 11317dc7771cSEwan Crawford // Method is internally called by the 'kernel breakpoint all' command to 11327dc7771cSEwan Crawford // enable or disable breaking on all kernels. 11337dc7771cSEwan Crawford // 11347dc7771cSEwan Crawford // When do_break is true we want to enable this functionality. 11357dc7771cSEwan Crawford // When do_break is false we want to disable it. 11367dc7771cSEwan Crawford void 11377dc7771cSEwan Crawford RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target) 11387dc7771cSEwan Crawford { 113954782db7SEwan Crawford Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS)); 11407dc7771cSEwan Crawford 11417dc7771cSEwan Crawford InitSearchFilter(target); 11427dc7771cSEwan Crawford 11437dc7771cSEwan Crawford // Set breakpoints on all the kernels 11447dc7771cSEwan Crawford if (do_break && !m_breakAllKernels) 11457dc7771cSEwan Crawford { 11467dc7771cSEwan Crawford m_breakAllKernels = true; 11477dc7771cSEwan Crawford 11487dc7771cSEwan Crawford for (const auto &module : m_rsmodules) 11497dc7771cSEwan Crawford BreakOnModuleKernels(module); 11507dc7771cSEwan Crawford 11517dc7771cSEwan Crawford if (log) 11527dc7771cSEwan Crawford log->Printf("RenderScriptRuntime::SetBreakAllKernels(True)" 11537dc7771cSEwan Crawford "- breakpoints set on all currently loaded kernels"); 11547dc7771cSEwan Crawford } 11557dc7771cSEwan Crawford else if (!do_break && m_breakAllKernels) // Breakpoints won't be set on any new kernels. 11567dc7771cSEwan Crawford { 11577dc7771cSEwan Crawford m_breakAllKernels = false; 11587dc7771cSEwan Crawford 11597dc7771cSEwan Crawford if (log) 11607dc7771cSEwan Crawford log->Printf("RenderScriptRuntime::SetBreakAllKernels(False) - breakpoints no longer automatically set"); 11617dc7771cSEwan Crawford } 11627dc7771cSEwan Crawford } 11637dc7771cSEwan Crawford 11647dc7771cSEwan Crawford // Given the name of a kernel this function creates a breakpoint using our 11657dc7771cSEwan Crawford // own breakpoint resolver, and returns the Breakpoint shared pointer. 11667dc7771cSEwan Crawford BreakpointSP 11677dc7771cSEwan Crawford RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name) 11687dc7771cSEwan Crawford { 116954782db7SEwan Crawford Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS)); 11707dc7771cSEwan Crawford 11717dc7771cSEwan Crawford if (!m_filtersp) 11727dc7771cSEwan Crawford { 11737dc7771cSEwan Crawford if (log) 11747dc7771cSEwan Crawford log->Printf("RenderScriptRuntime::CreateKernelBreakpoint - Error: No breakpoint search filter set"); 11757dc7771cSEwan Crawford return nullptr; 11767dc7771cSEwan Crawford } 11777dc7771cSEwan Crawford 11787dc7771cSEwan Crawford BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name)); 11797dc7771cSEwan Crawford BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(m_filtersp, resolver_sp, false, false, false); 11807dc7771cSEwan Crawford 118154782db7SEwan Crawford // Give RS breakpoints a specific name, so the user can manipulate them as a group. 118254782db7SEwan Crawford Error err; 118354782db7SEwan Crawford if (!bp->AddName("RenderScriptKernel", err) && log) 118454782db7SEwan Crawford log->Printf("RenderScriptRuntime::CreateKernelBreakpoint: Error setting break name, %s", err.AsCString()); 118554782db7SEwan Crawford 11867dc7771cSEwan Crawford return bp; 11877dc7771cSEwan Crawford } 11887dc7771cSEwan Crawford 11894640cde1SColin Riley void 119098156583SEwan Crawford RenderScriptRuntime::AttemptBreakpointAtKernelName(Stream &strm, const char* name, Error& error, TargetSP target) 11914640cde1SColin Riley { 11924640cde1SColin Riley if (!name) 11934640cde1SColin Riley { 11944640cde1SColin Riley error.SetErrorString("invalid kernel name"); 11954640cde1SColin Riley return; 11964640cde1SColin Riley } 11974640cde1SColin Riley 11987dc7771cSEwan Crawford InitSearchFilter(target); 119998156583SEwan Crawford 12004640cde1SColin Riley ConstString kernel_name(name); 12017dc7771cSEwan Crawford BreakpointSP bp = CreateKernelBreakpoint(kernel_name); 120298156583SEwan Crawford if (bp) 120398156583SEwan Crawford bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false); 12044640cde1SColin Riley 12054640cde1SColin Riley return; 12064640cde1SColin Riley } 12074640cde1SColin Riley 12084640cde1SColin Riley void 12095ec532a9SColin Riley RenderScriptRuntime::DumpModules(Stream &strm) const 12105ec532a9SColin Riley { 12115ec532a9SColin Riley strm.Printf("RenderScript Modules:"); 12125ec532a9SColin Riley strm.EOL(); 12135ec532a9SColin Riley strm.IndentMore(); 12145ec532a9SColin Riley for (const auto &module : m_rsmodules) 12155ec532a9SColin Riley { 12164640cde1SColin Riley module->Dump(strm); 12175ec532a9SColin Riley } 12185ec532a9SColin Riley strm.IndentLess(); 12195ec532a9SColin Riley } 12205ec532a9SColin Riley 122178f339d1SEwan Crawford RenderScriptRuntime::ScriptDetails* 122278f339d1SEwan Crawford RenderScriptRuntime::LookUpScript(addr_t address, bool create) 122378f339d1SEwan Crawford { 122478f339d1SEwan Crawford for (const auto & s : m_scripts) 122578f339d1SEwan Crawford { 122678f339d1SEwan Crawford if (s->script.isValid()) 122778f339d1SEwan Crawford if (*s->script == address) 122878f339d1SEwan Crawford return s.get(); 122978f339d1SEwan Crawford } 123078f339d1SEwan Crawford if (create) 123178f339d1SEwan Crawford { 123278f339d1SEwan Crawford std::unique_ptr<ScriptDetails> s(new ScriptDetails); 123378f339d1SEwan Crawford s->script = address; 123478f339d1SEwan Crawford m_scripts.push_back(std::move(s)); 1235d10ca9deSEwan Crawford return m_scripts.back().get(); 123678f339d1SEwan Crawford } 123778f339d1SEwan Crawford return nullptr; 123878f339d1SEwan Crawford } 123978f339d1SEwan Crawford 124078f339d1SEwan Crawford RenderScriptRuntime::AllocationDetails* 124178f339d1SEwan Crawford RenderScriptRuntime::LookUpAllocation(addr_t address, bool create) 124278f339d1SEwan Crawford { 124378f339d1SEwan Crawford for (const auto & a : m_allocations) 124478f339d1SEwan Crawford { 124578f339d1SEwan Crawford if (a->address.isValid()) 124678f339d1SEwan Crawford if (*a->address == address) 124778f339d1SEwan Crawford return a.get(); 124878f339d1SEwan Crawford } 124978f339d1SEwan Crawford if (create) 125078f339d1SEwan Crawford { 125178f339d1SEwan Crawford std::unique_ptr<AllocationDetails> a(new AllocationDetails); 125278f339d1SEwan Crawford a->address = address; 125378f339d1SEwan Crawford m_allocations.push_back(std::move(a)); 1254d10ca9deSEwan Crawford return m_allocations.back().get(); 125578f339d1SEwan Crawford } 125678f339d1SEwan Crawford return nullptr; 125778f339d1SEwan Crawford } 125878f339d1SEwan Crawford 12595ec532a9SColin Riley void 12605ec532a9SColin Riley RSModuleDescriptor::Dump(Stream &strm) const 12615ec532a9SColin Riley { 12625ec532a9SColin Riley strm.Indent(); 12635ec532a9SColin Riley m_module->GetFileSpec().Dump(&strm); 12644640cde1SColin Riley if(m_module->GetNumCompileUnits()) 12654640cde1SColin Riley { 12664640cde1SColin Riley strm.Indent("Debug info loaded."); 12674640cde1SColin Riley } 12684640cde1SColin Riley else 12694640cde1SColin Riley { 12704640cde1SColin Riley strm.Indent("Debug info does not exist."); 12714640cde1SColin Riley } 12725ec532a9SColin Riley strm.EOL(); 12735ec532a9SColin Riley strm.IndentMore(); 12745ec532a9SColin Riley strm.Indent(); 1275189598edSColin Riley strm.Printf("Globals: %" PRIu64, static_cast<uint64_t>(m_globals.size())); 12765ec532a9SColin Riley strm.EOL(); 12775ec532a9SColin Riley strm.IndentMore(); 12785ec532a9SColin Riley for (const auto &global : m_globals) 12795ec532a9SColin Riley { 12805ec532a9SColin Riley global.Dump(strm); 12815ec532a9SColin Riley } 12825ec532a9SColin Riley strm.IndentLess(); 12835ec532a9SColin Riley strm.Indent(); 1284189598edSColin Riley strm.Printf("Kernels: %" PRIu64, static_cast<uint64_t>(m_kernels.size())); 12855ec532a9SColin Riley strm.EOL(); 12865ec532a9SColin Riley strm.IndentMore(); 12875ec532a9SColin Riley for (const auto &kernel : m_kernels) 12885ec532a9SColin Riley { 12895ec532a9SColin Riley kernel.Dump(strm); 12905ec532a9SColin Riley } 12914640cde1SColin Riley strm.Printf("Pragmas: %" PRIu64 , static_cast<uint64_t>(m_pragmas.size())); 12924640cde1SColin Riley strm.EOL(); 12934640cde1SColin Riley strm.IndentMore(); 12944640cde1SColin Riley for (const auto &key_val : m_pragmas) 12954640cde1SColin Riley { 12964640cde1SColin Riley strm.Printf("%s: %s", key_val.first.c_str(), key_val.second.c_str()); 12974640cde1SColin Riley strm.EOL(); 12984640cde1SColin Riley } 12995ec532a9SColin Riley strm.IndentLess(4); 13005ec532a9SColin Riley } 13015ec532a9SColin Riley 13025ec532a9SColin Riley void 13035ec532a9SColin Riley RSGlobalDescriptor::Dump(Stream &strm) const 13045ec532a9SColin Riley { 13055ec532a9SColin Riley strm.Indent(m_name.AsCString()); 13064640cde1SColin Riley VariableList var_list; 13074640cde1SColin Riley m_module->m_module->FindGlobalVariables(m_name, nullptr, true, 1U, var_list); 13084640cde1SColin Riley if (var_list.GetSize() == 1) 13094640cde1SColin Riley { 13104640cde1SColin Riley auto var = var_list.GetVariableAtIndex(0); 13114640cde1SColin Riley auto type = var->GetType(); 13124640cde1SColin Riley if(type) 13134640cde1SColin Riley { 13144640cde1SColin Riley strm.Printf(" - "); 13154640cde1SColin Riley type->DumpTypeName(&strm); 13164640cde1SColin Riley } 13174640cde1SColin Riley else 13184640cde1SColin Riley { 13194640cde1SColin Riley strm.Printf(" - Unknown Type"); 13204640cde1SColin Riley } 13214640cde1SColin Riley } 13224640cde1SColin Riley else 13234640cde1SColin Riley { 13244640cde1SColin Riley strm.Printf(" - variable identified, but not found in binary"); 13254640cde1SColin Riley const Symbol* s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData); 13264640cde1SColin Riley if (s) 13274640cde1SColin Riley { 13284640cde1SColin Riley strm.Printf(" (symbol exists) "); 13294640cde1SColin Riley } 13304640cde1SColin Riley } 13314640cde1SColin Riley 13325ec532a9SColin Riley strm.EOL(); 13335ec532a9SColin Riley } 13345ec532a9SColin Riley 13355ec532a9SColin Riley void 13365ec532a9SColin Riley RSKernelDescriptor::Dump(Stream &strm) const 13375ec532a9SColin Riley { 13385ec532a9SColin Riley strm.Indent(m_name.AsCString()); 13395ec532a9SColin Riley strm.EOL(); 13405ec532a9SColin Riley } 13415ec532a9SColin Riley 13425ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed 13435ec532a9SColin Riley { 13445ec532a9SColin Riley private: 13455ec532a9SColin Riley public: 13465ec532a9SColin Riley CommandObjectRenderScriptRuntimeModuleProbe(CommandInterpreter &interpreter) 13475ec532a9SColin Riley : CommandObjectParsed(interpreter, "renderscript module probe", 13485ec532a9SColin Riley "Initiates a Probe of all loaded modules for kernels and other renderscript objects.", 13495ec532a9SColin Riley "renderscript module probe", 1350e87764f2SEnrico Granata eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBeLaunched) 13515ec532a9SColin Riley { 13525ec532a9SColin Riley } 13535ec532a9SColin Riley 13545ec532a9SColin Riley ~CommandObjectRenderScriptRuntimeModuleProbe() {} 13555ec532a9SColin Riley 13565ec532a9SColin Riley bool 13575ec532a9SColin Riley DoExecute(Args &command, CommandReturnObject &result) 13585ec532a9SColin Riley { 13595ec532a9SColin Riley const size_t argc = command.GetArgumentCount(); 13605ec532a9SColin Riley if (argc == 0) 13615ec532a9SColin Riley { 13625ec532a9SColin Riley Target *target = m_exe_ctx.GetTargetPtr(); 13635ec532a9SColin Riley RenderScriptRuntime *runtime = 13645ec532a9SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 13655ec532a9SColin Riley auto module_list = target->GetImages(); 13665ec532a9SColin Riley bool new_rs_details = runtime->ProbeModules(module_list); 13675ec532a9SColin Riley if (new_rs_details) 13685ec532a9SColin Riley { 13695ec532a9SColin Riley result.AppendMessage("New renderscript modules added to runtime model."); 13705ec532a9SColin Riley } 13715ec532a9SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 13725ec532a9SColin Riley return true; 13735ec532a9SColin Riley } 13745ec532a9SColin Riley 13755ec532a9SColin Riley result.AppendErrorWithFormat("'%s' takes no arguments", m_cmd_name.c_str()); 13765ec532a9SColin Riley result.SetStatus(eReturnStatusFailed); 13775ec532a9SColin Riley return false; 13785ec532a9SColin Riley } 13795ec532a9SColin Riley }; 13805ec532a9SColin Riley 13815ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed 13825ec532a9SColin Riley { 13835ec532a9SColin Riley private: 13845ec532a9SColin Riley public: 13855ec532a9SColin Riley CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter) 13865ec532a9SColin Riley : CommandObjectParsed(interpreter, "renderscript module dump", 13875ec532a9SColin Riley "Dumps renderscript specific information for all modules.", "renderscript module dump", 1388e87764f2SEnrico Granata eCommandRequiresProcess | eCommandProcessMustBeLaunched) 13895ec532a9SColin Riley { 13905ec532a9SColin Riley } 13915ec532a9SColin Riley 13925ec532a9SColin Riley ~CommandObjectRenderScriptRuntimeModuleDump() {} 13935ec532a9SColin Riley 13945ec532a9SColin Riley bool 13955ec532a9SColin Riley DoExecute(Args &command, CommandReturnObject &result) 13965ec532a9SColin Riley { 13975ec532a9SColin Riley RenderScriptRuntime *runtime = 13985ec532a9SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 13995ec532a9SColin Riley runtime->DumpModules(result.GetOutputStream()); 14005ec532a9SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 14015ec532a9SColin Riley return true; 14025ec532a9SColin Riley } 14035ec532a9SColin Riley }; 14045ec532a9SColin Riley 14055ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword 14065ec532a9SColin Riley { 14075ec532a9SColin Riley private: 14085ec532a9SColin Riley public: 14095ec532a9SColin Riley CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter) 14105ec532a9SColin Riley : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with renderscript modules.", 14115ec532a9SColin Riley NULL) 14125ec532a9SColin Riley { 14135ec532a9SColin Riley LoadSubCommand("probe", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleProbe(interpreter))); 14145ec532a9SColin Riley LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter))); 14155ec532a9SColin Riley } 14165ec532a9SColin Riley 14175ec532a9SColin Riley ~CommandObjectRenderScriptRuntimeModule() {} 14185ec532a9SColin Riley }; 14195ec532a9SColin Riley 14204640cde1SColin Riley class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed 14214640cde1SColin Riley { 14224640cde1SColin Riley private: 14234640cde1SColin Riley public: 14244640cde1SColin Riley CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter) 14254640cde1SColin Riley : CommandObjectParsed(interpreter, "renderscript kernel list", 14264640cde1SColin Riley "Lists renderscript kernel names and associated script resources.", "renderscript kernel list", 14274640cde1SColin Riley eCommandRequiresProcess | eCommandProcessMustBeLaunched) 14284640cde1SColin Riley { 14294640cde1SColin Riley } 14304640cde1SColin Riley 14314640cde1SColin Riley ~CommandObjectRenderScriptRuntimeKernelList() {} 14324640cde1SColin Riley 14334640cde1SColin Riley bool 14344640cde1SColin Riley DoExecute(Args &command, CommandReturnObject &result) 14354640cde1SColin Riley { 14364640cde1SColin Riley RenderScriptRuntime *runtime = 14374640cde1SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 14384640cde1SColin Riley runtime->DumpKernels(result.GetOutputStream()); 14394640cde1SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 14404640cde1SColin Riley return true; 14414640cde1SColin Riley } 14424640cde1SColin Riley }; 14434640cde1SColin Riley 14447dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpointSet : public CommandObjectParsed 14454640cde1SColin Riley { 14464640cde1SColin Riley private: 14474640cde1SColin Riley public: 14487dc7771cSEwan Crawford CommandObjectRenderScriptRuntimeKernelBreakpointSet(CommandInterpreter &interpreter) 14497dc7771cSEwan Crawford : CommandObjectParsed(interpreter, "renderscript kernel breakpoint set", 14507dc7771cSEwan Crawford "Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint set <kernel_name>", 14514640cde1SColin Riley eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) 14524640cde1SColin Riley { 14534640cde1SColin Riley } 14544640cde1SColin Riley 14557dc7771cSEwan Crawford ~CommandObjectRenderScriptRuntimeKernelBreakpointSet() {} 14564640cde1SColin Riley 14574640cde1SColin Riley bool 14584640cde1SColin Riley DoExecute(Args &command, CommandReturnObject &result) 14594640cde1SColin Riley { 14604640cde1SColin Riley const size_t argc = command.GetArgumentCount(); 14614640cde1SColin Riley if (argc == 1) 14624640cde1SColin Riley { 14634640cde1SColin Riley RenderScriptRuntime *runtime = 14644640cde1SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 14654640cde1SColin Riley 14664640cde1SColin Riley Error error; 146798156583SEwan Crawford runtime->AttemptBreakpointAtKernelName(result.GetOutputStream(), command.GetArgumentAtIndex(0), 146898156583SEwan Crawford error, m_exe_ctx.GetTargetSP()); 14694640cde1SColin Riley 14704640cde1SColin Riley if (error.Success()) 14714640cde1SColin Riley { 14724640cde1SColin Riley result.AppendMessage("Breakpoint(s) created"); 14734640cde1SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 14744640cde1SColin Riley return true; 14754640cde1SColin Riley } 14764640cde1SColin Riley result.SetStatus(eReturnStatusFailed); 14774640cde1SColin Riley result.AppendErrorWithFormat("Error: %s", error.AsCString()); 14784640cde1SColin Riley return false; 14794640cde1SColin Riley } 14804640cde1SColin Riley 14814640cde1SColin Riley result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name", m_cmd_name.c_str()); 14824640cde1SColin Riley result.SetStatus(eReturnStatusFailed); 14834640cde1SColin Riley return false; 14844640cde1SColin Riley } 14854640cde1SColin Riley }; 14864640cde1SColin Riley 14877dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpointAll : public CommandObjectParsed 14887dc7771cSEwan Crawford { 14897dc7771cSEwan Crawford private: 14907dc7771cSEwan Crawford public: 14917dc7771cSEwan Crawford CommandObjectRenderScriptRuntimeKernelBreakpointAll(CommandInterpreter &interpreter) 14927dc7771cSEwan Crawford : CommandObjectParsed(interpreter, "renderscript kernel breakpoint all", 14937dc7771cSEwan Crawford "Automatically sets a breakpoint on all renderscript kernels that are or will be loaded.\n" 14947dc7771cSEwan Crawford "Disabling option means breakpoints will no longer be set on any kernels loaded in the future, " 14957dc7771cSEwan Crawford "but does not remove currently set breakpoints.", 14967dc7771cSEwan Crawford "renderscript kernel breakpoint all <enable/disable>", 14977dc7771cSEwan Crawford eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) 14987dc7771cSEwan Crawford { 14997dc7771cSEwan Crawford } 15007dc7771cSEwan Crawford 15017dc7771cSEwan Crawford ~CommandObjectRenderScriptRuntimeKernelBreakpointAll() {} 15027dc7771cSEwan Crawford 15037dc7771cSEwan Crawford bool 15047dc7771cSEwan Crawford DoExecute(Args &command, CommandReturnObject &result) 15057dc7771cSEwan Crawford { 15067dc7771cSEwan Crawford const size_t argc = command.GetArgumentCount(); 15077dc7771cSEwan Crawford if (argc != 1) 15087dc7771cSEwan Crawford { 15097dc7771cSEwan Crawford result.AppendErrorWithFormat("'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str()); 15107dc7771cSEwan Crawford result.SetStatus(eReturnStatusFailed); 15117dc7771cSEwan Crawford return false; 15127dc7771cSEwan Crawford } 15137dc7771cSEwan Crawford 15147dc7771cSEwan Crawford RenderScriptRuntime *runtime = 15157dc7771cSEwan Crawford static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript)); 15167dc7771cSEwan Crawford 15177dc7771cSEwan Crawford bool do_break = false; 15187dc7771cSEwan Crawford const char* argument = command.GetArgumentAtIndex(0); 15197dc7771cSEwan Crawford if (strcmp(argument, "enable") == 0) 15207dc7771cSEwan Crawford { 15217dc7771cSEwan Crawford do_break = true; 15227dc7771cSEwan Crawford result.AppendMessage("Breakpoints will be set on all kernels."); 15237dc7771cSEwan Crawford } 15247dc7771cSEwan Crawford else if (strcmp(argument, "disable") == 0) 15257dc7771cSEwan Crawford { 15267dc7771cSEwan Crawford do_break = false; 15277dc7771cSEwan Crawford result.AppendMessage("Breakpoints will not be set on any new kernels."); 15287dc7771cSEwan Crawford } 15297dc7771cSEwan Crawford else 15307dc7771cSEwan Crawford { 15317dc7771cSEwan Crawford result.AppendErrorWithFormat("Argument must be either 'enable' or 'disable'"); 15327dc7771cSEwan Crawford result.SetStatus(eReturnStatusFailed); 15337dc7771cSEwan Crawford return false; 15347dc7771cSEwan Crawford } 15357dc7771cSEwan Crawford 15367dc7771cSEwan Crawford runtime->SetBreakAllKernels(do_break, m_exe_ctx.GetTargetSP()); 15377dc7771cSEwan Crawford 15387dc7771cSEwan Crawford result.SetStatus(eReturnStatusSuccessFinishResult); 15397dc7771cSEwan Crawford return true; 15407dc7771cSEwan Crawford } 15417dc7771cSEwan Crawford }; 15427dc7771cSEwan Crawford 15437dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectMultiword 15447dc7771cSEwan Crawford { 15457dc7771cSEwan Crawford private: 15467dc7771cSEwan Crawford public: 15477dc7771cSEwan Crawford CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter) 15487dc7771cSEwan Crawford : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that generate breakpoints on renderscript kernels.", 15497dc7771cSEwan Crawford nullptr) 15507dc7771cSEwan Crawford { 15517dc7771cSEwan Crawford LoadSubCommand("set", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointSet(interpreter))); 15527dc7771cSEwan Crawford LoadSubCommand("all", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointAll(interpreter))); 15537dc7771cSEwan Crawford } 15547dc7771cSEwan Crawford 15557dc7771cSEwan Crawford ~CommandObjectRenderScriptRuntimeKernelBreakpoint() {} 15567dc7771cSEwan Crawford }; 15577dc7771cSEwan Crawford 15584640cde1SColin Riley class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword 15594640cde1SColin Riley { 15604640cde1SColin Riley private: 15614640cde1SColin Riley public: 15624640cde1SColin Riley CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter) 15634640cde1SColin Riley : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with renderscript kernels.", 15644640cde1SColin Riley NULL) 15654640cde1SColin Riley { 15664640cde1SColin Riley LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(interpreter))); 15674640cde1SColin Riley LoadSubCommand("breakpoint", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter))); 15684640cde1SColin Riley } 15694640cde1SColin Riley 15704640cde1SColin Riley ~CommandObjectRenderScriptRuntimeKernel() {} 15714640cde1SColin Riley }; 15724640cde1SColin Riley 15734640cde1SColin Riley class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed 15744640cde1SColin Riley { 15754640cde1SColin Riley private: 15764640cde1SColin Riley public: 15774640cde1SColin Riley CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter) 15784640cde1SColin Riley : CommandObjectParsed(interpreter, "renderscript context dump", 15794640cde1SColin Riley "Dumps renderscript context information.", "renderscript context dump", 15804640cde1SColin Riley eCommandRequiresProcess | eCommandProcessMustBeLaunched) 15814640cde1SColin Riley { 15824640cde1SColin Riley } 15834640cde1SColin Riley 15844640cde1SColin Riley ~CommandObjectRenderScriptRuntimeContextDump() {} 15854640cde1SColin Riley 15864640cde1SColin Riley bool 15874640cde1SColin Riley DoExecute(Args &command, CommandReturnObject &result) 15884640cde1SColin Riley { 15894640cde1SColin Riley RenderScriptRuntime *runtime = 15904640cde1SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 15914640cde1SColin Riley runtime->DumpContexts(result.GetOutputStream()); 15924640cde1SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 15934640cde1SColin Riley return true; 15944640cde1SColin Riley } 15954640cde1SColin Riley }; 15964640cde1SColin Riley 15974640cde1SColin Riley class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword 15984640cde1SColin Riley { 15994640cde1SColin Riley private: 16004640cde1SColin Riley public: 16014640cde1SColin Riley CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter) 16024640cde1SColin Riley : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with renderscript contexts.", 16034640cde1SColin Riley NULL) 16044640cde1SColin Riley { 16054640cde1SColin Riley LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(interpreter))); 16064640cde1SColin Riley } 16074640cde1SColin Riley 16084640cde1SColin Riley ~CommandObjectRenderScriptRuntimeContext() {} 16094640cde1SColin Riley }; 16104640cde1SColin Riley 16114640cde1SColin Riley class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed 16124640cde1SColin Riley { 16134640cde1SColin Riley private: 16144640cde1SColin Riley public: 16154640cde1SColin Riley CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter) 16164640cde1SColin Riley : CommandObjectParsed(interpreter, "renderscript status", 16174640cde1SColin Riley "Displays current renderscript runtime status.", "renderscript status", 16184640cde1SColin Riley eCommandRequiresProcess | eCommandProcessMustBeLaunched) 16194640cde1SColin Riley { 16204640cde1SColin Riley } 16214640cde1SColin Riley 16224640cde1SColin Riley ~CommandObjectRenderScriptRuntimeStatus() {} 16234640cde1SColin Riley 16244640cde1SColin Riley bool 16254640cde1SColin Riley DoExecute(Args &command, CommandReturnObject &result) 16264640cde1SColin Riley { 16274640cde1SColin Riley RenderScriptRuntime *runtime = 16284640cde1SColin Riley (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 16294640cde1SColin Riley runtime->Status(result.GetOutputStream()); 16304640cde1SColin Riley result.SetStatus(eReturnStatusSuccessFinishResult); 16314640cde1SColin Riley return true; 16324640cde1SColin Riley } 16334640cde1SColin Riley }; 16344640cde1SColin Riley 16355ec532a9SColin Riley class CommandObjectRenderScriptRuntime : public CommandObjectMultiword 16365ec532a9SColin Riley { 16375ec532a9SColin Riley public: 16385ec532a9SColin Riley CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter) 16395ec532a9SColin Riley : CommandObjectMultiword(interpreter, "renderscript", "A set of commands for operating on renderscript.", 16405ec532a9SColin Riley "renderscript <subcommand> [<subcommand-options>]") 16415ec532a9SColin Riley { 16425ec532a9SColin Riley LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter))); 16434640cde1SColin Riley LoadSubCommand("status", CommandObjectSP(new CommandObjectRenderScriptRuntimeStatus(interpreter))); 16444640cde1SColin Riley LoadSubCommand("kernel", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernel(interpreter))); 16454640cde1SColin Riley LoadSubCommand("context", CommandObjectSP(new CommandObjectRenderScriptRuntimeContext(interpreter))); 16465ec532a9SColin Riley } 16475ec532a9SColin Riley 16485ec532a9SColin Riley ~CommandObjectRenderScriptRuntime() {} 16495ec532a9SColin Riley }; 1650ef20b08fSColin Riley 1651ef20b08fSColin Riley void 1652ef20b08fSColin Riley RenderScriptRuntime::Initiate() 16535ec532a9SColin Riley { 1654ef20b08fSColin Riley assert(!m_initiated); 16555ec532a9SColin Riley } 1656ef20b08fSColin Riley 1657ef20b08fSColin Riley RenderScriptRuntime::RenderScriptRuntime(Process *process) 16587dc7771cSEwan Crawford : lldb_private::CPPLanguageRuntime(process), m_initiated(false), m_debuggerPresentFlagged(false), 16597dc7771cSEwan Crawford m_breakAllKernels(false) 1660ef20b08fSColin Riley { 16614640cde1SColin Riley ModulesDidLoad(process->GetTarget().GetImages()); 1662ef20b08fSColin Riley } 16634640cde1SColin Riley 16644640cde1SColin Riley lldb::CommandObjectSP 16654640cde1SColin Riley RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter& interpreter) 16664640cde1SColin Riley { 16674640cde1SColin Riley static CommandObjectSP command_object; 16684640cde1SColin Riley if(!command_object) 16694640cde1SColin Riley { 16704640cde1SColin Riley command_object.reset(new CommandObjectRenderScriptRuntime(interpreter)); 16714640cde1SColin Riley } 16724640cde1SColin Riley return command_object; 16734640cde1SColin Riley } 16744640cde1SColin Riley 167578f339d1SEwan Crawford RenderScriptRuntime::~RenderScriptRuntime() = default; 1676