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