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 
355ec532a9SColin Riley //------------------------------------------------------------------
365ec532a9SColin Riley // Static Functions
375ec532a9SColin Riley //------------------------------------------------------------------
385ec532a9SColin Riley LanguageRuntime *
395ec532a9SColin Riley RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType language)
405ec532a9SColin Riley {
415ec532a9SColin Riley 
425ec532a9SColin Riley     if (language == eLanguageTypeExtRenderScript)
435ec532a9SColin Riley         return new RenderScriptRuntime(process);
445ec532a9SColin Riley     else
455ec532a9SColin Riley         return NULL;
465ec532a9SColin Riley }
475ec532a9SColin Riley 
4898156583SEwan Crawford // Callback with a module to search for matching symbols.
4998156583SEwan Crawford // We first check that the module contains RS kernels.
5098156583SEwan Crawford // Then look for a symbol which matches our kernel name.
5198156583SEwan Crawford // The breakpoint address is finally set using the address of this symbol.
5298156583SEwan Crawford Searcher::CallbackReturn
5398156583SEwan Crawford RSBreakpointResolver::SearchCallback(SearchFilter &filter,
5498156583SEwan Crawford                                      SymbolContext &context,
5598156583SEwan Crawford                                      Address*,
5698156583SEwan Crawford                                      bool)
5798156583SEwan Crawford {
5898156583SEwan Crawford     ModuleSP module = context.module_sp;
5998156583SEwan Crawford 
6098156583SEwan Crawford     if (!module)
6198156583SEwan Crawford         return Searcher::eCallbackReturnContinue;
6298156583SEwan Crawford 
6398156583SEwan Crawford     // Is this a module containing renderscript kernels?
6498156583SEwan Crawford     if (nullptr == module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData))
6598156583SEwan Crawford         return Searcher::eCallbackReturnContinue;
6698156583SEwan Crawford 
6798156583SEwan Crawford     // Attempt to set a breakpoint on the kernel name symbol within the module library.
6898156583SEwan Crawford     // If it's not found, it's likely debug info is unavailable - try to set a
6998156583SEwan Crawford     // breakpoint on <name>.expand.
7098156583SEwan Crawford 
7198156583SEwan Crawford     const Symbol* kernel_sym = module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode);
7298156583SEwan Crawford     if (!kernel_sym)
7398156583SEwan Crawford     {
7498156583SEwan Crawford         std::string kernel_name_expanded(m_kernel_name.AsCString());
7598156583SEwan Crawford         kernel_name_expanded.append(".expand");
7698156583SEwan Crawford         kernel_sym = module->FindFirstSymbolWithNameAndType(ConstString(kernel_name_expanded.c_str()), eSymbolTypeCode);
7798156583SEwan Crawford     }
7898156583SEwan Crawford 
7998156583SEwan Crawford     if (kernel_sym)
8098156583SEwan Crawford     {
8198156583SEwan Crawford         Address bp_addr = kernel_sym->GetAddress();
8298156583SEwan Crawford         if (filter.AddressPasses(bp_addr))
8398156583SEwan Crawford             m_breakpoint->AddLocation(bp_addr);
8498156583SEwan Crawford     }
8598156583SEwan Crawford 
8698156583SEwan Crawford     return Searcher::eCallbackReturnContinue;
8798156583SEwan Crawford }
8898156583SEwan Crawford 
895ec532a9SColin Riley void
905ec532a9SColin Riley RenderScriptRuntime::Initialize()
915ec532a9SColin Riley {
924640cde1SColin Riley     PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance, GetCommandObject);
935ec532a9SColin Riley }
945ec532a9SColin Riley 
955ec532a9SColin Riley void
965ec532a9SColin Riley RenderScriptRuntime::Terminate()
975ec532a9SColin Riley {
985ec532a9SColin Riley     PluginManager::UnregisterPlugin(CreateInstance);
995ec532a9SColin Riley }
1005ec532a9SColin Riley 
1015ec532a9SColin Riley lldb_private::ConstString
1025ec532a9SColin Riley RenderScriptRuntime::GetPluginNameStatic()
1035ec532a9SColin Riley {
1045ec532a9SColin Riley     static ConstString g_name("renderscript");
1055ec532a9SColin Riley     return g_name;
1065ec532a9SColin Riley }
1075ec532a9SColin Riley 
108ef20b08fSColin Riley RenderScriptRuntime::ModuleKind
109ef20b08fSColin Riley RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp)
110ef20b08fSColin Riley {
111ef20b08fSColin Riley     if (module_sp)
112ef20b08fSColin Riley     {
113ef20b08fSColin Riley         // Is this a module containing renderscript kernels?
114ef20b08fSColin Riley         const Symbol *info_sym = module_sp->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
115ef20b08fSColin Riley         if (info_sym)
116ef20b08fSColin Riley         {
117ef20b08fSColin Riley             return eModuleKindKernelObj;
118ef20b08fSColin Riley         }
1194640cde1SColin Riley 
1204640cde1SColin Riley         // Is this the main RS runtime library
1214640cde1SColin Riley         const ConstString rs_lib("libRS.so");
1224640cde1SColin Riley         if (module_sp->GetFileSpec().GetFilename() == rs_lib)
1234640cde1SColin Riley         {
1244640cde1SColin Riley             return eModuleKindLibRS;
1254640cde1SColin Riley         }
1264640cde1SColin Riley 
1274640cde1SColin Riley         const ConstString rs_driverlib("libRSDriver.so");
1284640cde1SColin Riley         if (module_sp->GetFileSpec().GetFilename() == rs_driverlib)
1294640cde1SColin Riley         {
1304640cde1SColin Riley             return eModuleKindDriver;
1314640cde1SColin Riley         }
1324640cde1SColin Riley 
1334640cde1SColin Riley         const ConstString rs_cpureflib("libRSCPURef.so");
1344640cde1SColin Riley         if (module_sp->GetFileSpec().GetFilename() == rs_cpureflib)
1354640cde1SColin Riley         {
1364640cde1SColin Riley             return eModuleKindImpl;
1374640cde1SColin Riley         }
1384640cde1SColin Riley 
139ef20b08fSColin Riley     }
140ef20b08fSColin Riley     return eModuleKindIgnored;
141ef20b08fSColin Riley }
142ef20b08fSColin Riley 
143ef20b08fSColin Riley bool
144ef20b08fSColin Riley RenderScriptRuntime::IsRenderScriptModule(const lldb::ModuleSP &module_sp)
145ef20b08fSColin Riley {
146ef20b08fSColin Riley     return GetModuleKind(module_sp) != eModuleKindIgnored;
147ef20b08fSColin Riley }
148ef20b08fSColin Riley 
149ef20b08fSColin Riley 
150ef20b08fSColin Riley void
151ef20b08fSColin Riley RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list )
152ef20b08fSColin Riley {
153ef20b08fSColin Riley     Mutex::Locker locker (module_list.GetMutex ());
154ef20b08fSColin Riley 
155ef20b08fSColin Riley     size_t num_modules = module_list.GetSize();
156ef20b08fSColin Riley     for (size_t i = 0; i < num_modules; i++)
157ef20b08fSColin Riley     {
158ef20b08fSColin Riley         auto mod = module_list.GetModuleAtIndex (i);
159ef20b08fSColin Riley         if (IsRenderScriptModule (mod))
160ef20b08fSColin Riley         {
161ef20b08fSColin Riley             LoadModule(mod);
162ef20b08fSColin Riley         }
163ef20b08fSColin Riley     }
164ef20b08fSColin Riley }
165ef20b08fSColin Riley 
166ef20b08fSColin Riley 
1675ec532a9SColin Riley //------------------------------------------------------------------
1685ec532a9SColin Riley // PluginInterface protocol
1695ec532a9SColin Riley //------------------------------------------------------------------
1705ec532a9SColin Riley lldb_private::ConstString
1715ec532a9SColin Riley RenderScriptRuntime::GetPluginName()
1725ec532a9SColin Riley {
1735ec532a9SColin Riley     return GetPluginNameStatic();
1745ec532a9SColin Riley }
1755ec532a9SColin Riley 
1765ec532a9SColin Riley uint32_t
1775ec532a9SColin Riley RenderScriptRuntime::GetPluginVersion()
1785ec532a9SColin Riley {
1795ec532a9SColin Riley     return 1;
1805ec532a9SColin Riley }
1815ec532a9SColin Riley 
1825ec532a9SColin Riley bool
1835ec532a9SColin Riley RenderScriptRuntime::IsVTableName(const char *name)
1845ec532a9SColin Riley {
1855ec532a9SColin Riley     return false;
1865ec532a9SColin Riley }
1875ec532a9SColin Riley 
1885ec532a9SColin Riley bool
1895ec532a9SColin Riley RenderScriptRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
1905ec532a9SColin Riley                                               TypeAndOrName &class_type_or_name, Address &address)
1915ec532a9SColin Riley {
1925ec532a9SColin Riley     return false;
1935ec532a9SColin Riley }
1945ec532a9SColin Riley 
1955ec532a9SColin Riley bool
1965ec532a9SColin Riley RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value)
1975ec532a9SColin Riley {
1985ec532a9SColin Riley     return false;
1995ec532a9SColin Riley }
2005ec532a9SColin Riley 
2015ec532a9SColin Riley lldb::BreakpointResolverSP
2025ec532a9SColin Riley RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp)
2035ec532a9SColin Riley {
2045ec532a9SColin Riley     BreakpointResolverSP resolver_sp;
2055ec532a9SColin Riley     return resolver_sp;
2065ec532a9SColin Riley }
2075ec532a9SColin Riley 
2084640cde1SColin Riley 
2094640cde1SColin Riley const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] =
2104640cde1SColin Riley {
2114640cde1SColin Riley     //rsdScript
2124640cde1SColin Riley     {"rsdScriptInit", "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhjj", 0, RenderScriptRuntime::eModuleKindDriver, &lldb_private::RenderScriptRuntime::CaptureScriptInit1},
2134640cde1SColin Riley     {"rsdScriptInvokeForEach", "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvjPK12RsScriptCall", 0, RenderScriptRuntime::eModuleKindDriver, nullptr},
2144640cde1SColin Riley     {"rsdScriptInvokeForEachMulti", "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall", 0, RenderScriptRuntime::eModuleKindDriver, nullptr},
2154640cde1SColin Riley     {"rsdScriptInvokeFunction", "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvj", 0, RenderScriptRuntime::eModuleKindDriver, nullptr},
2164640cde1SColin Riley     {"rsdScriptSetGlobalVar", "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvj", 0, RenderScriptRuntime::eModuleKindDriver, &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar1},
2174640cde1SColin Riley 
2184640cde1SColin Riley     //rsdAllocation
2194640cde1SColin Riley     {"rsdAllocationInit", "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", 0, RenderScriptRuntime::eModuleKindDriver, &lldb_private::RenderScriptRuntime::CaptureAllocationInit1},
2204640cde1SColin Riley     {"rsdAllocationRead2D", "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvjj", 0, RenderScriptRuntime::eModuleKindDriver, nullptr},
2214640cde1SColin Riley };
2224640cde1SColin Riley const size_t RenderScriptRuntime::s_runtimeHookCount = sizeof(s_runtimeHookDefns)/sizeof(s_runtimeHookDefns[0]);
2234640cde1SColin Riley 
2244640cde1SColin Riley 
2254640cde1SColin Riley bool
2264640cde1SColin Riley RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
2274640cde1SColin Riley {
2284640cde1SColin Riley     RuntimeHook* hook_info = (RuntimeHook*)baton;
2294640cde1SColin Riley     ExecutionContext context(ctx->exe_ctx_ref);
2304640cde1SColin Riley 
2314640cde1SColin Riley     RenderScriptRuntime *lang_rt = (RenderScriptRuntime *)context.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
2324640cde1SColin Riley 
2334640cde1SColin Riley     lang_rt->HookCallback(hook_info, context);
2344640cde1SColin Riley 
2354640cde1SColin Riley     return false;
2364640cde1SColin Riley }
2374640cde1SColin Riley 
2384640cde1SColin Riley 
2394640cde1SColin Riley void
2404640cde1SColin Riley RenderScriptRuntime::HookCallback(RuntimeHook* hook_info, ExecutionContext& context)
2414640cde1SColin Riley {
2424640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
2434640cde1SColin Riley 
2444640cde1SColin Riley     if(log)
2454640cde1SColin Riley         log->Printf ("RenderScriptRuntime::HookCallback - '%s' .", hook_info->defn->name);
2464640cde1SColin Riley 
2474640cde1SColin Riley     if (hook_info->defn->grabber)
2484640cde1SColin Riley     {
2494640cde1SColin Riley         (this->*(hook_info->defn->grabber))(hook_info, context);
2504640cde1SColin Riley     }
2514640cde1SColin Riley }
2524640cde1SColin Riley 
2534640cde1SColin Riley 
2544640cde1SColin Riley bool
2554640cde1SColin Riley RenderScriptRuntime::GetArg32Simple(ExecutionContext& context, uint32_t arg, uint32_t *data)
2564640cde1SColin Riley {
2574640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
2584640cde1SColin Riley 
2594640cde1SColin Riley     if (!data)
2604640cde1SColin Riley         return false;
2614640cde1SColin Riley 
2624640cde1SColin Riley     Error error;
2634640cde1SColin Riley     RegisterContext* reg_ctx = context.GetRegisterContext();
2644640cde1SColin Riley     Process* process = context.GetProcessPtr();
2654640cde1SColin Riley 
2664640cde1SColin Riley     if (context.GetTargetPtr()->GetArchitecture().GetMachine() == llvm::Triple::ArchType::x86)
2674640cde1SColin Riley     {
2684640cde1SColin Riley         uint64_t sp = reg_ctx->GetSP();
2694640cde1SColin Riley         {
2704640cde1SColin Riley             uint32_t offset = (1 + arg) * sizeof(uint32_t);
2714640cde1SColin Riley             process->ReadMemory(sp + offset, data, sizeof(uint32_t), error);
2724640cde1SColin Riley             if(error.Fail())
2734640cde1SColin Riley             {
2744640cde1SColin Riley                 if(log)
2754640cde1SColin Riley                     log->Printf ("RenderScriptRuntime:: GetArg32Simple - error reading X86 stack: %s.", error.AsCString());
2764640cde1SColin Riley             }
2774640cde1SColin Riley         }
2784640cde1SColin Riley     }
2794640cde1SColin Riley     else if (context.GetTargetPtr()->GetArchitecture().GetMachine() == llvm::Triple::ArchType::arm)
2804640cde1SColin Riley     {
2814640cde1SColin Riley         if (arg < 4)
2824640cde1SColin Riley         {
2834640cde1SColin Riley             const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg);
2844640cde1SColin Riley             RegisterValue rVal;
2854640cde1SColin Riley             reg_ctx->ReadRegister(rArg, rVal);
2864640cde1SColin Riley             (*data) = rVal.GetAsUInt32();
2874640cde1SColin Riley         }
2884640cde1SColin Riley         else
2894640cde1SColin Riley         {
2904640cde1SColin Riley             uint64_t sp = reg_ctx->GetSP();
2914640cde1SColin Riley             {
2924640cde1SColin Riley                 uint32_t offset = (arg-4) * sizeof(uint32_t);
2934640cde1SColin Riley                 process->ReadMemory(sp + offset, &data, sizeof(uint32_t), error);
2944640cde1SColin Riley                 if(error.Fail())
2954640cde1SColin Riley                 {
2964640cde1SColin Riley                     if(log)
2974640cde1SColin Riley                         log->Printf ("RenderScriptRuntime:: GetArg32Simple - error reading ARM stack: %s.", error.AsCString());
2984640cde1SColin Riley                 }
2994640cde1SColin Riley             }
3004640cde1SColin Riley         }
3014640cde1SColin Riley     }
3024640cde1SColin Riley     return true;
3034640cde1SColin Riley }
3044640cde1SColin Riley 
3054640cde1SColin Riley void
3064640cde1SColin Riley RenderScriptRuntime::CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context)
3074640cde1SColin Riley {
3084640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
3094640cde1SColin Riley 
3104640cde1SColin Riley     //Context, Script, int, data, length
3114640cde1SColin Riley 
3124640cde1SColin Riley     Error error;
3134640cde1SColin Riley 
3144640cde1SColin Riley     uint32_t rs_context_u32 = 0U;
3154640cde1SColin Riley     uint32_t rs_script_u32 = 0U;
3164640cde1SColin Riley     uint32_t rs_id_u32 = 0U;
3174640cde1SColin Riley     uint32_t rs_data_u32 = 0U;
3184640cde1SColin Riley     uint32_t rs_length_u32 = 0U;
3194640cde1SColin Riley 
3204640cde1SColin Riley     std::string resname;
3214640cde1SColin Riley     std::string cachedir;
3224640cde1SColin Riley 
3234640cde1SColin Riley     GetArg32Simple(context, 0, &rs_context_u32);
3244640cde1SColin Riley     GetArg32Simple(context, 1, &rs_script_u32);
3254640cde1SColin Riley     GetArg32Simple(context, 2, &rs_id_u32);
3264640cde1SColin Riley     GetArg32Simple(context, 3, &rs_data_u32);
3274640cde1SColin Riley     GetArg32Simple(context, 4, &rs_length_u32);
3284640cde1SColin Riley 
3294640cde1SColin Riley     if(log)
3304640cde1SColin Riley     {
3314640cde1SColin Riley         log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 ":%" PRIu64 "bytes.",
3324640cde1SColin Riley                         (uint64_t)rs_context_u32, (uint64_t)rs_script_u32, (uint64_t)rs_id_u32, (uint64_t)rs_data_u32, (uint64_t)rs_length_u32);
3334640cde1SColin Riley 
3344640cde1SColin Riley         addr_t script_addr =  (addr_t)rs_script_u32;
3354640cde1SColin Riley         if (m_scriptMappings.find( script_addr ) != m_scriptMappings.end())
3364640cde1SColin Riley         {
3374640cde1SColin Riley             auto rsm = m_scriptMappings[script_addr];
3384640cde1SColin Riley             if (rs_id_u32 < rsm->m_globals.size())
3394640cde1SColin Riley             {
3404640cde1SColin Riley                 auto rsg = rsm->m_globals[rs_id_u32];
3414640cde1SColin Riley                 log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - Setting of '%s' within '%s' inferred", rsg.m_name.AsCString(),
3424640cde1SColin Riley                                 rsm->m_module->GetFileSpec().GetFilename().AsCString());
3434640cde1SColin Riley             }
3444640cde1SColin Riley         }
3454640cde1SColin Riley     }
3464640cde1SColin Riley }
3474640cde1SColin Riley 
3484640cde1SColin Riley void
3494640cde1SColin Riley RenderScriptRuntime::CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context)
3504640cde1SColin Riley {
3514640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
3524640cde1SColin Riley 
3534640cde1SColin Riley     //Context, Alloc, bool
3544640cde1SColin Riley 
3554640cde1SColin Riley     Error error;
3564640cde1SColin Riley 
3574640cde1SColin Riley     uint32_t rs_context_u32 = 0U;
3584640cde1SColin Riley     uint32_t rs_alloc_u32 = 0U;
3594640cde1SColin Riley     uint32_t rs_forceZero_u32 = 0U;
3604640cde1SColin Riley 
3614640cde1SColin Riley     GetArg32Simple(context, 0, &rs_context_u32);
3624640cde1SColin Riley     GetArg32Simple(context, 1, &rs_alloc_u32);
3634640cde1SColin Riley     GetArg32Simple(context, 2, &rs_forceZero_u32);
3644640cde1SColin Riley 
3654640cde1SColin Riley     if(log)
3664640cde1SColin Riley         log->Printf ("RenderScriptRuntime::CaptureAllocationInit1 - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .",
3674640cde1SColin Riley                         (uint64_t)rs_context_u32, (uint64_t)rs_alloc_u32, (uint64_t)rs_forceZero_u32);
3684640cde1SColin Riley }
3694640cde1SColin Riley 
3704640cde1SColin Riley void
3714640cde1SColin Riley RenderScriptRuntime::CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context)
3724640cde1SColin Riley {
3734640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
3744640cde1SColin Riley 
3754640cde1SColin Riley     //Context, Script, resname Str, cachedir Str
3764640cde1SColin Riley     Error error;
3774640cde1SColin Riley     Process* process = context.GetProcessPtr();
3784640cde1SColin Riley 
3794640cde1SColin Riley     uint32_t rs_context_u32 = 0U;
3804640cde1SColin Riley     uint32_t rs_script_u32 = 0U;
3814640cde1SColin Riley     uint32_t rs_resnameptr_u32 = 0U;
3824640cde1SColin Riley     uint32_t rs_cachedirptr_u32 = 0U;
3834640cde1SColin Riley 
3844640cde1SColin Riley     std::string resname;
3854640cde1SColin Riley     std::string cachedir;
3864640cde1SColin Riley 
3874640cde1SColin Riley     GetArg32Simple(context, 0, &rs_context_u32);
3884640cde1SColin Riley     GetArg32Simple(context, 1, &rs_script_u32);
3894640cde1SColin Riley     GetArg32Simple(context, 2, &rs_resnameptr_u32);
3904640cde1SColin Riley     GetArg32Simple(context, 3, &rs_cachedirptr_u32);
3914640cde1SColin Riley 
3924640cde1SColin Riley     process->ReadCStringFromMemory((lldb::addr_t)rs_resnameptr_u32, resname, error);
3934640cde1SColin Riley     if (error.Fail())
3944640cde1SColin Riley     {
3954640cde1SColin Riley         if(log)
3964640cde1SColin Riley             log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading resname: %s.", error.AsCString());
3974640cde1SColin Riley 
3984640cde1SColin Riley     }
3994640cde1SColin Riley 
4004640cde1SColin Riley     process->ReadCStringFromMemory((lldb::addr_t)rs_cachedirptr_u32, cachedir, error);
4014640cde1SColin Riley     if (error.Fail())
4024640cde1SColin Riley     {
4034640cde1SColin Riley         if(log)
4044640cde1SColin Riley             log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading cachedir: %s.", error.AsCString());
4054640cde1SColin Riley     }
4064640cde1SColin Riley 
4074640cde1SColin Riley     if (log)
4084640cde1SColin Riley         log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .",
4094640cde1SColin Riley                      (uint64_t)rs_context_u32, (uint64_t)rs_script_u32, resname.c_str(), cachedir.c_str());
4104640cde1SColin Riley 
4114640cde1SColin Riley     if (resname.size() > 0)
4124640cde1SColin Riley     {
4134640cde1SColin Riley         StreamString strm;
4144640cde1SColin Riley         strm.Printf("librs.%s.so", resname.c_str());
4154640cde1SColin Riley 
4164640cde1SColin Riley         ScriptDetails script;
4174640cde1SColin Riley         script.cachedir = cachedir;
4184640cde1SColin Riley         script.resname = resname;
4194640cde1SColin Riley         script.scriptDyLib.assign(strm.GetData());
4204640cde1SColin Riley         script.script = rs_script_u32;
4214640cde1SColin Riley         script.context = rs_context_u32;
4224640cde1SColin Riley 
4234640cde1SColin Riley         m_scripts.push_back(script);
4244640cde1SColin Riley 
4254640cde1SColin Riley         if (log)
4264640cde1SColin Riley             log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - '%s' tagged with context 0x%" PRIx64 " and script 0x%" PRIx64 ".",
4274640cde1SColin Riley                          strm.GetData(), (uint64_t)rs_context_u32, (uint64_t)rs_script_u32);
4284640cde1SColin Riley     }
4294640cde1SColin Riley     else if (log)
4304640cde1SColin Riley     {
4314640cde1SColin Riley         log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - resource name invalid, Script not tagged");
4324640cde1SColin Riley     }
4334640cde1SColin Riley 
4344640cde1SColin Riley }
4354640cde1SColin Riley 
4364640cde1SColin Riley 
4374640cde1SColin Riley void
4384640cde1SColin Riley RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
4394640cde1SColin Riley {
4404640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
4414640cde1SColin Riley 
4424640cde1SColin Riley     if (!module)
4434640cde1SColin Riley     {
4444640cde1SColin Riley         return;
4454640cde1SColin Riley     }
4464640cde1SColin Riley 
4474640cde1SColin Riley     if ((GetProcess()->GetTarget().GetArchitecture().GetMachine() != llvm::Triple::ArchType::x86)
4484640cde1SColin Riley         && (GetProcess()->GetTarget().GetArchitecture().GetMachine() != llvm::Triple::ArchType::arm))
4494640cde1SColin Riley     {
4504640cde1SColin Riley         if (log)
4514640cde1SColin Riley             log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to hook runtime. Only X86, ARM supported currently.");
4524640cde1SColin Riley 
4534640cde1SColin Riley         return;
4544640cde1SColin Riley     }
4554640cde1SColin Riley 
4564640cde1SColin Riley     Target &target = GetProcess()->GetTarget();
4574640cde1SColin Riley 
4584640cde1SColin Riley     for (size_t idx = 0; idx < s_runtimeHookCount; idx++)
4594640cde1SColin Riley     {
4604640cde1SColin Riley         const HookDefn* hook_defn = &s_runtimeHookDefns[idx];
4614640cde1SColin Riley         if (hook_defn->kind != kind) {
4624640cde1SColin Riley             continue;
4634640cde1SColin Riley         }
4644640cde1SColin Riley 
4654640cde1SColin Riley         const Symbol *sym = module->FindFirstSymbolWithNameAndType(ConstString(hook_defn->symbol_name), eSymbolTypeCode);
4664640cde1SColin Riley 
467358cf1eaSGreg Clayton         addr_t addr = sym->GetLoadAddress(&target);
4684640cde1SColin Riley         if (addr == LLDB_INVALID_ADDRESS)
4694640cde1SColin Riley         {
4704640cde1SColin Riley             if(log)
4714640cde1SColin Riley                 log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to resolve the address of hook function '%s' with symbol '%s'.",
4724640cde1SColin Riley                              hook_defn->name, hook_defn->symbol_name);
4734640cde1SColin Riley             continue;
4744640cde1SColin Riley         }
4754640cde1SColin Riley 
4764640cde1SColin Riley         RuntimeHookSP hook(new RuntimeHook());
4774640cde1SColin Riley         hook->address = addr;
4784640cde1SColin Riley         hook->defn = hook_defn;
4794640cde1SColin Riley         hook->bp_sp = target.CreateBreakpoint(addr, true, false);
4804640cde1SColin Riley         hook->bp_sp->SetCallback(HookCallback, hook.get(), true);
4814640cde1SColin Riley         m_runtimeHooks[addr] = hook;
4824640cde1SColin Riley         if (log)
4834640cde1SColin Riley         {
4844640cde1SColin Riley             log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Successfully hooked '%s' in '%s' version %" PRIu64 " at 0x%" PRIx64 ".",
4854640cde1SColin Riley                 hook_defn->name, module->GetFileSpec().GetFilename().AsCString(), (uint64_t)hook_defn->version, (uint64_t)addr);
4864640cde1SColin Riley         }
4874640cde1SColin Riley     }
4884640cde1SColin Riley }
4894640cde1SColin Riley 
4904640cde1SColin Riley void
4914640cde1SColin Riley RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp)
4924640cde1SColin Riley {
4934640cde1SColin Riley     if (!rsmodule_sp)
4944640cde1SColin Riley         return;
4954640cde1SColin Riley 
4964640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
4974640cde1SColin Riley 
4984640cde1SColin Riley     const ModuleSP module = rsmodule_sp->m_module;
4994640cde1SColin Riley     const FileSpec& file = module->GetPlatformFileSpec();
5004640cde1SColin Riley 
5014640cde1SColin Riley     for (const auto &rs_script : m_scripts)
5024640cde1SColin Riley     {
5034640cde1SColin Riley         if (file.GetFilename() == ConstString(rs_script.scriptDyLib.c_str()))
5044640cde1SColin Riley         {
5054640cde1SColin Riley             if (m_scriptMappings.find( rs_script.script ) != m_scriptMappings.end())
5064640cde1SColin Riley             {
5074640cde1SColin Riley                 if (m_scriptMappings[rs_script.script] != rsmodule_sp)
5084640cde1SColin Riley                 {
5094640cde1SColin Riley                     if (log)
5104640cde1SColin Riley                     {
5114640cde1SColin Riley                         log->Printf ("RenderScriptRuntime::FixupScriptDetails - Error: script %" PRIx64 " wants reassigned to new rsmodule '%s'.",
5124640cde1SColin Riley                                      (uint64_t)rs_script.script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
5134640cde1SColin Riley                     }
5144640cde1SColin Riley                 }
5154640cde1SColin Riley             }
5164640cde1SColin Riley             else
5174640cde1SColin Riley             {
5184640cde1SColin Riley                 m_scriptMappings[rs_script.script] = rsmodule_sp;
5194640cde1SColin Riley                 rsmodule_sp->m_resname = rs_script.resname;
5204640cde1SColin Riley                 if (log)
5214640cde1SColin Riley                 {
5224640cde1SColin Riley                     log->Printf ("RenderScriptRuntime::FixupScriptDetails - script %" PRIx64 " associated with rsmodule '%s'.",
5234640cde1SColin Riley                                     (uint64_t)rs_script.script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
5244640cde1SColin Riley                 }
5254640cde1SColin Riley             }
5264640cde1SColin Riley         }
5274640cde1SColin Riley     }
5284640cde1SColin Riley 
5294640cde1SColin Riley }
5304640cde1SColin Riley 
5315ec532a9SColin Riley bool
5325ec532a9SColin Riley RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
5335ec532a9SColin Riley {
5344640cde1SColin Riley     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
5354640cde1SColin Riley 
5365ec532a9SColin Riley     if (module_sp)
5375ec532a9SColin Riley     {
5385ec532a9SColin Riley         for (const auto &rs_module : m_rsmodules)
5395ec532a9SColin Riley         {
5404640cde1SColin Riley             if (rs_module->m_module == module_sp)
541*7dc7771cSEwan Crawford             {
542*7dc7771cSEwan Crawford                 // Check if the user has enabled automatically breaking on
543*7dc7771cSEwan Crawford                 // all RS kernels.
544*7dc7771cSEwan Crawford                 if (m_breakAllKernels)
545*7dc7771cSEwan Crawford                     BreakOnModuleKernels(rs_module);
546*7dc7771cSEwan Crawford 
5475ec532a9SColin Riley                 return false;
5485ec532a9SColin Riley             }
549*7dc7771cSEwan Crawford         }
550ef20b08fSColin Riley         bool module_loaded = false;
551ef20b08fSColin Riley         switch (GetModuleKind(module_sp))
552ef20b08fSColin Riley         {
553ef20b08fSColin Riley             case eModuleKindKernelObj:
554ef20b08fSColin Riley             {
5554640cde1SColin Riley                 RSModuleDescriptorSP module_desc;
5564640cde1SColin Riley                 module_desc.reset(new RSModuleDescriptor(module_sp));
5574640cde1SColin Riley                 if (module_desc->ParseRSInfo())
5585ec532a9SColin Riley                 {
5595ec532a9SColin Riley                     m_rsmodules.push_back(module_desc);
560ef20b08fSColin Riley                     module_loaded = true;
5615ec532a9SColin Riley                 }
5624640cde1SColin Riley                 if (module_loaded)
5634640cde1SColin Riley                 {
5644640cde1SColin Riley                     FixupScriptDetails(module_desc);
5654640cde1SColin Riley                 }
566ef20b08fSColin Riley                 break;
567ef20b08fSColin Riley             }
568ef20b08fSColin Riley             case eModuleKindDriver:
5694640cde1SColin Riley             {
5704640cde1SColin Riley                 if (!m_libRSDriver)
5714640cde1SColin Riley                 {
5724640cde1SColin Riley                     m_libRSDriver = module_sp;
5734640cde1SColin Riley                     LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver);
5744640cde1SColin Riley                 }
5754640cde1SColin Riley                 break;
5764640cde1SColin Riley             }
577ef20b08fSColin Riley             case eModuleKindImpl:
5784640cde1SColin Riley             {
5794640cde1SColin Riley                 m_libRSCpuRef = module_sp;
5804640cde1SColin Riley                 break;
5814640cde1SColin Riley             }
582ef20b08fSColin Riley             case eModuleKindLibRS:
5834640cde1SColin Riley             {
5844640cde1SColin Riley                 if (!m_libRS)
5854640cde1SColin Riley                 {
5864640cde1SColin Riley                     m_libRS = module_sp;
5874640cde1SColin Riley                     static ConstString gDbgPresentStr("gDebuggerPresent");
5884640cde1SColin Riley                     const Symbol* debug_present = m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData);
5894640cde1SColin Riley                     if (debug_present)
5904640cde1SColin Riley                     {
5914640cde1SColin Riley                         Error error;
5924640cde1SColin Riley                         uint32_t flag = 0x00000001U;
5934640cde1SColin Riley                         Target &target = GetProcess()->GetTarget();
594358cf1eaSGreg Clayton                         addr_t addr = debug_present->GetLoadAddress(&target);
5954640cde1SColin Riley                         GetProcess()->WriteMemory(addr, &flag, sizeof(flag), error);
5964640cde1SColin Riley                         if(error.Success())
5974640cde1SColin Riley                         {
5984640cde1SColin Riley                             if (log)
5994640cde1SColin Riley                                 log->Printf ("RenderScriptRuntime::LoadModule - Debugger present flag set on debugee");
6004640cde1SColin Riley 
6014640cde1SColin Riley                             m_debuggerPresentFlagged = true;
6024640cde1SColin Riley                         }
6034640cde1SColin Riley                         else if (log)
6044640cde1SColin Riley                         {
6054640cde1SColin Riley                             log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags '%s' ", error.AsCString());
6064640cde1SColin Riley                         }
6074640cde1SColin Riley                     }
6084640cde1SColin Riley                     else if (log)
6094640cde1SColin Riley                     {
6104640cde1SColin Riley                         log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags - symbol not found");
6114640cde1SColin Riley                     }
6124640cde1SColin Riley                 }
6134640cde1SColin Riley                 break;
6144640cde1SColin Riley             }
615ef20b08fSColin Riley             default:
616ef20b08fSColin Riley                 break;
617ef20b08fSColin Riley         }
618ef20b08fSColin Riley         if (module_loaded)
619ef20b08fSColin Riley             Update();
620ef20b08fSColin Riley         return module_loaded;
6215ec532a9SColin Riley     }
6225ec532a9SColin Riley     return false;
6235ec532a9SColin Riley }
6245ec532a9SColin Riley 
625ef20b08fSColin Riley void
626ef20b08fSColin Riley RenderScriptRuntime::Update()
627ef20b08fSColin Riley {
628ef20b08fSColin Riley     if (m_rsmodules.size() > 0)
629ef20b08fSColin Riley     {
630ef20b08fSColin Riley         if (!m_initiated)
631ef20b08fSColin Riley         {
632ef20b08fSColin Riley             Initiate();
633ef20b08fSColin Riley         }
634ef20b08fSColin Riley     }
635ef20b08fSColin Riley }
636ef20b08fSColin Riley 
637ef20b08fSColin Riley 
6385ec532a9SColin Riley // The maximum line length of an .rs.info packet
6395ec532a9SColin Riley #define MAXLINE 500
6405ec532a9SColin Riley 
6415ec532a9SColin Riley // The .rs.info symbol in renderscript modules contains a string which needs to be parsed.
6425ec532a9SColin Riley // The string is basic and is parsed on a line by line basis.
6435ec532a9SColin Riley bool
6445ec532a9SColin Riley RSModuleDescriptor::ParseRSInfo()
6455ec532a9SColin Riley {
6465ec532a9SColin Riley     const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
6475ec532a9SColin Riley     if (info_sym)
6485ec532a9SColin Riley     {
649358cf1eaSGreg Clayton         const addr_t addr = info_sym->GetAddressRef().GetFileAddress();
6505ec532a9SColin Riley         const addr_t size = info_sym->GetByteSize();
6515ec532a9SColin Riley         const FileSpec fs = m_module->GetFileSpec();
6525ec532a9SColin Riley 
6535ec532a9SColin Riley         DataBufferSP buffer = fs.ReadFileContents(addr, size);
6545ec532a9SColin Riley 
6555ec532a9SColin Riley         if (!buffer)
6565ec532a9SColin Riley             return false;
6575ec532a9SColin Riley 
6585ec532a9SColin Riley         std::string info((const char *)buffer->GetBytes());
6595ec532a9SColin Riley 
6605ec532a9SColin Riley         std::vector<std::string> info_lines;
661e8433cc1SBruce Mitchener         size_t lpos = info.find('\n');
6625ec532a9SColin Riley         while (lpos != std::string::npos)
6635ec532a9SColin Riley         {
6645ec532a9SColin Riley             info_lines.push_back(info.substr(0, lpos));
6655ec532a9SColin Riley             info = info.substr(lpos + 1);
666e8433cc1SBruce Mitchener             lpos = info.find('\n');
6675ec532a9SColin Riley         }
6685ec532a9SColin Riley         size_t offset = 0;
6695ec532a9SColin Riley         while (offset < info_lines.size())
6705ec532a9SColin Riley         {
6715ec532a9SColin Riley             std::string line = info_lines[offset];
6725ec532a9SColin Riley             // Parse directives
6735ec532a9SColin Riley             uint32_t numDefns = 0;
6745ec532a9SColin Riley             if (sscanf(line.c_str(), "exportVarCount: %u", &numDefns) == 1)
6755ec532a9SColin Riley             {
6765ec532a9SColin Riley                 while (numDefns--)
6774640cde1SColin Riley                     m_globals.push_back(RSGlobalDescriptor(this, info_lines[++offset].c_str()));
6785ec532a9SColin Riley             }
6795ec532a9SColin Riley             else if (sscanf(line.c_str(), "exportFuncCount: %u", &numDefns) == 1)
6805ec532a9SColin Riley             {
6815ec532a9SColin Riley             }
6825ec532a9SColin Riley             else if (sscanf(line.c_str(), "exportForEachCount: %u", &numDefns) == 1)
6835ec532a9SColin Riley             {
6845ec532a9SColin Riley                 char name[MAXLINE];
6855ec532a9SColin Riley                 while (numDefns--)
6865ec532a9SColin Riley                 {
6875ec532a9SColin Riley                     uint32_t slot = 0;
6885ec532a9SColin Riley                     name[0] = '\0';
6895ec532a9SColin Riley                     if (sscanf(info_lines[++offset].c_str(), "%u - %s", &slot, &name[0]) == 2)
6905ec532a9SColin Riley                     {
6914640cde1SColin Riley                         m_kernels.push_back(RSKernelDescriptor(this, name, slot));
6924640cde1SColin Riley                     }
6934640cde1SColin Riley                 }
6944640cde1SColin Riley             }
6954640cde1SColin Riley             else if (sscanf(line.c_str(), "pragmaCount: %u", &numDefns) == 1)
6964640cde1SColin Riley             {
6974640cde1SColin Riley                 char name[MAXLINE];
6984640cde1SColin Riley                 char value[MAXLINE];
6994640cde1SColin Riley                 while (numDefns--)
7004640cde1SColin Riley                 {
7014640cde1SColin Riley                     name[0] = '\0';
7024640cde1SColin Riley                     value[0] = '\0';
7034640cde1SColin Riley                     if (sscanf(info_lines[++offset].c_str(), "%s - %s", &name[0], &value[0]) != 0
7044640cde1SColin Riley                         && (name[0] != '\0'))
7054640cde1SColin Riley                     {
7064640cde1SColin Riley                         m_pragmas[std::string(name)] = value;
7075ec532a9SColin Riley                     }
7085ec532a9SColin Riley                 }
7095ec532a9SColin Riley             }
7105ec532a9SColin Riley             else if (sscanf(line.c_str(), "objectSlotCount: %u", &numDefns) == 1)
7115ec532a9SColin Riley             {
7125ec532a9SColin Riley             }
7135ec532a9SColin Riley 
7145ec532a9SColin Riley             offset++;
7155ec532a9SColin Riley         }
7165ec532a9SColin Riley         return m_kernels.size() > 0;
7175ec532a9SColin Riley     }
7185ec532a9SColin Riley     return false;
7195ec532a9SColin Riley }
7205ec532a9SColin Riley 
7215ec532a9SColin Riley bool
7225ec532a9SColin Riley RenderScriptRuntime::ProbeModules(const ModuleList module_list)
7235ec532a9SColin Riley {
7245ec532a9SColin Riley     bool rs_found = false;
7255ec532a9SColin Riley     size_t num_modules = module_list.GetSize();
7265ec532a9SColin Riley     for (size_t i = 0; i < num_modules; i++)
7275ec532a9SColin Riley     {
7285ec532a9SColin Riley         auto module = module_list.GetModuleAtIndex(i);
7295ec532a9SColin Riley         rs_found |= LoadModule(module);
7305ec532a9SColin Riley     }
7315ec532a9SColin Riley     return rs_found;
7325ec532a9SColin Riley }
7335ec532a9SColin Riley 
7345ec532a9SColin Riley void
7354640cde1SColin Riley RenderScriptRuntime::Status(Stream &strm) const
7364640cde1SColin Riley {
7374640cde1SColin Riley     if (m_libRS)
7384640cde1SColin Riley     {
7394640cde1SColin Riley         strm.Printf("Runtime Library discovered.");
7404640cde1SColin Riley         strm.EOL();
7414640cde1SColin Riley     }
7424640cde1SColin Riley     if (m_libRSDriver)
7434640cde1SColin Riley     {
7444640cde1SColin Riley         strm.Printf("Runtime Driver discovered.");
7454640cde1SColin Riley         strm.EOL();
7464640cde1SColin Riley     }
7474640cde1SColin Riley     if (m_libRSCpuRef)
7484640cde1SColin Riley     {
7494640cde1SColin Riley         strm.Printf("CPU Reference Implementation discovered.");
7504640cde1SColin Riley         strm.EOL();
7514640cde1SColin Riley     }
7524640cde1SColin Riley 
7534640cde1SColin Riley     if (m_runtimeHooks.size())
7544640cde1SColin Riley     {
7554640cde1SColin Riley         strm.Printf("Runtime functions hooked:");
7564640cde1SColin Riley         strm.EOL();
7574640cde1SColin Riley         for (auto b : m_runtimeHooks)
7584640cde1SColin Riley         {
7594640cde1SColin Riley             strm.Indent(b.second->defn->name);
7604640cde1SColin Riley             strm.EOL();
7614640cde1SColin Riley         }
7624640cde1SColin Riley         strm.EOL();
7634640cde1SColin Riley     }
7644640cde1SColin Riley     else
7654640cde1SColin Riley     {
7664640cde1SColin Riley         strm.Printf("Runtime is not hooked.");
7674640cde1SColin Riley         strm.EOL();
7684640cde1SColin Riley     }
7694640cde1SColin Riley }
7704640cde1SColin Riley 
7714640cde1SColin Riley void
7724640cde1SColin Riley RenderScriptRuntime::DumpContexts(Stream &strm) const
7734640cde1SColin Riley {
7744640cde1SColin Riley     strm.Printf("Inferred RenderScript Contexts:");
7754640cde1SColin Riley     strm.EOL();
7764640cde1SColin Riley     strm.IndentMore();
7774640cde1SColin Riley 
7784640cde1SColin Riley     std::map<addr_t, uint64_t> contextReferences;
7794640cde1SColin Riley 
7804640cde1SColin Riley     for (const auto &script : m_scripts)
7814640cde1SColin Riley     {
7824640cde1SColin Riley         if (contextReferences.find(script.context) != contextReferences.end())
7834640cde1SColin Riley         {
7844640cde1SColin Riley             contextReferences[script.context]++;
7854640cde1SColin Riley         }
7864640cde1SColin Riley         else
7874640cde1SColin Riley         {
7884640cde1SColin Riley             contextReferences[script.context] = 1;
7894640cde1SColin Riley         }
7904640cde1SColin Riley     }
7914640cde1SColin Riley 
7924640cde1SColin Riley     for (const auto& cRef : contextReferences)
7934640cde1SColin Riley     {
7944640cde1SColin Riley         strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances", cRef.first, cRef.second);
7954640cde1SColin Riley         strm.EOL();
7964640cde1SColin Riley     }
7974640cde1SColin Riley     strm.IndentLess();
7984640cde1SColin Riley }
7994640cde1SColin Riley 
8004640cde1SColin Riley void
8014640cde1SColin Riley RenderScriptRuntime::DumpKernels(Stream &strm) const
8024640cde1SColin Riley {
8034640cde1SColin Riley     strm.Printf("RenderScript Kernels:");
8044640cde1SColin Riley     strm.EOL();
8054640cde1SColin Riley     strm.IndentMore();
8064640cde1SColin Riley     for (const auto &module : m_rsmodules)
8074640cde1SColin Riley     {
8084640cde1SColin Riley         strm.Printf("Resource '%s':",module->m_resname.c_str());
8094640cde1SColin Riley         strm.EOL();
8104640cde1SColin Riley         for (const auto &kernel : module->m_kernels)
8114640cde1SColin Riley         {
8124640cde1SColin Riley             strm.Indent(kernel.m_name.AsCString());
8134640cde1SColin Riley             strm.EOL();
8144640cde1SColin Riley         }
8154640cde1SColin Riley     }
8164640cde1SColin Riley     strm.IndentLess();
8174640cde1SColin Riley }
8184640cde1SColin Riley 
819*7dc7771cSEwan Crawford // Set breakpoints on every kernel found in RS module
820*7dc7771cSEwan Crawford void
821*7dc7771cSEwan Crawford RenderScriptRuntime::BreakOnModuleKernels(const RSModuleDescriptorSP rsmodule_sp)
822*7dc7771cSEwan Crawford {
823*7dc7771cSEwan Crawford     for (const auto &kernel : rsmodule_sp->m_kernels)
824*7dc7771cSEwan Crawford     {
825*7dc7771cSEwan Crawford         // Don't set breakpoint on 'root' kernel
826*7dc7771cSEwan Crawford         if (strcmp(kernel.m_name.AsCString(), "root") == 0)
827*7dc7771cSEwan Crawford             continue;
828*7dc7771cSEwan Crawford 
829*7dc7771cSEwan Crawford         CreateKernelBreakpoint(kernel.m_name);
830*7dc7771cSEwan Crawford     }
831*7dc7771cSEwan Crawford }
832*7dc7771cSEwan Crawford 
833*7dc7771cSEwan Crawford // Method is internally called by the 'kernel breakpoint all' command to
834*7dc7771cSEwan Crawford // enable or disable breaking on all kernels.
835*7dc7771cSEwan Crawford //
836*7dc7771cSEwan Crawford // When do_break is true we want to enable this functionality.
837*7dc7771cSEwan Crawford // When do_break is false we want to disable it.
838*7dc7771cSEwan Crawford void
839*7dc7771cSEwan Crawford RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target)
840*7dc7771cSEwan Crawford {
841*7dc7771cSEwan Crawford     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
842*7dc7771cSEwan Crawford 
843*7dc7771cSEwan Crawford     InitSearchFilter(target);
844*7dc7771cSEwan Crawford 
845*7dc7771cSEwan Crawford     // Set breakpoints on all the kernels
846*7dc7771cSEwan Crawford     if (do_break && !m_breakAllKernels)
847*7dc7771cSEwan Crawford     {
848*7dc7771cSEwan Crawford         m_breakAllKernels = true;
849*7dc7771cSEwan Crawford 
850*7dc7771cSEwan Crawford         for (const auto &module : m_rsmodules)
851*7dc7771cSEwan Crawford             BreakOnModuleKernels(module);
852*7dc7771cSEwan Crawford 
853*7dc7771cSEwan Crawford         if (log)
854*7dc7771cSEwan Crawford             log->Printf("RenderScriptRuntime::SetBreakAllKernels(True)"
855*7dc7771cSEwan Crawford                         "- breakpoints set on all currently loaded kernels");
856*7dc7771cSEwan Crawford     }
857*7dc7771cSEwan Crawford     else if (!do_break && m_breakAllKernels) // Breakpoints won't be set on any new kernels.
858*7dc7771cSEwan Crawford     {
859*7dc7771cSEwan Crawford         m_breakAllKernels = false;
860*7dc7771cSEwan Crawford 
861*7dc7771cSEwan Crawford         if (log)
862*7dc7771cSEwan Crawford             log->Printf("RenderScriptRuntime::SetBreakAllKernels(False) - breakpoints no longer automatically set");
863*7dc7771cSEwan Crawford     }
864*7dc7771cSEwan Crawford }
865*7dc7771cSEwan Crawford 
866*7dc7771cSEwan Crawford // Given the name of a kernel this function creates a breakpoint using our
867*7dc7771cSEwan Crawford // own breakpoint resolver, and returns the Breakpoint shared pointer.
868*7dc7771cSEwan Crawford BreakpointSP
869*7dc7771cSEwan Crawford RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name)
870*7dc7771cSEwan Crawford {
871*7dc7771cSEwan Crawford     Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
872*7dc7771cSEwan Crawford 
873*7dc7771cSEwan Crawford     if (!m_filtersp)
874*7dc7771cSEwan Crawford     {
875*7dc7771cSEwan Crawford         if (log)
876*7dc7771cSEwan Crawford             log->Printf("RenderScriptRuntime::CreateKernelBreakpoint - Error: No breakpoint search filter set");
877*7dc7771cSEwan Crawford         return nullptr;
878*7dc7771cSEwan Crawford     }
879*7dc7771cSEwan Crawford 
880*7dc7771cSEwan Crawford     BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name));
881*7dc7771cSEwan Crawford     BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(m_filtersp, resolver_sp, false, false, false);
882*7dc7771cSEwan Crawford 
883*7dc7771cSEwan Crawford     return bp;
884*7dc7771cSEwan Crawford }
885*7dc7771cSEwan Crawford 
8864640cde1SColin Riley void
88798156583SEwan Crawford RenderScriptRuntime::AttemptBreakpointAtKernelName(Stream &strm, const char* name, Error& error, TargetSP target)
8884640cde1SColin Riley {
8894640cde1SColin Riley     if (!name)
8904640cde1SColin Riley     {
8914640cde1SColin Riley         error.SetErrorString("invalid kernel name");
8924640cde1SColin Riley         return;
8934640cde1SColin Riley     }
8944640cde1SColin Riley 
895*7dc7771cSEwan Crawford     InitSearchFilter(target);
89698156583SEwan Crawford 
8974640cde1SColin Riley     ConstString kernel_name(name);
898*7dc7771cSEwan Crawford     BreakpointSP bp = CreateKernelBreakpoint(kernel_name);
89998156583SEwan Crawford     if (bp)
90098156583SEwan Crawford         bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false);
9014640cde1SColin Riley 
9024640cde1SColin Riley     return;
9034640cde1SColin Riley }
9044640cde1SColin Riley 
9054640cde1SColin Riley void
9065ec532a9SColin Riley RenderScriptRuntime::DumpModules(Stream &strm) const
9075ec532a9SColin Riley {
9085ec532a9SColin Riley     strm.Printf("RenderScript Modules:");
9095ec532a9SColin Riley     strm.EOL();
9105ec532a9SColin Riley     strm.IndentMore();
9115ec532a9SColin Riley     for (const auto &module : m_rsmodules)
9125ec532a9SColin Riley     {
9134640cde1SColin Riley         module->Dump(strm);
9145ec532a9SColin Riley     }
9155ec532a9SColin Riley     strm.IndentLess();
9165ec532a9SColin Riley }
9175ec532a9SColin Riley 
9185ec532a9SColin Riley void
9195ec532a9SColin Riley RSModuleDescriptor::Dump(Stream &strm) const
9205ec532a9SColin Riley {
9215ec532a9SColin Riley     strm.Indent();
9225ec532a9SColin Riley     m_module->GetFileSpec().Dump(&strm);
9234640cde1SColin Riley     m_module->ParseAllDebugSymbols();
9244640cde1SColin Riley     if(m_module->GetNumCompileUnits())
9254640cde1SColin Riley     {
9264640cde1SColin Riley         strm.Indent("Debug info loaded.");
9274640cde1SColin Riley     }
9284640cde1SColin Riley     else
9294640cde1SColin Riley     {
9304640cde1SColin Riley         strm.Indent("Debug info does not exist.");
9314640cde1SColin Riley     }
9325ec532a9SColin Riley     strm.EOL();
9335ec532a9SColin Riley     strm.IndentMore();
9345ec532a9SColin Riley     strm.Indent();
935189598edSColin Riley     strm.Printf("Globals: %" PRIu64, static_cast<uint64_t>(m_globals.size()));
9365ec532a9SColin Riley     strm.EOL();
9375ec532a9SColin Riley     strm.IndentMore();
9385ec532a9SColin Riley     for (const auto &global : m_globals)
9395ec532a9SColin Riley     {
9405ec532a9SColin Riley         global.Dump(strm);
9415ec532a9SColin Riley     }
9425ec532a9SColin Riley     strm.IndentLess();
9435ec532a9SColin Riley     strm.Indent();
944189598edSColin Riley     strm.Printf("Kernels: %" PRIu64, static_cast<uint64_t>(m_kernels.size()));
9455ec532a9SColin Riley     strm.EOL();
9465ec532a9SColin Riley     strm.IndentMore();
9475ec532a9SColin Riley     for (const auto &kernel : m_kernels)
9485ec532a9SColin Riley     {
9495ec532a9SColin Riley         kernel.Dump(strm);
9505ec532a9SColin Riley     }
9514640cde1SColin Riley     strm.Printf("Pragmas: %"  PRIu64 , static_cast<uint64_t>(m_pragmas.size()));
9524640cde1SColin Riley     strm.EOL();
9534640cde1SColin Riley     strm.IndentMore();
9544640cde1SColin Riley     for (const auto &key_val : m_pragmas)
9554640cde1SColin Riley     {
9564640cde1SColin Riley         strm.Printf("%s: %s", key_val.first.c_str(), key_val.second.c_str());
9574640cde1SColin Riley         strm.EOL();
9584640cde1SColin Riley     }
9595ec532a9SColin Riley     strm.IndentLess(4);
9605ec532a9SColin Riley }
9615ec532a9SColin Riley 
9625ec532a9SColin Riley void
9635ec532a9SColin Riley RSGlobalDescriptor::Dump(Stream &strm) const
9645ec532a9SColin Riley {
9655ec532a9SColin Riley     strm.Indent(m_name.AsCString());
9664640cde1SColin Riley     VariableList var_list;
9674640cde1SColin Riley     m_module->m_module->FindGlobalVariables(m_name, nullptr, true, 1U, var_list);
9684640cde1SColin Riley     if (var_list.GetSize() == 1)
9694640cde1SColin Riley     {
9704640cde1SColin Riley         auto var = var_list.GetVariableAtIndex(0);
9714640cde1SColin Riley         auto type = var->GetType();
9724640cde1SColin Riley         if(type)
9734640cde1SColin Riley         {
9744640cde1SColin Riley             strm.Printf(" - ");
9754640cde1SColin Riley             type->DumpTypeName(&strm);
9764640cde1SColin Riley         }
9774640cde1SColin Riley         else
9784640cde1SColin Riley         {
9794640cde1SColin Riley             strm.Printf(" - Unknown Type");
9804640cde1SColin Riley         }
9814640cde1SColin Riley     }
9824640cde1SColin Riley     else
9834640cde1SColin Riley     {
9844640cde1SColin Riley         strm.Printf(" - variable identified, but not found in binary");
9854640cde1SColin Riley         const Symbol* s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData);
9864640cde1SColin Riley         if (s)
9874640cde1SColin Riley         {
9884640cde1SColin Riley             strm.Printf(" (symbol exists) ");
9894640cde1SColin Riley         }
9904640cde1SColin Riley     }
9914640cde1SColin Riley 
9925ec532a9SColin Riley     strm.EOL();
9935ec532a9SColin Riley }
9945ec532a9SColin Riley 
9955ec532a9SColin Riley void
9965ec532a9SColin Riley RSKernelDescriptor::Dump(Stream &strm) const
9975ec532a9SColin Riley {
9985ec532a9SColin Riley     strm.Indent(m_name.AsCString());
9995ec532a9SColin Riley     strm.EOL();
10005ec532a9SColin Riley }
10015ec532a9SColin Riley 
10025ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed
10035ec532a9SColin Riley {
10045ec532a9SColin Riley   private:
10055ec532a9SColin Riley   public:
10065ec532a9SColin Riley     CommandObjectRenderScriptRuntimeModuleProbe(CommandInterpreter &interpreter)
10075ec532a9SColin Riley         : CommandObjectParsed(interpreter, "renderscript module probe",
10085ec532a9SColin Riley                               "Initiates a Probe of all loaded modules for kernels and other renderscript objects.",
10095ec532a9SColin Riley                               "renderscript module probe",
1010e87764f2SEnrico Granata                               eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBeLaunched)
10115ec532a9SColin Riley     {
10125ec532a9SColin Riley     }
10135ec532a9SColin Riley 
10145ec532a9SColin Riley     ~CommandObjectRenderScriptRuntimeModuleProbe() {}
10155ec532a9SColin Riley 
10165ec532a9SColin Riley     bool
10175ec532a9SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
10185ec532a9SColin Riley     {
10195ec532a9SColin Riley         const size_t argc = command.GetArgumentCount();
10205ec532a9SColin Riley         if (argc == 0)
10215ec532a9SColin Riley         {
10225ec532a9SColin Riley             Target *target = m_exe_ctx.GetTargetPtr();
10235ec532a9SColin Riley             RenderScriptRuntime *runtime =
10245ec532a9SColin Riley                 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
10255ec532a9SColin Riley             auto module_list = target->GetImages();
10265ec532a9SColin Riley             bool new_rs_details = runtime->ProbeModules(module_list);
10275ec532a9SColin Riley             if (new_rs_details)
10285ec532a9SColin Riley             {
10295ec532a9SColin Riley                 result.AppendMessage("New renderscript modules added to runtime model.");
10305ec532a9SColin Riley             }
10315ec532a9SColin Riley             result.SetStatus(eReturnStatusSuccessFinishResult);
10325ec532a9SColin Riley             return true;
10335ec532a9SColin Riley         }
10345ec532a9SColin Riley 
10355ec532a9SColin Riley         result.AppendErrorWithFormat("'%s' takes no arguments", m_cmd_name.c_str());
10365ec532a9SColin Riley         result.SetStatus(eReturnStatusFailed);
10375ec532a9SColin Riley         return false;
10385ec532a9SColin Riley     }
10395ec532a9SColin Riley };
10405ec532a9SColin Riley 
10415ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed
10425ec532a9SColin Riley {
10435ec532a9SColin Riley   private:
10445ec532a9SColin Riley   public:
10455ec532a9SColin Riley     CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter)
10465ec532a9SColin Riley         : CommandObjectParsed(interpreter, "renderscript module dump",
10475ec532a9SColin Riley                               "Dumps renderscript specific information for all modules.", "renderscript module dump",
1048e87764f2SEnrico Granata                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
10495ec532a9SColin Riley     {
10505ec532a9SColin Riley     }
10515ec532a9SColin Riley 
10525ec532a9SColin Riley     ~CommandObjectRenderScriptRuntimeModuleDump() {}
10535ec532a9SColin Riley 
10545ec532a9SColin Riley     bool
10555ec532a9SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
10565ec532a9SColin Riley     {
10575ec532a9SColin Riley         RenderScriptRuntime *runtime =
10585ec532a9SColin Riley             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
10595ec532a9SColin Riley         runtime->DumpModules(result.GetOutputStream());
10605ec532a9SColin Riley         result.SetStatus(eReturnStatusSuccessFinishResult);
10615ec532a9SColin Riley         return true;
10625ec532a9SColin Riley     }
10635ec532a9SColin Riley };
10645ec532a9SColin Riley 
10655ec532a9SColin Riley class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword
10665ec532a9SColin Riley {
10675ec532a9SColin Riley   private:
10685ec532a9SColin Riley   public:
10695ec532a9SColin Riley     CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter)
10705ec532a9SColin Riley         : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with renderscript modules.",
10715ec532a9SColin Riley                                  NULL)
10725ec532a9SColin Riley     {
10735ec532a9SColin Riley         LoadSubCommand("probe", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleProbe(interpreter)));
10745ec532a9SColin Riley         LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter)));
10755ec532a9SColin Riley     }
10765ec532a9SColin Riley 
10775ec532a9SColin Riley     ~CommandObjectRenderScriptRuntimeModule() {}
10785ec532a9SColin Riley };
10795ec532a9SColin Riley 
10804640cde1SColin Riley class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed
10814640cde1SColin Riley {
10824640cde1SColin Riley   private:
10834640cde1SColin Riley   public:
10844640cde1SColin Riley     CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter)
10854640cde1SColin Riley         : CommandObjectParsed(interpreter, "renderscript kernel list",
10864640cde1SColin Riley                               "Lists renderscript kernel names and associated script resources.", "renderscript kernel list",
10874640cde1SColin Riley                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
10884640cde1SColin Riley     {
10894640cde1SColin Riley     }
10904640cde1SColin Riley 
10914640cde1SColin Riley     ~CommandObjectRenderScriptRuntimeKernelList() {}
10924640cde1SColin Riley 
10934640cde1SColin Riley     bool
10944640cde1SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
10954640cde1SColin Riley     {
10964640cde1SColin Riley         RenderScriptRuntime *runtime =
10974640cde1SColin Riley             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
10984640cde1SColin Riley         runtime->DumpKernels(result.GetOutputStream());
10994640cde1SColin Riley         result.SetStatus(eReturnStatusSuccessFinishResult);
11004640cde1SColin Riley         return true;
11014640cde1SColin Riley     }
11024640cde1SColin Riley };
11034640cde1SColin Riley 
1104*7dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpointSet : public CommandObjectParsed
11054640cde1SColin Riley {
11064640cde1SColin Riley   private:
11074640cde1SColin Riley   public:
1108*7dc7771cSEwan Crawford     CommandObjectRenderScriptRuntimeKernelBreakpointSet(CommandInterpreter &interpreter)
1109*7dc7771cSEwan Crawford         : CommandObjectParsed(interpreter, "renderscript kernel breakpoint set",
1110*7dc7771cSEwan Crawford                               "Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint set <kernel_name>",
11114640cde1SColin Riley                               eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
11124640cde1SColin Riley     {
11134640cde1SColin Riley     }
11144640cde1SColin Riley 
1115*7dc7771cSEwan Crawford     ~CommandObjectRenderScriptRuntimeKernelBreakpointSet() {}
11164640cde1SColin Riley 
11174640cde1SColin Riley     bool
11184640cde1SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
11194640cde1SColin Riley     {
11204640cde1SColin Riley         const size_t argc = command.GetArgumentCount();
11214640cde1SColin Riley         if (argc == 1)
11224640cde1SColin Riley         {
11234640cde1SColin Riley             RenderScriptRuntime *runtime =
11244640cde1SColin Riley                 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
11254640cde1SColin Riley 
11264640cde1SColin Riley             Error error;
112798156583SEwan Crawford             runtime->AttemptBreakpointAtKernelName(result.GetOutputStream(), command.GetArgumentAtIndex(0),
112898156583SEwan Crawford                                                    error, m_exe_ctx.GetTargetSP());
11294640cde1SColin Riley 
11304640cde1SColin Riley             if (error.Success())
11314640cde1SColin Riley             {
11324640cde1SColin Riley                 result.AppendMessage("Breakpoint(s) created");
11334640cde1SColin Riley                 result.SetStatus(eReturnStatusSuccessFinishResult);
11344640cde1SColin Riley                 return true;
11354640cde1SColin Riley             }
11364640cde1SColin Riley             result.SetStatus(eReturnStatusFailed);
11374640cde1SColin Riley             result.AppendErrorWithFormat("Error: %s", error.AsCString());
11384640cde1SColin Riley             return false;
11394640cde1SColin Riley         }
11404640cde1SColin Riley 
11414640cde1SColin Riley         result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name", m_cmd_name.c_str());
11424640cde1SColin Riley         result.SetStatus(eReturnStatusFailed);
11434640cde1SColin Riley         return false;
11444640cde1SColin Riley     }
11454640cde1SColin Riley };
11464640cde1SColin Riley 
1147*7dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpointAll : public CommandObjectParsed
1148*7dc7771cSEwan Crawford {
1149*7dc7771cSEwan Crawford   private:
1150*7dc7771cSEwan Crawford   public:
1151*7dc7771cSEwan Crawford     CommandObjectRenderScriptRuntimeKernelBreakpointAll(CommandInterpreter &interpreter)
1152*7dc7771cSEwan Crawford         : CommandObjectParsed(interpreter, "renderscript kernel breakpoint all",
1153*7dc7771cSEwan Crawford                               "Automatically sets a breakpoint on all renderscript kernels that are or will be loaded.\n"
1154*7dc7771cSEwan Crawford                               "Disabling option means breakpoints will no longer be set on any kernels loaded in the future, "
1155*7dc7771cSEwan Crawford                               "but does not remove currently set breakpoints.",
1156*7dc7771cSEwan Crawford                               "renderscript kernel breakpoint all <enable/disable>",
1157*7dc7771cSEwan Crawford                               eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
1158*7dc7771cSEwan Crawford     {
1159*7dc7771cSEwan Crawford     }
1160*7dc7771cSEwan Crawford 
1161*7dc7771cSEwan Crawford     ~CommandObjectRenderScriptRuntimeKernelBreakpointAll() {}
1162*7dc7771cSEwan Crawford 
1163*7dc7771cSEwan Crawford     bool
1164*7dc7771cSEwan Crawford     DoExecute(Args &command, CommandReturnObject &result)
1165*7dc7771cSEwan Crawford     {
1166*7dc7771cSEwan Crawford         const size_t argc = command.GetArgumentCount();
1167*7dc7771cSEwan Crawford         if (argc != 1)
1168*7dc7771cSEwan Crawford         {
1169*7dc7771cSEwan Crawford             result.AppendErrorWithFormat("'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str());
1170*7dc7771cSEwan Crawford             result.SetStatus(eReturnStatusFailed);
1171*7dc7771cSEwan Crawford             return false;
1172*7dc7771cSEwan Crawford         }
1173*7dc7771cSEwan Crawford 
1174*7dc7771cSEwan Crawford         RenderScriptRuntime *runtime =
1175*7dc7771cSEwan Crawford           static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
1176*7dc7771cSEwan Crawford 
1177*7dc7771cSEwan Crawford         bool do_break = false;
1178*7dc7771cSEwan Crawford         const char* argument = command.GetArgumentAtIndex(0);
1179*7dc7771cSEwan Crawford         if (strcmp(argument, "enable") == 0)
1180*7dc7771cSEwan Crawford         {
1181*7dc7771cSEwan Crawford             do_break = true;
1182*7dc7771cSEwan Crawford             result.AppendMessage("Breakpoints will be set on all kernels.");
1183*7dc7771cSEwan Crawford         }
1184*7dc7771cSEwan Crawford         else if (strcmp(argument, "disable") == 0)
1185*7dc7771cSEwan Crawford         {
1186*7dc7771cSEwan Crawford             do_break = false;
1187*7dc7771cSEwan Crawford             result.AppendMessage("Breakpoints will not be set on any new kernels.");
1188*7dc7771cSEwan Crawford         }
1189*7dc7771cSEwan Crawford         else
1190*7dc7771cSEwan Crawford         {
1191*7dc7771cSEwan Crawford             result.AppendErrorWithFormat("Argument must be either 'enable' or 'disable'");
1192*7dc7771cSEwan Crawford             result.SetStatus(eReturnStatusFailed);
1193*7dc7771cSEwan Crawford             return false;
1194*7dc7771cSEwan Crawford         }
1195*7dc7771cSEwan Crawford 
1196*7dc7771cSEwan Crawford         runtime->SetBreakAllKernels(do_break, m_exe_ctx.GetTargetSP());
1197*7dc7771cSEwan Crawford 
1198*7dc7771cSEwan Crawford         result.SetStatus(eReturnStatusSuccessFinishResult);
1199*7dc7771cSEwan Crawford         return true;
1200*7dc7771cSEwan Crawford     }
1201*7dc7771cSEwan Crawford };
1202*7dc7771cSEwan Crawford 
1203*7dc7771cSEwan Crawford class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectMultiword
1204*7dc7771cSEwan Crawford {
1205*7dc7771cSEwan Crawford   private:
1206*7dc7771cSEwan Crawford   public:
1207*7dc7771cSEwan Crawford     CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter)
1208*7dc7771cSEwan Crawford         : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that generate breakpoints on renderscript kernels.",
1209*7dc7771cSEwan Crawford                                  nullptr)
1210*7dc7771cSEwan Crawford     {
1211*7dc7771cSEwan Crawford         LoadSubCommand("set", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointSet(interpreter)));
1212*7dc7771cSEwan Crawford         LoadSubCommand("all", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointAll(interpreter)));
1213*7dc7771cSEwan Crawford     }
1214*7dc7771cSEwan Crawford 
1215*7dc7771cSEwan Crawford     ~CommandObjectRenderScriptRuntimeKernelBreakpoint() {}
1216*7dc7771cSEwan Crawford };
1217*7dc7771cSEwan Crawford 
12184640cde1SColin Riley class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword
12194640cde1SColin Riley {
12204640cde1SColin Riley   private:
12214640cde1SColin Riley   public:
12224640cde1SColin Riley     CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter)
12234640cde1SColin Riley         : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with renderscript kernels.",
12244640cde1SColin Riley                                  NULL)
12254640cde1SColin Riley     {
12264640cde1SColin Riley         LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(interpreter)));
12274640cde1SColin Riley         LoadSubCommand("breakpoint", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter)));
12284640cde1SColin Riley     }
12294640cde1SColin Riley 
12304640cde1SColin Riley     ~CommandObjectRenderScriptRuntimeKernel() {}
12314640cde1SColin Riley };
12324640cde1SColin Riley 
12334640cde1SColin Riley class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed
12344640cde1SColin Riley {
12354640cde1SColin Riley   private:
12364640cde1SColin Riley   public:
12374640cde1SColin Riley     CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter)
12384640cde1SColin Riley         : CommandObjectParsed(interpreter, "renderscript context dump",
12394640cde1SColin Riley                               "Dumps renderscript context information.", "renderscript context dump",
12404640cde1SColin Riley                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
12414640cde1SColin Riley     {
12424640cde1SColin Riley     }
12434640cde1SColin Riley 
12444640cde1SColin Riley     ~CommandObjectRenderScriptRuntimeContextDump() {}
12454640cde1SColin Riley 
12464640cde1SColin Riley     bool
12474640cde1SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
12484640cde1SColin Riley     {
12494640cde1SColin Riley         RenderScriptRuntime *runtime =
12504640cde1SColin Riley             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
12514640cde1SColin Riley         runtime->DumpContexts(result.GetOutputStream());
12524640cde1SColin Riley         result.SetStatus(eReturnStatusSuccessFinishResult);
12534640cde1SColin Riley         return true;
12544640cde1SColin Riley     }
12554640cde1SColin Riley };
12564640cde1SColin Riley 
12574640cde1SColin Riley class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword
12584640cde1SColin Riley {
12594640cde1SColin Riley   private:
12604640cde1SColin Riley   public:
12614640cde1SColin Riley     CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter)
12624640cde1SColin Riley         : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with renderscript contexts.",
12634640cde1SColin Riley                                  NULL)
12644640cde1SColin Riley     {
12654640cde1SColin Riley         LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(interpreter)));
12664640cde1SColin Riley     }
12674640cde1SColin Riley 
12684640cde1SColin Riley     ~CommandObjectRenderScriptRuntimeContext() {}
12694640cde1SColin Riley };
12704640cde1SColin Riley 
12714640cde1SColin Riley class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed
12724640cde1SColin Riley {
12734640cde1SColin Riley   private:
12744640cde1SColin Riley   public:
12754640cde1SColin Riley     CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter)
12764640cde1SColin Riley         : CommandObjectParsed(interpreter, "renderscript status",
12774640cde1SColin Riley                               "Displays current renderscript runtime status.", "renderscript status",
12784640cde1SColin Riley                               eCommandRequiresProcess | eCommandProcessMustBeLaunched)
12794640cde1SColin Riley     {
12804640cde1SColin Riley     }
12814640cde1SColin Riley 
12824640cde1SColin Riley     ~CommandObjectRenderScriptRuntimeStatus() {}
12834640cde1SColin Riley 
12844640cde1SColin Riley     bool
12854640cde1SColin Riley     DoExecute(Args &command, CommandReturnObject &result)
12864640cde1SColin Riley     {
12874640cde1SColin Riley         RenderScriptRuntime *runtime =
12884640cde1SColin Riley             (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
12894640cde1SColin Riley         runtime->Status(result.GetOutputStream());
12904640cde1SColin Riley         result.SetStatus(eReturnStatusSuccessFinishResult);
12914640cde1SColin Riley         return true;
12924640cde1SColin Riley     }
12934640cde1SColin Riley };
12944640cde1SColin Riley 
12955ec532a9SColin Riley class CommandObjectRenderScriptRuntime : public CommandObjectMultiword
12965ec532a9SColin Riley {
12975ec532a9SColin Riley   public:
12985ec532a9SColin Riley     CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter)
12995ec532a9SColin Riley         : CommandObjectMultiword(interpreter, "renderscript", "A set of commands for operating on renderscript.",
13005ec532a9SColin Riley                                  "renderscript <subcommand> [<subcommand-options>]")
13015ec532a9SColin Riley     {
13025ec532a9SColin Riley         LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter)));
13034640cde1SColin Riley         LoadSubCommand("status", CommandObjectSP(new CommandObjectRenderScriptRuntimeStatus(interpreter)));
13044640cde1SColin Riley         LoadSubCommand("kernel", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernel(interpreter)));
13054640cde1SColin Riley         LoadSubCommand("context", CommandObjectSP(new CommandObjectRenderScriptRuntimeContext(interpreter)));
13065ec532a9SColin Riley     }
13075ec532a9SColin Riley 
13085ec532a9SColin Riley     ~CommandObjectRenderScriptRuntime() {}
13095ec532a9SColin Riley };
1310ef20b08fSColin Riley 
1311ef20b08fSColin Riley void
1312ef20b08fSColin Riley RenderScriptRuntime::Initiate()
13135ec532a9SColin Riley {
1314ef20b08fSColin Riley     assert(!m_initiated);
13155ec532a9SColin Riley }
1316ef20b08fSColin Riley 
1317ef20b08fSColin Riley RenderScriptRuntime::RenderScriptRuntime(Process *process)
1318*7dc7771cSEwan Crawford     : lldb_private::CPPLanguageRuntime(process), m_initiated(false), m_debuggerPresentFlagged(false),
1319*7dc7771cSEwan Crawford       m_breakAllKernels(false)
1320ef20b08fSColin Riley {
13214640cde1SColin Riley     ModulesDidLoad(process->GetTarget().GetImages());
1322ef20b08fSColin Riley }
13234640cde1SColin Riley 
13244640cde1SColin Riley lldb::CommandObjectSP
13254640cde1SColin Riley RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter& interpreter)
13264640cde1SColin Riley {
13274640cde1SColin Riley     static CommandObjectSP command_object;
13284640cde1SColin Riley     if(!command_object)
13294640cde1SColin Riley     {
13304640cde1SColin Riley         command_object.reset(new CommandObjectRenderScriptRuntime(interpreter));
13314640cde1SColin Riley     }
13324640cde1SColin Riley     return command_object;
13334640cde1SColin Riley }
13344640cde1SColin Riley 
1335