11c3bbb01SEd Maste //===-- RenderScriptRuntime.h -----------------------------------*- C++ -*-===// 21c3bbb01SEd Maste // 31c3bbb01SEd Maste // The LLVM Compiler Infrastructure 41c3bbb01SEd Maste // 51c3bbb01SEd Maste // This file is distributed under the University of Illinois Open Source 61c3bbb01SEd Maste // License. See LICENSE.TXT for details. 71c3bbb01SEd Maste // 81c3bbb01SEd Maste //===----------------------------------------------------------------------===// 91c3bbb01SEd Maste 101c3bbb01SEd Maste #ifndef liblldb_RenderScriptRuntime_h_ 111c3bbb01SEd Maste #define liblldb_RenderScriptRuntime_h_ 121c3bbb01SEd Maste 139f2f44ceSEd Maste #include <array> 149f2f44ceSEd Maste #include <map> 159f2f44ceSEd Maste #include <memory> 169f2f44ceSEd Maste #include <string> 179f2f44ceSEd Maste #include <vector> 189f2f44ceSEd Maste 19435933ddSDimitry Andric #include "llvm/ADT/SmallVector.h" 20435933ddSDimitry Andric #include "llvm/ADT/StringRef.h" 211c3bbb01SEd Maste #include "lldb/Core/Module.h" 22435933ddSDimitry Andric #include "lldb/Expression/LLVMUserExpression.h" 234bb0738eSEd Maste #include "lldb/Target/CPPLanguageRuntime.h" 244bb0738eSEd Maste #include "lldb/Target/LanguageRuntime.h" 254bb0738eSEd Maste #include "lldb/lldb-private.h" 261c3bbb01SEd Maste 27435933ddSDimitry Andric namespace lldb_private { 28435933ddSDimitry Andric namespace lldb_renderscript { 291c3bbb01SEd Maste 301c3bbb01SEd Maste typedef uint32_t RSSlot; 311c3bbb01SEd Maste class RSModuleDescriptor; 321c3bbb01SEd Maste struct RSGlobalDescriptor; 331c3bbb01SEd Maste struct RSKernelDescriptor; 34435933ddSDimitry Andric struct RSReductionDescriptor; 35435933ddSDimitry Andric struct RSScriptGroupDescriptor; 361c3bbb01SEd Maste 371c3bbb01SEd Maste typedef std::shared_ptr<RSModuleDescriptor> RSModuleDescriptorSP; 381c3bbb01SEd Maste typedef std::shared_ptr<RSGlobalDescriptor> RSGlobalDescriptorSP; 391c3bbb01SEd Maste typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP; 40435933ddSDimitry Andric typedef std::shared_ptr<RSScriptGroupDescriptor> RSScriptGroupDescriptorSP; 411c3bbb01SEd Maste 42435933ddSDimitry Andric struct RSCoordinate { 43435933ddSDimitry Andric uint32_t x, y, z; 44435933ddSDimitry Andric RSCoordinateRSCoordinate45435933ddSDimitry Andric RSCoordinate() : x(), y(), z(){}; 46435933ddSDimitry Andric 47435933ddSDimitry Andric bool operator==(const lldb_renderscript::RSCoordinate &rhs) { 48435933ddSDimitry Andric return x == rhs.x && y == rhs.y && z == rhs.z; 49435933ddSDimitry Andric } 50435933ddSDimitry Andric }; 51435933ddSDimitry Andric 52435933ddSDimitry Andric // Breakpoint Resolvers decide where a breakpoint is placed, so having our own 53435933ddSDimitry Andric // allows us to limit the search scope to RS kernel modules. As well as check 54435933ddSDimitry Andric // for .expand kernels as a fallback. 55435933ddSDimitry Andric class RSBreakpointResolver : public BreakpointResolver { 569f2f44ceSEd Maste public: RSBreakpointResolver(Breakpoint * bp,ConstString name)57435933ddSDimitry Andric RSBreakpointResolver(Breakpoint *bp, ConstString name) 58435933ddSDimitry Andric : BreakpointResolver(bp, BreakpointResolver::NameResolver), 59435933ddSDimitry Andric m_kernel_name(name) {} 601c3bbb01SEd Maste GetDescription(Stream * strm)61435933ddSDimitry Andric void GetDescription(Stream *strm) override { 629f2f44ceSEd Maste if (strm) 63435933ddSDimitry Andric strm->Printf("RenderScript kernel breakpoint for '%s'", 64435933ddSDimitry Andric m_kernel_name.AsCString()); 659f2f44ceSEd Maste } 669f2f44ceSEd Maste Dump(Stream * s)67435933ddSDimitry Andric void Dump(Stream *s) const override {} 689f2f44ceSEd Maste 69435933ddSDimitry Andric Searcher::CallbackReturn SearchCallback(SearchFilter &filter, 70435933ddSDimitry Andric SymbolContext &context, Address *addr, 71435933ddSDimitry Andric bool containing) override; 729f2f44ceSEd Maste GetDepth()73*b5893f02SDimitry Andric lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } 749f2f44ceSEd Maste 759f2f44ceSEd Maste lldb::BreakpointResolverSP CopyForBreakpoint(Breakpoint & breakpoint)76435933ddSDimitry Andric CopyForBreakpoint(Breakpoint &breakpoint) override { 77435933ddSDimitry Andric lldb::BreakpointResolverSP ret_sp( 78435933ddSDimitry Andric new RSBreakpointResolver(&breakpoint, m_kernel_name)); 799f2f44ceSEd Maste return ret_sp; 809f2f44ceSEd Maste } 819f2f44ceSEd Maste 829f2f44ceSEd Maste protected: 839f2f44ceSEd Maste ConstString m_kernel_name; 849f2f44ceSEd Maste }; 851c3bbb01SEd Maste 86435933ddSDimitry Andric class RSReduceBreakpointResolver : public BreakpointResolver { 871c3bbb01SEd Maste public: 88435933ddSDimitry Andric enum ReduceKernelTypeFlags { 89435933ddSDimitry Andric eKernelTypeAll = ~(0), 90435933ddSDimitry Andric eKernelTypeNone = 0, 91435933ddSDimitry Andric eKernelTypeAccum = (1 << 0), 92435933ddSDimitry Andric eKernelTypeInit = (1 << 1), 93435933ddSDimitry Andric eKernelTypeComb = (1 << 2), 94435933ddSDimitry Andric eKernelTypeOutC = (1 << 3), 95435933ddSDimitry Andric eKernelTypeHalter = (1 << 4) 96435933ddSDimitry Andric }; 97435933ddSDimitry Andric 98435933ddSDimitry Andric RSReduceBreakpointResolver( 99435933ddSDimitry Andric Breakpoint *breakpoint, ConstString reduce_name, 100435933ddSDimitry Andric std::vector<lldb_renderscript::RSModuleDescriptorSP> *rs_modules, 101435933ddSDimitry Andric int kernel_types = eKernelTypeAll) BreakpointResolver(breakpoint,BreakpointResolver::NameResolver)102435933ddSDimitry Andric : BreakpointResolver(breakpoint, BreakpointResolver::NameResolver), 103435933ddSDimitry Andric m_reduce_name(reduce_name), m_rsmodules(rs_modules), 104435933ddSDimitry Andric m_kernel_types(kernel_types) { 105435933ddSDimitry Andric // The reduce breakpoint resolver handles adding breakpoints for named 106435933ddSDimitry Andric // reductions. 107435933ddSDimitry Andric // Breakpoints will be resolved for all constituent kernels in the named 108435933ddSDimitry Andric // reduction 1091c3bbb01SEd Maste } 1101c3bbb01SEd Maste GetDescription(Stream * strm)111435933ddSDimitry Andric void GetDescription(Stream *strm) override { 112435933ddSDimitry Andric if (strm) 113435933ddSDimitry Andric strm->Printf("RenderScript reduce breakpoint for '%s'", 114435933ddSDimitry Andric m_reduce_name.AsCString()); 115435933ddSDimitry Andric } 116435933ddSDimitry Andric Dump(Stream * s)117435933ddSDimitry Andric void Dump(Stream *s) const override {} 118435933ddSDimitry Andric 119435933ddSDimitry Andric Searcher::CallbackReturn SearchCallback(SearchFilter &filter, 120435933ddSDimitry Andric SymbolContext &context, Address *addr, 121435933ddSDimitry Andric bool containing) override; 122435933ddSDimitry Andric GetDepth()123*b5893f02SDimitry Andric lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } 124435933ddSDimitry Andric 125435933ddSDimitry Andric lldb::BreakpointResolverSP CopyForBreakpoint(Breakpoint & breakpoint)126435933ddSDimitry Andric CopyForBreakpoint(Breakpoint &breakpoint) override { 127435933ddSDimitry Andric lldb::BreakpointResolverSP ret_sp(new RSReduceBreakpointResolver( 128435933ddSDimitry Andric &breakpoint, m_reduce_name, m_rsmodules, m_kernel_types)); 129435933ddSDimitry Andric return ret_sp; 130435933ddSDimitry Andric } 131435933ddSDimitry Andric 132435933ddSDimitry Andric private: 133435933ddSDimitry Andric ConstString m_reduce_name; // The name of the reduction 134435933ddSDimitry Andric std::vector<lldb_renderscript::RSModuleDescriptorSP> *m_rsmodules; 135435933ddSDimitry Andric int m_kernel_types; 136435933ddSDimitry Andric }; 137435933ddSDimitry Andric 138435933ddSDimitry Andric struct RSKernelDescriptor { 139435933ddSDimitry Andric public: RSKernelDescriptorRSKernelDescriptor140435933ddSDimitry Andric RSKernelDescriptor(const RSModuleDescriptor *module, llvm::StringRef name, 141435933ddSDimitry Andric uint32_t slot) 142435933ddSDimitry Andric : m_module(module), m_name(name), m_slot(slot) {} 143435933ddSDimitry Andric 144435933ddSDimitry Andric void Dump(Stream &strm) const; 1451c3bbb01SEd Maste 1461c3bbb01SEd Maste const RSModuleDescriptor *m_module; 1471c3bbb01SEd Maste ConstString m_name; 1481c3bbb01SEd Maste RSSlot m_slot; 1491c3bbb01SEd Maste }; 1501c3bbb01SEd Maste 151435933ddSDimitry Andric struct RSGlobalDescriptor { 1521c3bbb01SEd Maste public: RSGlobalDescriptorRSGlobalDescriptor153435933ddSDimitry Andric RSGlobalDescriptor(const RSModuleDescriptor *module, llvm::StringRef name) 154435933ddSDimitry Andric : m_module(module), m_name(name) {} 1551c3bbb01SEd Maste 156435933ddSDimitry Andric void Dump(Stream &strm) const; 1571c3bbb01SEd Maste 1581c3bbb01SEd Maste const RSModuleDescriptor *m_module; 1591c3bbb01SEd Maste ConstString m_name; 1601c3bbb01SEd Maste }; 1611c3bbb01SEd Maste 162435933ddSDimitry Andric struct RSReductionDescriptor { 163435933ddSDimitry Andric RSReductionDescriptor(const RSModuleDescriptor *module, uint32_t sig, 164435933ddSDimitry Andric uint32_t accum_data_size, llvm::StringRef name, 165435933ddSDimitry Andric llvm::StringRef init_name, llvm::StringRef accum_name, 166435933ddSDimitry Andric llvm::StringRef comb_name, llvm::StringRef outc_name, 167435933ddSDimitry Andric llvm::StringRef halter_name = ".") m_moduleRSReductionDescriptor168435933ddSDimitry Andric : m_module(module), m_reduce_name(name), m_init_name(init_name), 169435933ddSDimitry Andric m_accum_name(accum_name), m_comb_name(comb_name), 170435933ddSDimitry Andric m_outc_name(outc_name), m_halter_name(halter_name) { 171435933ddSDimitry Andric // TODO Check whether the combiner is an autogenerated name, and track 172435933ddSDimitry Andric // this 173435933ddSDimitry Andric } 174435933ddSDimitry Andric 175435933ddSDimitry Andric void Dump(Stream &strm) const; 176435933ddSDimitry Andric 177435933ddSDimitry Andric const RSModuleDescriptor *m_module; 178435933ddSDimitry Andric ConstString m_reduce_name; // This is the name given to the general reduction 179435933ddSDimitry Andric // as a group as passed to pragma 180435933ddSDimitry Andric // reduce(m_reduce_name). There is no kernel function with this name 181435933ddSDimitry Andric ConstString m_init_name; // The name of the initializer name. "." if no 182435933ddSDimitry Andric // initializer given 183435933ddSDimitry Andric ConstString m_accum_name; // The accumulator function name. "." if not given 184435933ddSDimitry Andric ConstString m_comb_name; // The name of the combiner function. If this was not 185435933ddSDimitry Andric // given, a name is generated by the 186435933ddSDimitry Andric // compiler. TODO 187435933ddSDimitry Andric ConstString m_outc_name; // The name of the outconverter 188435933ddSDimitry Andric 189435933ddSDimitry Andric ConstString m_halter_name; // The name of the halter function. XXX This is not 190435933ddSDimitry Andric // yet specified by the RenderScript 191435933ddSDimitry Andric // compiler or runtime, and its semantics and existence is still under 192435933ddSDimitry Andric // discussion by the 193435933ddSDimitry Andric // RenderScript Contributors 194435933ddSDimitry Andric RSSlot m_accum_sig; // metatdata signature for this reduction (bitwise mask of 195435933ddSDimitry Andric // type information (see 196435933ddSDimitry Andric // libbcc/include/bcinfo/MetadataExtractor.h 197435933ddSDimitry Andric uint32_t m_accum_data_size; // Data size of the accumulator function input 198435933ddSDimitry Andric bool m_comb_name_generated; // Was the combiner name generated by the compiler 199435933ddSDimitry Andric }; 200435933ddSDimitry Andric 201435933ddSDimitry Andric class RSModuleDescriptor { 2028e0f8b8cSDimitry Andric std::string m_slang_version; 2038e0f8b8cSDimitry Andric std::string m_bcc_version; 2048e0f8b8cSDimitry Andric 2058e0f8b8cSDimitry Andric bool ParseVersionInfo(llvm::StringRef *, size_t n_lines); 2068e0f8b8cSDimitry Andric 207435933ddSDimitry Andric bool ParseExportForeachCount(llvm::StringRef *, size_t n_lines); 208435933ddSDimitry Andric 209435933ddSDimitry Andric bool ParseExportVarCount(llvm::StringRef *, size_t n_lines); 210435933ddSDimitry Andric 211435933ddSDimitry Andric bool ParseExportReduceCount(llvm::StringRef *, size_t n_lines); 212435933ddSDimitry Andric 213435933ddSDimitry Andric bool ParseBuildChecksum(llvm::StringRef *, size_t n_lines); 214435933ddSDimitry Andric 215435933ddSDimitry Andric bool ParsePragmaCount(llvm::StringRef *, size_t n_lines); 216435933ddSDimitry Andric 2171c3bbb01SEd Maste public: RSModuleDescriptor(const lldb::ModuleSP & module)2184bb0738eSEd Maste RSModuleDescriptor(const lldb::ModuleSP &module) : m_module(module) {} 2191c3bbb01SEd Maste 2209f2f44ceSEd Maste ~RSModuleDescriptor() = default; 2211c3bbb01SEd Maste 222435933ddSDimitry Andric bool ParseRSInfo(); 2231c3bbb01SEd Maste 224435933ddSDimitry Andric void Dump(Stream &strm) const; 2251c3bbb01SEd Maste 2268e0f8b8cSDimitry Andric void WarnIfVersionMismatch(Stream *s) const; 2278e0f8b8cSDimitry Andric 2281c3bbb01SEd Maste const lldb::ModuleSP m_module; 2291c3bbb01SEd Maste std::vector<RSKernelDescriptor> m_kernels; 2301c3bbb01SEd Maste std::vector<RSGlobalDescriptor> m_globals; 231435933ddSDimitry Andric std::vector<RSReductionDescriptor> m_reductions; 2321c3bbb01SEd Maste std::map<std::string, std::string> m_pragmas; 2331c3bbb01SEd Maste std::string m_resname; 2341c3bbb01SEd Maste }; 2351c3bbb01SEd Maste 236435933ddSDimitry Andric struct RSScriptGroupDescriptor { 237435933ddSDimitry Andric struct Kernel { 238435933ddSDimitry Andric ConstString m_name; 239435933ddSDimitry Andric lldb::addr_t m_addr; 240435933ddSDimitry Andric }; 241435933ddSDimitry Andric ConstString m_name; 242435933ddSDimitry Andric std::vector<Kernel> m_kernels; 243435933ddSDimitry Andric }; 244435933ddSDimitry Andric 245435933ddSDimitry Andric typedef std::vector<RSScriptGroupDescriptorSP> RSScriptGroupList; 246435933ddSDimitry Andric 247435933ddSDimitry Andric class RSScriptGroupBreakpointResolver : public BreakpointResolver { 248435933ddSDimitry Andric public: RSScriptGroupBreakpointResolver(Breakpoint * bp,const ConstString & name,const RSScriptGroupList & groups,bool stop_on_all)249435933ddSDimitry Andric RSScriptGroupBreakpointResolver(Breakpoint *bp, const ConstString &name, 250435933ddSDimitry Andric const RSScriptGroupList &groups, 251435933ddSDimitry Andric bool stop_on_all) 252435933ddSDimitry Andric : BreakpointResolver(bp, BreakpointResolver::NameResolver), 253435933ddSDimitry Andric m_group_name(name), m_script_groups(groups), 254435933ddSDimitry Andric m_stop_on_all(stop_on_all) {} 255435933ddSDimitry Andric GetDescription(Stream * strm)256435933ddSDimitry Andric void GetDescription(Stream *strm) override { 257435933ddSDimitry Andric if (strm) 258435933ddSDimitry Andric strm->Printf("RenderScript ScriptGroup breakpoint for '%s'", 259435933ddSDimitry Andric m_group_name.AsCString()); 260435933ddSDimitry Andric } 261435933ddSDimitry Andric Dump(Stream * s)262435933ddSDimitry Andric void Dump(Stream *s) const override {} 263435933ddSDimitry Andric 264435933ddSDimitry Andric Searcher::CallbackReturn SearchCallback(SearchFilter &filter, 265435933ddSDimitry Andric SymbolContext &context, Address *addr, 266435933ddSDimitry Andric bool containing) override; 267435933ddSDimitry Andric GetDepth()268*b5893f02SDimitry Andric lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } 269435933ddSDimitry Andric 270435933ddSDimitry Andric lldb::BreakpointResolverSP CopyForBreakpoint(Breakpoint & breakpoint)271435933ddSDimitry Andric CopyForBreakpoint(Breakpoint &breakpoint) override { 272435933ddSDimitry Andric lldb::BreakpointResolverSP ret_sp(new RSScriptGroupBreakpointResolver( 273435933ddSDimitry Andric &breakpoint, m_group_name, m_script_groups, m_stop_on_all)); 274435933ddSDimitry Andric return ret_sp; 275435933ddSDimitry Andric } 276435933ddSDimitry Andric 277435933ddSDimitry Andric protected: 278435933ddSDimitry Andric const RSScriptGroupDescriptorSP FindScriptGroup(const ConstString & name)279435933ddSDimitry Andric FindScriptGroup(const ConstString &name) const { 280435933ddSDimitry Andric for (auto sg : m_script_groups) { 281435933ddSDimitry Andric if (ConstString::Compare(sg->m_name, name) == 0) 282435933ddSDimitry Andric return sg; 283435933ddSDimitry Andric } 284435933ddSDimitry Andric return RSScriptGroupDescriptorSP(); 285435933ddSDimitry Andric } 286435933ddSDimitry Andric 287435933ddSDimitry Andric ConstString m_group_name; 288435933ddSDimitry Andric const RSScriptGroupList &m_script_groups; 289435933ddSDimitry Andric bool m_stop_on_all; 290435933ddSDimitry Andric }; 2919f2f44ceSEd Maste } // namespace lldb_renderscript 2929f2f44ceSEd Maste 293435933ddSDimitry Andric class RenderScriptRuntime : public lldb_private::CPPLanguageRuntime { 2941c3bbb01SEd Maste public: 295435933ddSDimitry Andric enum ModuleKind { 2961c3bbb01SEd Maste eModuleKindIgnored, 2971c3bbb01SEd Maste eModuleKindLibRS, 2981c3bbb01SEd Maste eModuleKindDriver, 2991c3bbb01SEd Maste eModuleKindImpl, 3001c3bbb01SEd Maste eModuleKindKernelObj 3011c3bbb01SEd Maste }; 3021c3bbb01SEd Maste 3039f2f44ceSEd Maste ~RenderScriptRuntime() override; 3041c3bbb01SEd Maste 3051c3bbb01SEd Maste //------------------------------------------------------------------ 3061c3bbb01SEd Maste // Static Functions 3071c3bbb01SEd Maste //------------------------------------------------------------------ 308435933ddSDimitry Andric static void Initialize(); 3091c3bbb01SEd Maste 310435933ddSDimitry Andric static void Terminate(); 3111c3bbb01SEd Maste 3124bb0738eSEd Maste static lldb_private::LanguageRuntime * 3134bb0738eSEd Maste CreateInstance(Process *process, lldb::LanguageType language); 3141c3bbb01SEd Maste 3154bb0738eSEd Maste static lldb::CommandObjectSP 3164bb0738eSEd Maste GetCommandObject(CommandInterpreter &interpreter); 3171c3bbb01SEd Maste 318435933ddSDimitry Andric static lldb_private::ConstString GetPluginNameStatic(); 3191c3bbb01SEd Maste 320435933ddSDimitry Andric static bool IsRenderScriptModule(const lldb::ModuleSP &module_sp); 3211c3bbb01SEd Maste 322435933ddSDimitry Andric static ModuleKind GetModuleKind(const lldb::ModuleSP &module_sp); 3231c3bbb01SEd Maste 324435933ddSDimitry Andric static void ModulesDidLoad(const lldb::ProcessSP &process_sp, 325435933ddSDimitry Andric const ModuleList &module_list); 3261c3bbb01SEd Maste 327435933ddSDimitry Andric bool IsVTableName(const char *name) override; 3281c3bbb01SEd Maste 329435933ddSDimitry Andric bool GetDynamicTypeAndAddress(ValueObject &in_value, 330435933ddSDimitry Andric lldb::DynamicValueType use_dynamic, 331435933ddSDimitry Andric TypeAndOrName &class_type_or_name, 332435933ddSDimitry Andric Address &address, 3339f2f44ceSEd Maste Value::ValueType &value_type) override; 3341c3bbb01SEd Maste 335435933ddSDimitry Andric TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name, 336435933ddSDimitry Andric ValueObject &static_value) override; 3371c3bbb01SEd Maste 338435933ddSDimitry Andric bool CouldHaveDynamicValue(ValueObject &in_value) override; 3391c3bbb01SEd Maste 340435933ddSDimitry Andric lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bp, 341435933ddSDimitry Andric bool catch_bp, 342435933ddSDimitry Andric bool throw_bp) override; 3431c3bbb01SEd Maste 344435933ddSDimitry Andric bool LoadModule(const lldb::ModuleSP &module_sp); 3451c3bbb01SEd Maste 346435933ddSDimitry Andric void DumpModules(Stream &strm) const; 3471c3bbb01SEd Maste 348435933ddSDimitry Andric void DumpContexts(Stream &strm) const; 3491c3bbb01SEd Maste 350435933ddSDimitry Andric void DumpKernels(Stream &strm) const; 3511c3bbb01SEd Maste 352435933ddSDimitry Andric bool DumpAllocation(Stream &strm, StackFrame *frame_ptr, const uint32_t id); 3531c3bbb01SEd Maste 354435933ddSDimitry Andric void ListAllocations(Stream &strm, StackFrame *frame_ptr, 355435933ddSDimitry Andric const uint32_t index); 3569f2f44ceSEd Maste 357435933ddSDimitry Andric bool RecomputeAllAllocations(Stream &strm, StackFrame *frame_ptr); 3589f2f44ceSEd Maste 359435933ddSDimitry Andric bool PlaceBreakpointOnKernel( 360435933ddSDimitry Andric lldb::TargetSP target, Stream &messages, const char *name, 361435933ddSDimitry Andric const lldb_renderscript::RSCoordinate *coords = nullptr); 3629f2f44ceSEd Maste 363435933ddSDimitry Andric bool PlaceBreakpointOnReduction( 364435933ddSDimitry Andric lldb::TargetSP target, Stream &messages, const char *reduce_name, 365435933ddSDimitry Andric const lldb_renderscript::RSCoordinate *coords = nullptr, 366435933ddSDimitry Andric int kernel_types = ~(0)); 3671c3bbb01SEd Maste 368435933ddSDimitry Andric bool PlaceBreakpointOnScriptGroup(lldb::TargetSP target, Stream &strm, 369435933ddSDimitry Andric const ConstString &name, bool stop_on_all); 3701c3bbb01SEd Maste 371435933ddSDimitry Andric void SetBreakAllKernels(bool do_break, lldb::TargetSP target); 3729f2f44ceSEd Maste 3735517e702SDimitry Andric void DumpStatus(Stream &strm) const; 3749f2f44ceSEd Maste 375435933ddSDimitry Andric void ModulesDidLoad(const ModuleList &module_list) override; 3761c3bbb01SEd Maste 377435933ddSDimitry Andric bool LoadAllocation(Stream &strm, const uint32_t alloc_id, 378435933ddSDimitry Andric const char *filename, StackFrame *frame_ptr); 3791c3bbb01SEd Maste 380435933ddSDimitry Andric bool SaveAllocation(Stream &strm, const uint32_t alloc_id, 381435933ddSDimitry Andric const char *filename, StackFrame *frame_ptr); 382435933ddSDimitry Andric 383435933ddSDimitry Andric void Update(); 384435933ddSDimitry Andric 385435933ddSDimitry Andric void Initiate(); 386435933ddSDimitry Andric GetScriptGroups()387435933ddSDimitry Andric const lldb_renderscript::RSScriptGroupList &GetScriptGroups() const { 388435933ddSDimitry Andric return m_scriptGroups; 389435933ddSDimitry Andric }; 390435933ddSDimitry Andric IsKnownKernel(const ConstString & name)391435933ddSDimitry Andric bool IsKnownKernel(const ConstString &name) { 392435933ddSDimitry Andric for (const auto &module : m_rsmodules) 393435933ddSDimitry Andric for (const auto &kernel : module->m_kernels) 394435933ddSDimitry Andric if (kernel.m_name == name) 395435933ddSDimitry Andric return true; 396435933ddSDimitry Andric return false; 397435933ddSDimitry Andric } 3981c3bbb01SEd Maste 3999f2f44ceSEd Maste //------------------------------------------------------------------ 4009f2f44ceSEd Maste // PluginInterface protocol 4019f2f44ceSEd Maste //------------------------------------------------------------------ 402435933ddSDimitry Andric lldb_private::ConstString GetPluginName() override; 4031c3bbb01SEd Maste 404435933ddSDimitry Andric uint32_t GetPluginVersion() override; 4054bb0738eSEd Maste 406435933ddSDimitry Andric static bool GetKernelCoordinate(lldb_renderscript::RSCoordinate &coord, 407435933ddSDimitry Andric Thread *thread_ptr); 408435933ddSDimitry Andric 409435933ddSDimitry Andric bool ResolveKernelName(lldb::addr_t kernel_address, ConstString &name); 4109f2f44ceSEd Maste 4119f2f44ceSEd Maste protected: 4129f2f44ceSEd Maste struct ScriptDetails; 4139f2f44ceSEd Maste struct AllocationDetails; 4149f2f44ceSEd Maste struct Element; 4159f2f44ceSEd Maste 416435933ddSDimitry Andric lldb_renderscript::RSScriptGroupList m_scriptGroups; 417435933ddSDimitry Andric InitSearchFilter(lldb::TargetSP target)418435933ddSDimitry Andric void InitSearchFilter(lldb::TargetSP target) { 4199f2f44ceSEd Maste if (!m_filtersp) 4209f2f44ceSEd Maste m_filtersp.reset(new SearchFilterForUnconstrainedSearches(target)); 4219f2f44ceSEd Maste } 4229f2f44ceSEd Maste 423435933ddSDimitry Andric void FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp); 4241c3bbb01SEd Maste 425435933ddSDimitry Andric void LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind); 4261c3bbb01SEd Maste 427435933ddSDimitry Andric bool RefreshAllocation(AllocationDetails *alloc, StackFrame *frame_ptr); 4289f2f44ceSEd Maste 429435933ddSDimitry Andric bool EvalRSExpression(const char *expression, StackFrame *frame_ptr, 430435933ddSDimitry Andric uint64_t *result); 4319f2f44ceSEd Maste 432435933ddSDimitry Andric lldb::BreakpointSP CreateScriptGroupBreakpoint(const ConstString &name, 433435933ddSDimitry Andric bool multi); 4349f2f44ceSEd Maste 435435933ddSDimitry Andric lldb::BreakpointSP CreateKernelBreakpoint(const ConstString &name); 436435933ddSDimitry Andric 437435933ddSDimitry Andric lldb::BreakpointSP CreateReductionBreakpoint(const ConstString &name, 438435933ddSDimitry Andric int kernel_types); 439435933ddSDimitry Andric 440435933ddSDimitry Andric void BreakOnModuleKernels( 441435933ddSDimitry Andric const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp); 4429f2f44ceSEd Maste 4431c3bbb01SEd Maste struct RuntimeHook; 444435933ddSDimitry Andric typedef void (RenderScriptRuntime::*CaptureStateFn)( 445435933ddSDimitry Andric RuntimeHook *hook_info, 4464bb0738eSEd Maste ExecutionContext &context); // Please do this! 4471c3bbb01SEd Maste 448435933ddSDimitry Andric struct HookDefn { 4491c3bbb01SEd Maste const char *name; 4509f2f44ceSEd Maste const char *symbol_name_m32; // mangled name for the 32 bit architectures 4519f2f44ceSEd Maste const char *symbol_name_m64; // mangled name for the 64 bit archs 4521c3bbb01SEd Maste uint32_t version; 4531c3bbb01SEd Maste ModuleKind kind; 4541c3bbb01SEd Maste CaptureStateFn grabber; 4551c3bbb01SEd Maste }; 4561c3bbb01SEd Maste 457435933ddSDimitry Andric struct RuntimeHook { 4581c3bbb01SEd Maste lldb::addr_t address; 4591c3bbb01SEd Maste const HookDefn *defn; 4601c3bbb01SEd Maste lldb::BreakpointSP bp_sp; 4611c3bbb01SEd Maste }; 4621c3bbb01SEd Maste 4631c3bbb01SEd Maste typedef std::shared_ptr<RuntimeHook> RuntimeHookSP; 4641c3bbb01SEd Maste 4651c3bbb01SEd Maste lldb::ModuleSP m_libRS; 4661c3bbb01SEd Maste lldb::ModuleSP m_libRSDriver; 4671c3bbb01SEd Maste lldb::ModuleSP m_libRSCpuRef; 4689f2f44ceSEd Maste std::vector<lldb_renderscript::RSModuleDescriptorSP> m_rsmodules; 4691c3bbb01SEd Maste 4709f2f44ceSEd Maste std::vector<std::unique_ptr<ScriptDetails>> m_scripts; 4719f2f44ceSEd Maste std::vector<std::unique_ptr<AllocationDetails>> m_allocations; 4729f2f44ceSEd Maste 473435933ddSDimitry Andric std::map<lldb::addr_t, lldb_renderscript::RSModuleDescriptorSP> 474435933ddSDimitry Andric m_scriptMappings; 4751c3bbb01SEd Maste std::map<lldb::addr_t, RuntimeHookSP> m_runtimeHooks; 476435933ddSDimitry Andric std::map<lldb::user_id_t, std::unique_ptr<lldb_renderscript::RSCoordinate>> 477435933ddSDimitry Andric m_conditional_breaks; 4789f2f44ceSEd Maste 479435933ddSDimitry Andric lldb::SearchFilterSP 480435933ddSDimitry Andric m_filtersp; // Needed to create breakpoints through Target API 4811c3bbb01SEd Maste 4821c3bbb01SEd Maste bool m_initiated; 4831c3bbb01SEd Maste bool m_debuggerPresentFlagged; 4849f2f44ceSEd Maste bool m_breakAllKernels; 4851c3bbb01SEd Maste static const HookDefn s_runtimeHookDefns[]; 4861c3bbb01SEd Maste static const size_t s_runtimeHookCount; 487435933ddSDimitry Andric LLVMUserExpression::IRPasses *m_ir_passes; 4881c3bbb01SEd Maste 4891c3bbb01SEd Maste private: 4901c3bbb01SEd Maste RenderScriptRuntime(Process *process); // Call CreateInstance instead. 4911c3bbb01SEd Maste 492435933ddSDimitry Andric static bool HookCallback(void *baton, StoppointCallbackContext *ctx, 493435933ddSDimitry Andric lldb::user_id_t break_id, 4941c3bbb01SEd Maste lldb::user_id_t break_loc_id); 4951c3bbb01SEd Maste 496435933ddSDimitry Andric static bool KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx, 497435933ddSDimitry Andric lldb::user_id_t break_id, 498435933ddSDimitry Andric lldb::user_id_t break_loc_id); 4999f2f44ceSEd Maste 500435933ddSDimitry Andric void HookCallback(RuntimeHook *hook_info, ExecutionContext &context); 5011c3bbb01SEd Maste 502435933ddSDimitry Andric // Callback function when 'debugHintScriptGroup2' executes on the target. 503435933ddSDimitry Andric void CaptureDebugHintScriptGroup2(RuntimeHook *hook_info, 504435933ddSDimitry Andric ExecutionContext &context); 5051c3bbb01SEd Maste 506435933ddSDimitry Andric void CaptureScriptInit(RuntimeHook *hook_info, ExecutionContext &context); 5071c3bbb01SEd Maste 508435933ddSDimitry Andric void CaptureAllocationInit(RuntimeHook *hook_info, ExecutionContext &context); 5099f2f44ceSEd Maste 510435933ddSDimitry Andric void CaptureAllocationDestroy(RuntimeHook *hook_info, 511435933ddSDimitry Andric ExecutionContext &context); 5124bb0738eSEd Maste 513435933ddSDimitry Andric void CaptureSetGlobalVar(RuntimeHook *hook_info, ExecutionContext &context); 5144bb0738eSEd Maste 515435933ddSDimitry Andric void CaptureScriptInvokeForEachMulti(RuntimeHook *hook_info, 516435933ddSDimitry Andric ExecutionContext &context); 5174bb0738eSEd Maste 518435933ddSDimitry Andric AllocationDetails *FindAllocByID(Stream &strm, const uint32_t alloc_id); 5194bb0738eSEd Maste 520435933ddSDimitry Andric std::shared_ptr<uint8_t> GetAllocationData(AllocationDetails *alloc, 521435933ddSDimitry Andric StackFrame *frame_ptr); 5224bb0738eSEd Maste 523435933ddSDimitry Andric void SetElementSize(Element &elem); 5244bb0738eSEd Maste 525435933ddSDimitry Andric static bool GetFrameVarAsUnsigned(const lldb::StackFrameSP, 526435933ddSDimitry Andric const char *var_name, uint64_t &val); 5274bb0738eSEd Maste 528435933ddSDimitry Andric void FindStructTypeName(Element &elem, StackFrame *frame_ptr); 529444ed5c5SDimitry Andric 530435933ddSDimitry Andric size_t PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer, 531435933ddSDimitry Andric size_t offset, const Element &elem); 532435933ddSDimitry Andric 533435933ddSDimitry Andric size_t CalculateElementHeaderSize(const Element &elem); 534435933ddSDimitry Andric 535435933ddSDimitry Andric void SetConditional(lldb::BreakpointSP bp, lldb_private::Stream &messages, 536435933ddSDimitry Andric const lldb_renderscript::RSCoordinate &coord); 5379f2f44ceSEd Maste // 5389f2f44ceSEd Maste // Helper functions for jitting the runtime 5399f2f44ceSEd Maste // 5409f2f44ceSEd Maste 541435933ddSDimitry Andric bool JITDataPointer(AllocationDetails *alloc, StackFrame *frame_ptr, 5424bb0738eSEd Maste uint32_t x = 0, uint32_t y = 0, uint32_t z = 0); 5439f2f44ceSEd Maste 544435933ddSDimitry Andric bool JITTypePointer(AllocationDetails *alloc, StackFrame *frame_ptr); 5459f2f44ceSEd Maste 546435933ddSDimitry Andric bool JITTypePacked(AllocationDetails *alloc, StackFrame *frame_ptr); 5479f2f44ceSEd Maste 548435933ddSDimitry Andric bool JITElementPacked(Element &elem, const lldb::addr_t context, 549435933ddSDimitry Andric StackFrame *frame_ptr); 5509f2f44ceSEd Maste 551435933ddSDimitry Andric bool JITAllocationSize(AllocationDetails *alloc, StackFrame *frame_ptr); 5529f2f44ceSEd Maste 553435933ddSDimitry Andric bool JITSubelements(Element &elem, const lldb::addr_t context, 554435933ddSDimitry Andric StackFrame *frame_ptr); 5559f2f44ceSEd Maste 556435933ddSDimitry Andric bool JITAllocationStride(AllocationDetails *alloc, StackFrame *frame_ptr); 5579f2f44ceSEd Maste 5589f2f44ceSEd Maste // Search for a script detail object using a target address. 5599f2f44ceSEd Maste // If a script does not currently exist this function will return nullptr. 5609f2f44ceSEd Maste // If 'create' is true and there is no previous script with this address, 561435933ddSDimitry Andric // then a new Script detail object will be created for this address and 562435933ddSDimitry Andric // returned. 563435933ddSDimitry Andric ScriptDetails *LookUpScript(lldb::addr_t address, bool create); 5649f2f44ceSEd Maste 565435933ddSDimitry Andric // Search for a previously saved allocation detail object using a target 566435933ddSDimitry Andric // address. 567435933ddSDimitry Andric // If an allocation does not exist for this address then nullptr will be 568435933ddSDimitry Andric // returned. 569435933ddSDimitry Andric AllocationDetails *LookUpAllocation(lldb::addr_t address); 570435933ddSDimitry Andric 571435933ddSDimitry Andric // Creates a new allocation with the specified address assigning a new ID and 572435933ddSDimitry Andric // removes 573435933ddSDimitry Andric // any previous stored allocation which has the same address. 574435933ddSDimitry Andric AllocationDetails *CreateAllocation(lldb::addr_t address); 575435933ddSDimitry Andric 576435933ddSDimitry Andric bool GetOverrideExprOptions(clang::TargetOptions &prototype) override; 577435933ddSDimitry Andric 578435933ddSDimitry Andric bool GetIRPasses(LLVMUserExpression::IRPasses &passes) override; 5791c3bbb01SEd Maste }; 5801c3bbb01SEd Maste 5811c3bbb01SEd Maste } // namespace lldb_private 5821c3bbb01SEd Maste 5831c3bbb01SEd Maste #endif // liblldb_RenderScriptRuntime_h_ 584