| //===-- RenderScriptRuntime.cpp ---------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "RenderScriptRuntime.h" |
| |
| #include "lldb/Core/ConstString.h" |
| #include "lldb/Core/Debugger.h" |
| #include "lldb/Core/Error.h" |
| #include "lldb/Core/Log.h" |
| #include "lldb/Core/PluginManager.h" |
| #include "lldb/Symbol/Symbol.h" |
| #include "lldb/Target/Process.h" |
| #include "lldb/Target/Target.h" |
| #include "lldb/Interpreter/Args.h" |
| #include "lldb/Interpreter/Options.h" |
| #include "lldb/Interpreter/CommandInterpreter.h" |
| #include "lldb/Interpreter/CommandReturnObject.h" |
| #include "lldb/Interpreter/CommandObjectMultiword.h" |
| |
| using namespace lldb; |
| using namespace lldb_private; |
| |
| //------------------------------------------------------------------ |
| // Static Functions |
| //------------------------------------------------------------------ |
| LanguageRuntime * |
| RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType language) |
| { |
| |
| if (language == eLanguageTypeExtRenderScript) |
| return new RenderScriptRuntime(process); |
| else |
| return NULL; |
| } |
| |
| void |
| RenderScriptRuntime::Initialize() |
| { |
| PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance); |
| } |
| |
| void |
| RenderScriptRuntime::Terminate() |
| { |
| PluginManager::UnregisterPlugin(CreateInstance); |
| } |
| |
| lldb_private::ConstString |
| RenderScriptRuntime::GetPluginNameStatic() |
| { |
| static ConstString g_name("renderscript"); |
| return g_name; |
| } |
| |
| //------------------------------------------------------------------ |
| // PluginInterface protocol |
| //------------------------------------------------------------------ |
| lldb_private::ConstString |
| RenderScriptRuntime::GetPluginName() |
| { |
| return GetPluginNameStatic(); |
| } |
| |
| uint32_t |
| RenderScriptRuntime::GetPluginVersion() |
| { |
| return 1; |
| } |
| |
| bool |
| RenderScriptRuntime::IsVTableName(const char *name) |
| { |
| return false; |
| } |
| |
| bool |
| RenderScriptRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic, |
| TypeAndOrName &class_type_or_name, Address &address) |
| { |
| return false; |
| } |
| |
| bool |
| RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value) |
| { |
| return false; |
| } |
| |
| lldb::BreakpointResolverSP |
| RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) |
| { |
| BreakpointResolverSP resolver_sp; |
| return resolver_sp; |
| } |
| |
| bool |
| RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp) |
| { |
| if (module_sp) |
| { |
| for (const auto &rs_module : m_rsmodules) |
| { |
| if (rs_module.m_module == module_sp) |
| return false; |
| } |
| RSModuleDescriptor module_desc(module_sp); |
| if (module_desc.ParseRSInfo()) |
| { |
| m_rsmodules.push_back(module_desc); |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| // The maximum line length of an .rs.info packet |
| #define MAXLINE 500 |
| |
| // The .rs.info symbol in renderscript modules contains a string which needs to be parsed. |
| // The string is basic and is parsed on a line by line basis. |
| bool |
| RSModuleDescriptor::ParseRSInfo() |
| { |
| const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData); |
| if (info_sym) |
| { |
| const addr_t addr = info_sym->GetAddress().GetFileAddress(); |
| const addr_t size = info_sym->GetByteSize(); |
| const FileSpec fs = m_module->GetFileSpec(); |
| |
| DataBufferSP buffer = fs.ReadFileContents(addr, size); |
| |
| if (!buffer) |
| return false; |
| |
| std::string info((const char *)buffer->GetBytes()); |
| |
| std::vector<std::string> info_lines; |
| size_t lpos = info.find_first_of("\n"); |
| while (lpos != std::string::npos) |
| { |
| info_lines.push_back(info.substr(0, lpos)); |
| info = info.substr(lpos + 1); |
| lpos = info.find_first_of("\n"); |
| } |
| size_t offset = 0; |
| while (offset < info_lines.size()) |
| { |
| std::string line = info_lines[offset]; |
| // Parse directives |
| uint32_t numDefns = 0; |
| if (sscanf(line.c_str(), "exportVarCount: %u", &numDefns) == 1) |
| { |
| while (numDefns--) |
| m_globals.push_back(RSGlobalDescriptor(*this, info_lines[++offset].c_str())); |
| } |
| else if (sscanf(line.c_str(), "exportFuncCount: %u", &numDefns) == 1) |
| { |
| } |
| else if (sscanf(line.c_str(), "exportForEachCount: %u", &numDefns) == 1) |
| { |
| char name[MAXLINE]; |
| while (numDefns--) |
| { |
| uint32_t slot = 0; |
| name[0] = '\0'; |
| if (sscanf(info_lines[++offset].c_str(), "%u - %s", &slot, &name[0]) == 2) |
| { |
| m_kernels.push_back(RSKernelDescriptor(*this, name, slot)); |
| } |
| } |
| } |
| else if (sscanf(line.c_str(), "objectSlotCount: %u", &numDefns) == 1) |
| { |
| } |
| |
| offset++; |
| } |
| return m_kernels.size() > 0; |
| } |
| return false; |
| } |
| |
| bool |
| RenderScriptRuntime::ProbeModules(const ModuleList module_list) |
| { |
| bool rs_found = false; |
| size_t num_modules = module_list.GetSize(); |
| for (size_t i = 0; i < num_modules; i++) |
| { |
| auto module = module_list.GetModuleAtIndex(i); |
| rs_found |= LoadModule(module); |
| } |
| return rs_found; |
| } |
| |
| void |
| RenderScriptRuntime::DumpModules(Stream &strm) const |
| { |
| strm.Printf("RenderScript Modules:"); |
| strm.EOL(); |
| strm.IndentMore(); |
| for (const auto &module : m_rsmodules) |
| { |
| module.Dump(strm); |
| } |
| strm.IndentLess(); |
| } |
| |
| void |
| RSModuleDescriptor::Dump(Stream &strm) const |
| { |
| strm.Indent(); |
| m_module->GetFileSpec().Dump(&strm); |
| strm.EOL(); |
| strm.IndentMore(); |
| strm.Indent(); |
| strm.Printf("Globals: %u", m_globals.size()); |
| strm.EOL(); |
| strm.IndentMore(); |
| for (const auto &global : m_globals) |
| { |
| global.Dump(strm); |
| } |
| strm.IndentLess(); |
| strm.Indent(); |
| strm.Printf("Kernels: %u", m_kernels.size()); |
| strm.EOL(); |
| strm.IndentMore(); |
| for (const auto &kernel : m_kernels) |
| { |
| kernel.Dump(strm); |
| } |
| strm.IndentLess(4); |
| } |
| |
| void |
| RSGlobalDescriptor::Dump(Stream &strm) const |
| { |
| strm.Indent(m_name.AsCString()); |
| strm.EOL(); |
| } |
| |
| void |
| RSKernelDescriptor::Dump(Stream &strm) const |
| { |
| strm.Indent(m_name.AsCString()); |
| strm.EOL(); |
| } |
| |
| class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed |
| { |
| private: |
| public: |
| CommandObjectRenderScriptRuntimeModuleProbe(CommandInterpreter &interpreter) |
| : CommandObjectParsed(interpreter, "renderscript module probe", |
| "Initiates a Probe of all loaded modules for kernels and other renderscript objects.", |
| "renderscript module probe", |
| eFlagRequiresTarget | eFlagRequiresProcess | eFlagProcessMustBeLaunched) |
| { |
| } |
| |
| ~CommandObjectRenderScriptRuntimeModuleProbe() {} |
| |
| bool |
| DoExecute(Args &command, CommandReturnObject &result) |
| { |
| const size_t argc = command.GetArgumentCount(); |
| if (argc == 0) |
| { |
| Target *target = m_exe_ctx.GetTargetPtr(); |
| RenderScriptRuntime *runtime = |
| (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); |
| auto module_list = target->GetImages(); |
| bool new_rs_details = runtime->ProbeModules(module_list); |
| if (new_rs_details) |
| { |
| result.AppendMessage("New renderscript modules added to runtime model."); |
| } |
| result.SetStatus(eReturnStatusSuccessFinishResult); |
| return true; |
| } |
| |
| result.AppendErrorWithFormat("'%s' takes no arguments", m_cmd_name.c_str()); |
| result.SetStatus(eReturnStatusFailed); |
| return false; |
| } |
| }; |
| |
| class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed |
| { |
| private: |
| public: |
| CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter) |
| : CommandObjectParsed(interpreter, "renderscript module dump", |
| "Dumps renderscript specific information for all modules.", "renderscript module dump", |
| eFlagRequiresProcess | eFlagProcessMustBeLaunched) |
| { |
| } |
| |
| ~CommandObjectRenderScriptRuntimeModuleDump() {} |
| |
| bool |
| DoExecute(Args &command, CommandReturnObject &result) |
| { |
| RenderScriptRuntime *runtime = |
| (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); |
| runtime->DumpModules(result.GetOutputStream()); |
| result.SetStatus(eReturnStatusSuccessFinishResult); |
| return true; |
| } |
| }; |
| |
| class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword |
| { |
| private: |
| public: |
| CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter) |
| : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with renderscript modules.", |
| NULL) |
| { |
| LoadSubCommand("probe", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleProbe(interpreter))); |
| LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter))); |
| } |
| |
| ~CommandObjectRenderScriptRuntimeModule() {} |
| }; |
| |
| class CommandObjectRenderScriptRuntime : public CommandObjectMultiword |
| { |
| public: |
| CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter) |
| : CommandObjectMultiword(interpreter, "renderscript", "A set of commands for operating on renderscript.", |
| "renderscript <subcommand> [<subcommand-options>]") |
| { |
| LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter))); |
| } |
| |
| ~CommandObjectRenderScriptRuntime() {} |
| }; |
| RenderScriptRuntime::RenderScriptRuntime(Process *process) |
| : lldb_private::CPPLanguageRuntime(process) |
| { |
| if (process) |
| { |
| CommandInterpreter &interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter(); |
| interpreter.AddCommand("renderscript", CommandObjectSP(new CommandObjectRenderScriptRuntime(interpreter)), |
| true); |
| } |
| } |