1061da546Spatrick //===-- RenderScriptRuntime.h -----------------------------------*- C++ -*-===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9dda28197Spatrick #ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H
10dda28197Spatrick #define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H
11061da546Spatrick 
12061da546Spatrick #include <array>
13061da546Spatrick #include <map>
14061da546Spatrick #include <memory>
15061da546Spatrick #include <string>
16061da546Spatrick #include <vector>
17061da546Spatrick 
18061da546Spatrick #include "llvm/ADT/SmallVector.h"
19061da546Spatrick #include "llvm/ADT/StringRef.h"
20061da546Spatrick #include "lldb/Core/Module.h"
21061da546Spatrick #include "lldb/Expression/LLVMUserExpression.h"
22061da546Spatrick #include "lldb/Target/LanguageRuntime.h"
23061da546Spatrick #include "lldb/lldb-private.h"
24061da546Spatrick 
25061da546Spatrick #include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h"
26061da546Spatrick 
27dda28197Spatrick namespace clang {
28dda28197Spatrick class TargetOptions;
29dda28197Spatrick }
30dda28197Spatrick 
31061da546Spatrick namespace lldb_private {
32061da546Spatrick namespace lldb_renderscript {
33061da546Spatrick 
34061da546Spatrick typedef uint32_t RSSlot;
35061da546Spatrick class RSModuleDescriptor;
36061da546Spatrick struct RSGlobalDescriptor;
37061da546Spatrick struct RSKernelDescriptor;
38061da546Spatrick struct RSReductionDescriptor;
39061da546Spatrick struct RSScriptGroupDescriptor;
40061da546Spatrick 
41061da546Spatrick typedef std::shared_ptr<RSModuleDescriptor> RSModuleDescriptorSP;
42061da546Spatrick typedef std::shared_ptr<RSGlobalDescriptor> RSGlobalDescriptorSP;
43061da546Spatrick typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP;
44061da546Spatrick typedef std::shared_ptr<RSScriptGroupDescriptor> RSScriptGroupDescriptorSP;
45061da546Spatrick 
46061da546Spatrick struct RSCoordinate {
47be691f3bSpatrick   uint32_t x = 0, y = 0, z = 0;
48061da546Spatrick 
49be691f3bSpatrick   RSCoordinate() = default;
50061da546Spatrick 
51061da546Spatrick   bool operator==(const lldb_renderscript::RSCoordinate &rhs) {
52061da546Spatrick     return x == rhs.x && y == rhs.y && z == rhs.z;
53061da546Spatrick   }
54061da546Spatrick };
55061da546Spatrick 
56061da546Spatrick // Breakpoint Resolvers decide where a breakpoint is placed, so having our own
57061da546Spatrick // allows us to limit the search scope to RS kernel modules. As well as check
58061da546Spatrick // for .expand kernels as a fallback.
59061da546Spatrick class RSBreakpointResolver : public BreakpointResolver {
60061da546Spatrick public:
RSBreakpointResolver(const lldb::BreakpointSP & bp,ConstString name)61dda28197Spatrick   RSBreakpointResolver(const lldb::BreakpointSP &bp, ConstString name)
62061da546Spatrick       : BreakpointResolver(bp, BreakpointResolver::NameResolver),
63061da546Spatrick         m_kernel_name(name) {}
64061da546Spatrick 
GetDescription(Stream * strm)65061da546Spatrick   void GetDescription(Stream *strm) override {
66061da546Spatrick     if (strm)
67061da546Spatrick       strm->Printf("RenderScript kernel breakpoint for '%s'",
68061da546Spatrick                    m_kernel_name.AsCString());
69061da546Spatrick   }
70061da546Spatrick 
Dump(Stream * s)71061da546Spatrick   void Dump(Stream *s) const override {}
72061da546Spatrick 
73061da546Spatrick   Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
74061da546Spatrick                                           SymbolContext &context,
75061da546Spatrick                                           Address *addr) override;
76061da546Spatrick 
GetDepth()77061da546Spatrick   lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }
78061da546Spatrick 
79061da546Spatrick   lldb::BreakpointResolverSP
CopyForBreakpoint(lldb::BreakpointSP & breakpoint)80dda28197Spatrick   CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override {
81061da546Spatrick     lldb::BreakpointResolverSP ret_sp(
82dda28197Spatrick         new RSBreakpointResolver(breakpoint, m_kernel_name));
83061da546Spatrick     return ret_sp;
84061da546Spatrick   }
85061da546Spatrick 
86061da546Spatrick protected:
87061da546Spatrick   ConstString m_kernel_name;
88061da546Spatrick };
89061da546Spatrick 
90061da546Spatrick class RSReduceBreakpointResolver : public BreakpointResolver {
91061da546Spatrick public:
92061da546Spatrick   enum ReduceKernelTypeFlags {
93061da546Spatrick     eKernelTypeAll = ~(0),
94061da546Spatrick     eKernelTypeNone = 0,
95061da546Spatrick     eKernelTypeAccum = (1 << 0),
96061da546Spatrick     eKernelTypeInit = (1 << 1),
97061da546Spatrick     eKernelTypeComb = (1 << 2),
98061da546Spatrick     eKernelTypeOutC = (1 << 3),
99061da546Spatrick     eKernelTypeHalter = (1 << 4)
100061da546Spatrick   };
101061da546Spatrick 
102061da546Spatrick   RSReduceBreakpointResolver(
103dda28197Spatrick       const lldb::BreakpointSP &breakpoint, ConstString reduce_name,
104061da546Spatrick       std::vector<lldb_renderscript::RSModuleDescriptorSP> *rs_modules,
105061da546Spatrick       int kernel_types = eKernelTypeAll)
BreakpointResolver(breakpoint,BreakpointResolver::NameResolver)106061da546Spatrick       : BreakpointResolver(breakpoint, BreakpointResolver::NameResolver),
107061da546Spatrick         m_reduce_name(reduce_name), m_rsmodules(rs_modules),
108061da546Spatrick         m_kernel_types(kernel_types) {
109061da546Spatrick     // The reduce breakpoint resolver handles adding breakpoints for named
110061da546Spatrick     // reductions.
111061da546Spatrick     // Breakpoints will be resolved for all constituent kernels in the named
112061da546Spatrick     // reduction
113061da546Spatrick   }
114061da546Spatrick 
GetDescription(Stream * strm)115061da546Spatrick   void GetDescription(Stream *strm) override {
116061da546Spatrick     if (strm)
117061da546Spatrick       strm->Printf("RenderScript reduce breakpoint for '%s'",
118061da546Spatrick                    m_reduce_name.AsCString());
119061da546Spatrick   }
120061da546Spatrick 
Dump(Stream * s)121061da546Spatrick   void Dump(Stream *s) const override {}
122061da546Spatrick 
123061da546Spatrick   Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
124061da546Spatrick                                           SymbolContext &context,
125061da546Spatrick                                           Address *addr) override;
126061da546Spatrick 
GetDepth()127061da546Spatrick   lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }
128061da546Spatrick 
129061da546Spatrick   lldb::BreakpointResolverSP
CopyForBreakpoint(lldb::BreakpointSP & breakpoint)130dda28197Spatrick   CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override {
131061da546Spatrick     lldb::BreakpointResolverSP ret_sp(new RSReduceBreakpointResolver(
132dda28197Spatrick         breakpoint, m_reduce_name, m_rsmodules, m_kernel_types));
133061da546Spatrick     return ret_sp;
134061da546Spatrick   }
135061da546Spatrick 
136061da546Spatrick private:
137061da546Spatrick   ConstString m_reduce_name; // The name of the reduction
138061da546Spatrick   std::vector<lldb_renderscript::RSModuleDescriptorSP> *m_rsmodules;
139061da546Spatrick   int m_kernel_types;
140061da546Spatrick };
141061da546Spatrick 
142061da546Spatrick struct RSKernelDescriptor {
143061da546Spatrick public:
RSKernelDescriptorRSKernelDescriptor144061da546Spatrick   RSKernelDescriptor(const RSModuleDescriptor *module, llvm::StringRef name,
145061da546Spatrick                      uint32_t slot)
146061da546Spatrick       : m_module(module), m_name(name), m_slot(slot) {}
147061da546Spatrick 
148061da546Spatrick   void Dump(Stream &strm) const;
149061da546Spatrick 
150061da546Spatrick   const RSModuleDescriptor *m_module;
151061da546Spatrick   ConstString m_name;
152061da546Spatrick   RSSlot m_slot;
153061da546Spatrick };
154061da546Spatrick 
155061da546Spatrick struct RSGlobalDescriptor {
156061da546Spatrick public:
RSGlobalDescriptorRSGlobalDescriptor157061da546Spatrick   RSGlobalDescriptor(const RSModuleDescriptor *module, llvm::StringRef name)
158061da546Spatrick       : m_module(module), m_name(name) {}
159061da546Spatrick 
160061da546Spatrick   void Dump(Stream &strm) const;
161061da546Spatrick 
162061da546Spatrick   const RSModuleDescriptor *m_module;
163061da546Spatrick   ConstString m_name;
164061da546Spatrick };
165061da546Spatrick 
166061da546Spatrick struct RSReductionDescriptor {
167061da546Spatrick   RSReductionDescriptor(const RSModuleDescriptor *module, uint32_t sig,
168061da546Spatrick                         uint32_t accum_data_size, llvm::StringRef name,
169061da546Spatrick                         llvm::StringRef init_name, llvm::StringRef accum_name,
170061da546Spatrick                         llvm::StringRef comb_name, llvm::StringRef outc_name,
171061da546Spatrick                         llvm::StringRef halter_name = ".")
m_moduleRSReductionDescriptor172061da546Spatrick       : m_module(module), m_reduce_name(name), m_init_name(init_name),
173061da546Spatrick         m_accum_name(accum_name), m_comb_name(comb_name),
174*f6aab3d8Srobert         m_outc_name(outc_name), m_halter_name(halter_name), m_accum_sig(0),
175*f6aab3d8Srobert         m_accum_data_size(0), m_comb_name_generated(false) {
176061da546Spatrick     // TODO Check whether the combiner is an autogenerated name, and track
177061da546Spatrick     // this
178061da546Spatrick   }
179061da546Spatrick 
180061da546Spatrick   void Dump(Stream &strm) const;
181061da546Spatrick 
182061da546Spatrick   const RSModuleDescriptor *m_module;
183061da546Spatrick   ConstString m_reduce_name; // This is the name given to the general reduction
184061da546Spatrick                              // as a group as passed to pragma
185061da546Spatrick   // reduce(m_reduce_name). There is no kernel function with this name
186061da546Spatrick   ConstString m_init_name;  // The name of the initializer name. "." if no
187061da546Spatrick                             // initializer given
188061da546Spatrick   ConstString m_accum_name; // The accumulator function name. "." if not given
189061da546Spatrick   ConstString m_comb_name; // The name of the combiner function. If this was not
190061da546Spatrick                            // given, a name is generated by the
191061da546Spatrick                            // compiler. TODO
192061da546Spatrick   ConstString m_outc_name; // The name of the outconverter
193061da546Spatrick 
194061da546Spatrick   ConstString m_halter_name; // The name of the halter function. XXX This is not
195061da546Spatrick                              // yet specified by the RenderScript
196061da546Spatrick   // compiler or runtime, and its semantics and existence is still under
197061da546Spatrick   // discussion by the
198061da546Spatrick   // RenderScript Contributors
199061da546Spatrick   RSSlot m_accum_sig; // metatdata signature for this reduction (bitwise mask of
200061da546Spatrick                       // type information (see
201061da546Spatrick                       // libbcc/include/bcinfo/MetadataExtractor.h
202061da546Spatrick   uint32_t m_accum_data_size; // Data size of the accumulator function input
203061da546Spatrick   bool m_comb_name_generated; // Was the combiner name generated by the compiler
204061da546Spatrick };
205061da546Spatrick 
206061da546Spatrick class RSModuleDescriptor {
207061da546Spatrick   std::string m_slang_version;
208061da546Spatrick   std::string m_bcc_version;
209061da546Spatrick 
210061da546Spatrick   bool ParseVersionInfo(llvm::StringRef *, size_t n_lines);
211061da546Spatrick 
212061da546Spatrick   bool ParseExportForeachCount(llvm::StringRef *, size_t n_lines);
213061da546Spatrick 
214061da546Spatrick   bool ParseExportVarCount(llvm::StringRef *, size_t n_lines);
215061da546Spatrick 
216061da546Spatrick   bool ParseExportReduceCount(llvm::StringRef *, size_t n_lines);
217061da546Spatrick 
218061da546Spatrick   bool ParseBuildChecksum(llvm::StringRef *, size_t n_lines);
219061da546Spatrick 
220061da546Spatrick   bool ParsePragmaCount(llvm::StringRef *, size_t n_lines);
221061da546Spatrick 
222061da546Spatrick public:
RSModuleDescriptor(const lldb::ModuleSP & module)223061da546Spatrick   RSModuleDescriptor(const lldb::ModuleSP &module) : m_module(module) {}
224061da546Spatrick 
225061da546Spatrick   ~RSModuleDescriptor() = default;
226061da546Spatrick 
227061da546Spatrick   bool ParseRSInfo();
228061da546Spatrick 
229061da546Spatrick   void Dump(Stream &strm) const;
230061da546Spatrick 
231061da546Spatrick   void WarnIfVersionMismatch(Stream *s) const;
232061da546Spatrick 
233061da546Spatrick   const lldb::ModuleSP m_module;
234061da546Spatrick   std::vector<RSKernelDescriptor> m_kernels;
235061da546Spatrick   std::vector<RSGlobalDescriptor> m_globals;
236061da546Spatrick   std::vector<RSReductionDescriptor> m_reductions;
237061da546Spatrick   std::map<std::string, std::string> m_pragmas;
238061da546Spatrick   std::string m_resname;
239061da546Spatrick };
240061da546Spatrick 
241061da546Spatrick struct RSScriptGroupDescriptor {
242061da546Spatrick   struct Kernel {
243061da546Spatrick     ConstString m_name;
244061da546Spatrick     lldb::addr_t m_addr;
245061da546Spatrick   };
246061da546Spatrick   ConstString m_name;
247061da546Spatrick   std::vector<Kernel> m_kernels;
248061da546Spatrick };
249061da546Spatrick 
250061da546Spatrick typedef std::vector<RSScriptGroupDescriptorSP> RSScriptGroupList;
251061da546Spatrick 
252061da546Spatrick class RSScriptGroupBreakpointResolver : public BreakpointResolver {
253061da546Spatrick public:
RSScriptGroupBreakpointResolver(const lldb::BreakpointSP & bp,ConstString name,const RSScriptGroupList & groups,bool stop_on_all)254dda28197Spatrick   RSScriptGroupBreakpointResolver(const lldb::BreakpointSP &bp,
255dda28197Spatrick                                   ConstString name,
256061da546Spatrick                                   const RSScriptGroupList &groups,
257061da546Spatrick                                   bool stop_on_all)
258061da546Spatrick       : BreakpointResolver(bp, BreakpointResolver::NameResolver),
259061da546Spatrick         m_group_name(name), m_script_groups(groups),
260061da546Spatrick         m_stop_on_all(stop_on_all) {}
261061da546Spatrick 
GetDescription(Stream * strm)262061da546Spatrick   void GetDescription(Stream *strm) override {
263061da546Spatrick     if (strm)
264061da546Spatrick       strm->Printf("RenderScript ScriptGroup breakpoint for '%s'",
265061da546Spatrick                    m_group_name.AsCString());
266061da546Spatrick   }
267061da546Spatrick 
Dump(Stream * s)268061da546Spatrick   void Dump(Stream *s) const override {}
269061da546Spatrick 
270061da546Spatrick   Searcher::CallbackReturn SearchCallback(SearchFilter &filter,
271061da546Spatrick                                           SymbolContext &context,
272061da546Spatrick                                           Address *addr) override;
273061da546Spatrick 
GetDepth()274061da546Spatrick   lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; }
275061da546Spatrick 
276061da546Spatrick   lldb::BreakpointResolverSP
CopyForBreakpoint(lldb::BreakpointSP & breakpoint)277dda28197Spatrick   CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override {
278061da546Spatrick     lldb::BreakpointResolverSP ret_sp(new RSScriptGroupBreakpointResolver(
279dda28197Spatrick         breakpoint, m_group_name, m_script_groups, m_stop_on_all));
280061da546Spatrick     return ret_sp;
281061da546Spatrick   }
282061da546Spatrick 
283061da546Spatrick protected:
284061da546Spatrick   const RSScriptGroupDescriptorSP
FindScriptGroup(ConstString name)285061da546Spatrick   FindScriptGroup(ConstString name) const {
286061da546Spatrick     for (auto sg : m_script_groups) {
287061da546Spatrick       if (ConstString::Compare(sg->m_name, name) == 0)
288061da546Spatrick         return sg;
289061da546Spatrick     }
290061da546Spatrick     return RSScriptGroupDescriptorSP();
291061da546Spatrick   }
292061da546Spatrick 
293061da546Spatrick   ConstString m_group_name;
294061da546Spatrick   const RSScriptGroupList &m_script_groups;
295061da546Spatrick   bool m_stop_on_all;
296061da546Spatrick };
297061da546Spatrick } // namespace lldb_renderscript
298061da546Spatrick 
299061da546Spatrick class RenderScriptRuntime : public lldb_private::CPPLanguageRuntime {
300061da546Spatrick public:
301061da546Spatrick   enum ModuleKind {
302061da546Spatrick     eModuleKindIgnored,
303061da546Spatrick     eModuleKindLibRS,
304061da546Spatrick     eModuleKindDriver,
305061da546Spatrick     eModuleKindImpl,
306061da546Spatrick     eModuleKindKernelObj
307061da546Spatrick   };
308061da546Spatrick 
309061da546Spatrick   ~RenderScriptRuntime() override;
310061da546Spatrick 
311061da546Spatrick   // Static Functions
312061da546Spatrick   static void Initialize();
313061da546Spatrick 
314061da546Spatrick   static void Terminate();
315061da546Spatrick 
316061da546Spatrick   static lldb_private::LanguageRuntime *
317061da546Spatrick   CreateInstance(Process *process, lldb::LanguageType language);
318061da546Spatrick 
319061da546Spatrick   static lldb::CommandObjectSP
320061da546Spatrick   GetCommandObject(CommandInterpreter &interpreter);
321061da546Spatrick 
GetPluginNameStatic()322*f6aab3d8Srobert   static llvm::StringRef GetPluginNameStatic() { return "renderscript"; }
323061da546Spatrick 
324061da546Spatrick   static char ID;
325061da546Spatrick 
isA(const void * ClassID)326061da546Spatrick   bool isA(const void *ClassID) const override {
327061da546Spatrick     return ClassID == &ID || CPPLanguageRuntime::isA(ClassID);
328061da546Spatrick   }
329061da546Spatrick 
classof(const LanguageRuntime * runtime)330061da546Spatrick   static bool classof(const LanguageRuntime *runtime) {
331061da546Spatrick     return runtime->isA(&ID);
332061da546Spatrick   }
333061da546Spatrick 
334061da546Spatrick   static bool IsRenderScriptModule(const lldb::ModuleSP &module_sp);
335061da546Spatrick 
336061da546Spatrick   static ModuleKind GetModuleKind(const lldb::ModuleSP &module_sp);
337061da546Spatrick 
338061da546Spatrick   static void ModulesDidLoad(const lldb::ProcessSP &process_sp,
339061da546Spatrick                              const ModuleList &module_list);
340061da546Spatrick 
341061da546Spatrick   bool GetDynamicTypeAndAddress(ValueObject &in_value,
342061da546Spatrick                                 lldb::DynamicValueType use_dynamic,
343061da546Spatrick                                 TypeAndOrName &class_type_or_name,
344061da546Spatrick                                 Address &address,
345061da546Spatrick                                 Value::ValueType &value_type) override;
346061da546Spatrick 
347061da546Spatrick   TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name,
348061da546Spatrick                                  ValueObject &static_value) override;
349061da546Spatrick 
350061da546Spatrick   bool CouldHaveDynamicValue(ValueObject &in_value) override;
351061da546Spatrick 
352dda28197Spatrick   lldb::BreakpointResolverSP
353dda28197Spatrick   CreateExceptionResolver(const lldb::BreakpointSP &bp,
354dda28197Spatrick                           bool catch_bp, bool throw_bp) override;
355061da546Spatrick 
356061da546Spatrick   bool LoadModule(const lldb::ModuleSP &module_sp);
357061da546Spatrick 
358061da546Spatrick   void DumpModules(Stream &strm) const;
359061da546Spatrick 
360061da546Spatrick   void DumpContexts(Stream &strm) const;
361061da546Spatrick 
362061da546Spatrick   void DumpKernels(Stream &strm) const;
363061da546Spatrick 
364061da546Spatrick   bool DumpAllocation(Stream &strm, StackFrame *frame_ptr, const uint32_t id);
365061da546Spatrick 
366061da546Spatrick   void ListAllocations(Stream &strm, StackFrame *frame_ptr,
367061da546Spatrick                        const uint32_t index);
368061da546Spatrick 
369061da546Spatrick   bool RecomputeAllAllocations(Stream &strm, StackFrame *frame_ptr);
370061da546Spatrick 
371061da546Spatrick   bool PlaceBreakpointOnKernel(
372061da546Spatrick       lldb::TargetSP target, Stream &messages, const char *name,
373061da546Spatrick       const lldb_renderscript::RSCoordinate *coords = nullptr);
374061da546Spatrick 
375061da546Spatrick   bool PlaceBreakpointOnReduction(
376061da546Spatrick       lldb::TargetSP target, Stream &messages, const char *reduce_name,
377061da546Spatrick       const lldb_renderscript::RSCoordinate *coords = nullptr,
378061da546Spatrick       int kernel_types = ~(0));
379061da546Spatrick 
380061da546Spatrick   bool PlaceBreakpointOnScriptGroup(lldb::TargetSP target, Stream &strm,
381061da546Spatrick                                     ConstString name, bool stop_on_all);
382061da546Spatrick 
383061da546Spatrick   void SetBreakAllKernels(bool do_break, lldb::TargetSP target);
384061da546Spatrick 
385061da546Spatrick   void DumpStatus(Stream &strm) const;
386061da546Spatrick 
387061da546Spatrick   void ModulesDidLoad(const ModuleList &module_list) override;
388061da546Spatrick 
389061da546Spatrick   bool LoadAllocation(Stream &strm, const uint32_t alloc_id,
390061da546Spatrick                       const char *filename, StackFrame *frame_ptr);
391061da546Spatrick 
392061da546Spatrick   bool SaveAllocation(Stream &strm, const uint32_t alloc_id,
393061da546Spatrick                       const char *filename, StackFrame *frame_ptr);
394061da546Spatrick 
395061da546Spatrick   void Update();
396061da546Spatrick 
397061da546Spatrick   void Initiate();
398061da546Spatrick 
GetScriptGroups()399061da546Spatrick   const lldb_renderscript::RSScriptGroupList &GetScriptGroups() const {
400061da546Spatrick     return m_scriptGroups;
401061da546Spatrick   };
402061da546Spatrick 
IsKnownKernel(ConstString name)403061da546Spatrick   bool IsKnownKernel(ConstString name) {
404061da546Spatrick     for (const auto &module : m_rsmodules)
405061da546Spatrick       for (const auto &kernel : module->m_kernels)
406061da546Spatrick         if (kernel.m_name == name)
407061da546Spatrick           return true;
408061da546Spatrick     return false;
409061da546Spatrick   }
410061da546Spatrick 
411dda28197Spatrick   bool GetOverrideExprOptions(clang::TargetOptions &prototype);
412dda28197Spatrick 
413061da546Spatrick   // PluginInterface protocol
GetPluginName()414*f6aab3d8Srobert   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
415061da546Spatrick 
416061da546Spatrick   static bool GetKernelCoordinate(lldb_renderscript::RSCoordinate &coord,
417061da546Spatrick                                   Thread *thread_ptr);
418061da546Spatrick 
419061da546Spatrick   bool ResolveKernelName(lldb::addr_t kernel_address, ConstString &name);
420061da546Spatrick 
421061da546Spatrick protected:
422061da546Spatrick   struct ScriptDetails;
423061da546Spatrick   struct AllocationDetails;
424061da546Spatrick   struct Element;
425061da546Spatrick 
426061da546Spatrick   lldb_renderscript::RSScriptGroupList m_scriptGroups;
427061da546Spatrick 
InitSearchFilter(lldb::TargetSP target)428061da546Spatrick   void InitSearchFilter(lldb::TargetSP target) {
429061da546Spatrick     if (!m_filtersp)
430dda28197Spatrick       m_filtersp =
431dda28197Spatrick           std::make_shared<SearchFilterForUnconstrainedSearches>(target);
432061da546Spatrick   }
433061da546Spatrick 
434061da546Spatrick   void FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
435061da546Spatrick 
436061da546Spatrick   void LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind);
437061da546Spatrick 
438061da546Spatrick   bool RefreshAllocation(AllocationDetails *alloc, StackFrame *frame_ptr);
439061da546Spatrick 
440061da546Spatrick   bool EvalRSExpression(const char *expression, StackFrame *frame_ptr,
441061da546Spatrick                         uint64_t *result);
442061da546Spatrick 
443061da546Spatrick   lldb::BreakpointSP CreateScriptGroupBreakpoint(ConstString name,
444061da546Spatrick                                                  bool multi);
445061da546Spatrick 
446061da546Spatrick   lldb::BreakpointSP CreateKernelBreakpoint(ConstString name);
447061da546Spatrick 
448061da546Spatrick   lldb::BreakpointSP CreateReductionBreakpoint(ConstString name,
449061da546Spatrick                                                int kernel_types);
450061da546Spatrick 
451061da546Spatrick   void BreakOnModuleKernels(
452061da546Spatrick       const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
453061da546Spatrick 
454061da546Spatrick   struct RuntimeHook;
455061da546Spatrick   typedef void (RenderScriptRuntime::*CaptureStateFn)(
456061da546Spatrick       RuntimeHook *hook_info,
457061da546Spatrick       ExecutionContext &context); // Please do this!
458061da546Spatrick 
459061da546Spatrick   struct HookDefn {
460061da546Spatrick     const char *name;
461061da546Spatrick     const char *symbol_name_m32; // mangled name for the 32 bit architectures
462061da546Spatrick     const char *symbol_name_m64; // mangled name for the 64 bit archs
463061da546Spatrick     uint32_t version;
464061da546Spatrick     ModuleKind kind;
465061da546Spatrick     CaptureStateFn grabber;
466061da546Spatrick   };
467061da546Spatrick 
468061da546Spatrick   struct RuntimeHook {
469061da546Spatrick     lldb::addr_t address;
470061da546Spatrick     const HookDefn *defn;
471061da546Spatrick     lldb::BreakpointSP bp_sp;
472061da546Spatrick   };
473061da546Spatrick 
474061da546Spatrick   typedef std::shared_ptr<RuntimeHook> RuntimeHookSP;
475061da546Spatrick 
476061da546Spatrick   lldb::ModuleSP m_libRS;
477061da546Spatrick   lldb::ModuleSP m_libRSDriver;
478061da546Spatrick   lldb::ModuleSP m_libRSCpuRef;
479061da546Spatrick   std::vector<lldb_renderscript::RSModuleDescriptorSP> m_rsmodules;
480061da546Spatrick 
481061da546Spatrick   std::vector<std::unique_ptr<ScriptDetails>> m_scripts;
482061da546Spatrick   std::vector<std::unique_ptr<AllocationDetails>> m_allocations;
483061da546Spatrick 
484061da546Spatrick   std::map<lldb::addr_t, lldb_renderscript::RSModuleDescriptorSP>
485061da546Spatrick       m_scriptMappings;
486061da546Spatrick   std::map<lldb::addr_t, RuntimeHookSP> m_runtimeHooks;
487061da546Spatrick   std::map<lldb::user_id_t, std::unique_ptr<lldb_renderscript::RSCoordinate>>
488061da546Spatrick       m_conditional_breaks;
489061da546Spatrick 
490061da546Spatrick   lldb::SearchFilterSP
491061da546Spatrick       m_filtersp; // Needed to create breakpoints through Target API
492061da546Spatrick 
493061da546Spatrick   bool m_initiated;
494061da546Spatrick   bool m_debuggerPresentFlagged;
495061da546Spatrick   bool m_breakAllKernels;
496061da546Spatrick   static const HookDefn s_runtimeHookDefns[];
497061da546Spatrick   static const size_t s_runtimeHookCount;
498061da546Spatrick   LLVMUserExpression::IRPasses *m_ir_passes;
499061da546Spatrick 
500061da546Spatrick private:
501061da546Spatrick   RenderScriptRuntime(Process *process); // Call CreateInstance instead.
502061da546Spatrick 
503061da546Spatrick   static bool HookCallback(void *baton, StoppointCallbackContext *ctx,
504061da546Spatrick                            lldb::user_id_t break_id,
505061da546Spatrick                            lldb::user_id_t break_loc_id);
506061da546Spatrick 
507061da546Spatrick   static bool KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx,
508061da546Spatrick                                   lldb::user_id_t break_id,
509061da546Spatrick                                   lldb::user_id_t break_loc_id);
510061da546Spatrick 
511061da546Spatrick   void HookCallback(RuntimeHook *hook_info, ExecutionContext &context);
512061da546Spatrick 
513061da546Spatrick   // Callback function when 'debugHintScriptGroup2' executes on the target.
514061da546Spatrick   void CaptureDebugHintScriptGroup2(RuntimeHook *hook_info,
515061da546Spatrick                                     ExecutionContext &context);
516061da546Spatrick 
517061da546Spatrick   void CaptureScriptInit(RuntimeHook *hook_info, ExecutionContext &context);
518061da546Spatrick 
519061da546Spatrick   void CaptureAllocationInit(RuntimeHook *hook_info, ExecutionContext &context);
520061da546Spatrick 
521061da546Spatrick   void CaptureAllocationDestroy(RuntimeHook *hook_info,
522061da546Spatrick                                 ExecutionContext &context);
523061da546Spatrick 
524061da546Spatrick   void CaptureSetGlobalVar(RuntimeHook *hook_info, ExecutionContext &context);
525061da546Spatrick 
526061da546Spatrick   void CaptureScriptInvokeForEachMulti(RuntimeHook *hook_info,
527061da546Spatrick                                        ExecutionContext &context);
528061da546Spatrick 
529061da546Spatrick   AllocationDetails *FindAllocByID(Stream &strm, const uint32_t alloc_id);
530061da546Spatrick 
531061da546Spatrick   std::shared_ptr<uint8_t> GetAllocationData(AllocationDetails *alloc,
532061da546Spatrick                                              StackFrame *frame_ptr);
533061da546Spatrick 
534061da546Spatrick   void SetElementSize(Element &elem);
535061da546Spatrick 
536061da546Spatrick   static bool GetFrameVarAsUnsigned(const lldb::StackFrameSP,
537061da546Spatrick                                     const char *var_name, uint64_t &val);
538061da546Spatrick 
539061da546Spatrick   void FindStructTypeName(Element &elem, StackFrame *frame_ptr);
540061da546Spatrick 
541061da546Spatrick   size_t PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer,
542061da546Spatrick                                 size_t offset, const Element &elem);
543061da546Spatrick 
544061da546Spatrick   size_t CalculateElementHeaderSize(const Element &elem);
545061da546Spatrick 
546061da546Spatrick   void SetConditional(lldb::BreakpointSP bp, lldb_private::Stream &messages,
547061da546Spatrick                       const lldb_renderscript::RSCoordinate &coord);
548061da546Spatrick   //
549061da546Spatrick   // Helper functions for jitting the runtime
550061da546Spatrick   //
551061da546Spatrick 
552061da546Spatrick   bool JITDataPointer(AllocationDetails *alloc, StackFrame *frame_ptr,
553061da546Spatrick                       uint32_t x = 0, uint32_t y = 0, uint32_t z = 0);
554061da546Spatrick 
555061da546Spatrick   bool JITTypePointer(AllocationDetails *alloc, StackFrame *frame_ptr);
556061da546Spatrick 
557061da546Spatrick   bool JITTypePacked(AllocationDetails *alloc, StackFrame *frame_ptr);
558061da546Spatrick 
559061da546Spatrick   bool JITElementPacked(Element &elem, const lldb::addr_t context,
560061da546Spatrick                         StackFrame *frame_ptr);
561061da546Spatrick 
562061da546Spatrick   bool JITAllocationSize(AllocationDetails *alloc, StackFrame *frame_ptr);
563061da546Spatrick 
564061da546Spatrick   bool JITSubelements(Element &elem, const lldb::addr_t context,
565061da546Spatrick                       StackFrame *frame_ptr);
566061da546Spatrick 
567061da546Spatrick   bool JITAllocationStride(AllocationDetails *alloc, StackFrame *frame_ptr);
568061da546Spatrick 
569061da546Spatrick   // Search for a script detail object using a target address.
570061da546Spatrick   // If a script does not currently exist this function will return nullptr.
571061da546Spatrick   // If 'create' is true and there is no previous script with this address,
572061da546Spatrick   // then a new Script detail object will be created for this address and
573061da546Spatrick   // returned.
574061da546Spatrick   ScriptDetails *LookUpScript(lldb::addr_t address, bool create);
575061da546Spatrick 
576061da546Spatrick   // Search for a previously saved allocation detail object using a target
577061da546Spatrick   // address.
578061da546Spatrick   // If an allocation does not exist for this address then nullptr will be
579061da546Spatrick   // returned.
580061da546Spatrick   AllocationDetails *LookUpAllocation(lldb::addr_t address);
581061da546Spatrick 
582061da546Spatrick   // Creates a new allocation with the specified address assigning a new ID and
583061da546Spatrick   // removes
584061da546Spatrick   // any previous stored allocation which has the same address.
585061da546Spatrick   AllocationDetails *CreateAllocation(lldb::addr_t address);
586061da546Spatrick 
587061da546Spatrick   bool GetIRPasses(LLVMUserExpression::IRPasses &passes) override;
588061da546Spatrick };
589061da546Spatrick 
590061da546Spatrick } // namespace lldb_private
591061da546Spatrick 
592dda28197Spatrick #endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H
593