blob: f35051af5b32d8a3f93524172df8a415ca08e547 [file] [log] [blame]
Colin Riley5ec532a2015-04-09 16:49:25 +00001//===-- RenderScriptRuntime.cpp ---------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "RenderScriptRuntime.h"
11
12#include "lldb/Core/ConstString.h"
13#include "lldb/Core/Debugger.h"
14#include "lldb/Core/Error.h"
15#include "lldb/Core/Log.h"
16#include "lldb/Core/PluginManager.h"
17#include "lldb/Symbol/Symbol.h"
18#include "lldb/Target/Process.h"
19#include "lldb/Target/Target.h"
20#include "lldb/Interpreter/Args.h"
21#include "lldb/Interpreter/Options.h"
22#include "lldb/Interpreter/CommandInterpreter.h"
23#include "lldb/Interpreter/CommandReturnObject.h"
24#include "lldb/Interpreter/CommandObjectMultiword.h"
25
26using namespace lldb;
27using namespace lldb_private;
28
29//------------------------------------------------------------------
30// Static Functions
31//------------------------------------------------------------------
32LanguageRuntime *
33RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType language)
34{
35
36 if (language == eLanguageTypeExtRenderScript)
37 return new RenderScriptRuntime(process);
38 else
39 return NULL;
40}
41
42void
43RenderScriptRuntime::Initialize()
44{
45 PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance);
46}
47
48void
49RenderScriptRuntime::Terminate()
50{
51 PluginManager::UnregisterPlugin(CreateInstance);
52}
53
54lldb_private::ConstString
55RenderScriptRuntime::GetPluginNameStatic()
56{
57 static ConstString g_name("renderscript");
58 return g_name;
59}
60
61//------------------------------------------------------------------
62// PluginInterface protocol
63//------------------------------------------------------------------
64lldb_private::ConstString
65RenderScriptRuntime::GetPluginName()
66{
67 return GetPluginNameStatic();
68}
69
70uint32_t
71RenderScriptRuntime::GetPluginVersion()
72{
73 return 1;
74}
75
76bool
77RenderScriptRuntime::IsVTableName(const char *name)
78{
79 return false;
80}
81
82bool
83RenderScriptRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
84 TypeAndOrName &class_type_or_name, Address &address)
85{
86 return false;
87}
88
89bool
90RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value)
91{
92 return false;
93}
94
95lldb::BreakpointResolverSP
96RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp)
97{
98 BreakpointResolverSP resolver_sp;
99 return resolver_sp;
100}
101
102bool
103RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
104{
105 if (module_sp)
106 {
107 for (const auto &rs_module : m_rsmodules)
108 {
109 if (rs_module.m_module == module_sp)
110 return false;
111 }
112 RSModuleDescriptor module_desc(module_sp);
113 if (module_desc.ParseRSInfo())
114 {
115 m_rsmodules.push_back(module_desc);
116 return true;
117 }
118 }
119 return false;
120}
121
122// The maximum line length of an .rs.info packet
123#define MAXLINE 500
124
125// The .rs.info symbol in renderscript modules contains a string which needs to be parsed.
126// The string is basic and is parsed on a line by line basis.
127bool
128RSModuleDescriptor::ParseRSInfo()
129{
130 const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
131 if (info_sym)
132 {
133 const addr_t addr = info_sym->GetAddress().GetFileAddress();
134 const addr_t size = info_sym->GetByteSize();
135 const FileSpec fs = m_module->GetFileSpec();
136
137 DataBufferSP buffer = fs.ReadFileContents(addr, size);
138
139 if (!buffer)
140 return false;
141
142 std::string info((const char *)buffer->GetBytes());
143
144 std::vector<std::string> info_lines;
145 size_t lpos = info.find_first_of("\n");
146 while (lpos != std::string::npos)
147 {
148 info_lines.push_back(info.substr(0, lpos));
149 info = info.substr(lpos + 1);
150 lpos = info.find_first_of("\n");
151 }
152 size_t offset = 0;
153 while (offset < info_lines.size())
154 {
155 std::string line = info_lines[offset];
156 // Parse directives
157 uint32_t numDefns = 0;
158 if (sscanf(line.c_str(), "exportVarCount: %u", &numDefns) == 1)
159 {
160 while (numDefns--)
161 m_globals.push_back(RSGlobalDescriptor(*this, info_lines[++offset].c_str()));
162 }
163 else if (sscanf(line.c_str(), "exportFuncCount: %u", &numDefns) == 1)
164 {
165 }
166 else if (sscanf(line.c_str(), "exportForEachCount: %u", &numDefns) == 1)
167 {
168 char name[MAXLINE];
169 while (numDefns--)
170 {
171 uint32_t slot = 0;
172 name[0] = '\0';
173 if (sscanf(info_lines[++offset].c_str(), "%u - %s", &slot, &name[0]) == 2)
174 {
175 m_kernels.push_back(RSKernelDescriptor(*this, name, slot));
176 }
177 }
178 }
179 else if (sscanf(line.c_str(), "objectSlotCount: %u", &numDefns) == 1)
180 {
181 }
182
183 offset++;
184 }
185 return m_kernels.size() > 0;
186 }
187 return false;
188}
189
190bool
191RenderScriptRuntime::ProbeModules(const ModuleList module_list)
192{
193 bool rs_found = false;
194 size_t num_modules = module_list.GetSize();
195 for (size_t i = 0; i < num_modules; i++)
196 {
197 auto module = module_list.GetModuleAtIndex(i);
198 rs_found |= LoadModule(module);
199 }
200 return rs_found;
201}
202
203void
204RenderScriptRuntime::DumpModules(Stream &strm) const
205{
206 strm.Printf("RenderScript Modules:");
207 strm.EOL();
208 strm.IndentMore();
209 for (const auto &module : m_rsmodules)
210 {
211 module.Dump(strm);
212 }
213 strm.IndentLess();
214}
215
216void
217RSModuleDescriptor::Dump(Stream &strm) const
218{
219 strm.Indent();
220 m_module->GetFileSpec().Dump(&strm);
221 strm.EOL();
222 strm.IndentMore();
223 strm.Indent();
224 strm.Printf("Globals: %u", m_globals.size());
225 strm.EOL();
226 strm.IndentMore();
227 for (const auto &global : m_globals)
228 {
229 global.Dump(strm);
230 }
231 strm.IndentLess();
232 strm.Indent();
233 strm.Printf("Kernels: %u", m_kernels.size());
234 strm.EOL();
235 strm.IndentMore();
236 for (const auto &kernel : m_kernels)
237 {
238 kernel.Dump(strm);
239 }
240 strm.IndentLess(4);
241}
242
243void
244RSGlobalDescriptor::Dump(Stream &strm) const
245{
246 strm.Indent(m_name.AsCString());
247 strm.EOL();
248}
249
250void
251RSKernelDescriptor::Dump(Stream &strm) const
252{
253 strm.Indent(m_name.AsCString());
254 strm.EOL();
255}
256
257class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed
258{
259 private:
260 public:
261 CommandObjectRenderScriptRuntimeModuleProbe(CommandInterpreter &interpreter)
262 : CommandObjectParsed(interpreter, "renderscript module probe",
263 "Initiates a Probe of all loaded modules for kernels and other renderscript objects.",
264 "renderscript module probe",
265 eFlagRequiresTarget | eFlagRequiresProcess | eFlagProcessMustBeLaunched)
266 {
267 }
268
269 ~CommandObjectRenderScriptRuntimeModuleProbe() {}
270
271 bool
272 DoExecute(Args &command, CommandReturnObject &result)
273 {
274 const size_t argc = command.GetArgumentCount();
275 if (argc == 0)
276 {
277 Target *target = m_exe_ctx.GetTargetPtr();
278 RenderScriptRuntime *runtime =
279 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
280 auto module_list = target->GetImages();
281 bool new_rs_details = runtime->ProbeModules(module_list);
282 if (new_rs_details)
283 {
284 result.AppendMessage("New renderscript modules added to runtime model.");
285 }
286 result.SetStatus(eReturnStatusSuccessFinishResult);
287 return true;
288 }
289
290 result.AppendErrorWithFormat("'%s' takes no arguments", m_cmd_name.c_str());
291 result.SetStatus(eReturnStatusFailed);
292 return false;
293 }
294};
295
296class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed
297{
298 private:
299 public:
300 CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter)
301 : CommandObjectParsed(interpreter, "renderscript module dump",
302 "Dumps renderscript specific information for all modules.", "renderscript module dump",
303 eFlagRequiresProcess | eFlagProcessMustBeLaunched)
304 {
305 }
306
307 ~CommandObjectRenderScriptRuntimeModuleDump() {}
308
309 bool
310 DoExecute(Args &command, CommandReturnObject &result)
311 {
312 RenderScriptRuntime *runtime =
313 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
314 runtime->DumpModules(result.GetOutputStream());
315 result.SetStatus(eReturnStatusSuccessFinishResult);
316 return true;
317 }
318};
319
320class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword
321{
322 private:
323 public:
324 CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter)
325 : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with renderscript modules.",
326 NULL)
327 {
328 LoadSubCommand("probe", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleProbe(interpreter)));
329 LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter)));
330 }
331
332 ~CommandObjectRenderScriptRuntimeModule() {}
333};
334
335class CommandObjectRenderScriptRuntime : public CommandObjectMultiword
336{
337 public:
338 CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter)
339 : CommandObjectMultiword(interpreter, "renderscript", "A set of commands for operating on renderscript.",
340 "renderscript <subcommand> [<subcommand-options>]")
341 {
342 LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter)));
343 }
344
345 ~CommandObjectRenderScriptRuntime() {}
346};
347RenderScriptRuntime::RenderScriptRuntime(Process *process)
348 : lldb_private::CPPLanguageRuntime(process)
349{
350 if (process)
351 {
352 CommandInterpreter &interpreter = process->GetTarget().GetDebugger().GetCommandInterpreter();
353 interpreter.AddCommand("renderscript", CommandObjectSP(new CommandObjectRenderScriptRuntime(interpreter)),
354 true);
355 }
356}