|
|
@@ -0,0 +1,356 @@ |
|
|
//===-- 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); |
|
|
} |
|
|
} |