10b57cec5SDimitry Andric //===-- RenderScriptRuntime.h -----------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 95ffd83dbSDimitry Andric #ifndef LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H 105ffd83dbSDimitry Andric #define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include <array> 130b57cec5SDimitry Andric #include <map> 140b57cec5SDimitry Andric #include <memory> 150b57cec5SDimitry Andric #include <string> 160b57cec5SDimitry Andric #include <vector> 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 190b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 200b57cec5SDimitry Andric #include "lldb/Core/Module.h" 210b57cec5SDimitry Andric #include "lldb/Expression/LLVMUserExpression.h" 220b57cec5SDimitry Andric #include "lldb/Target/LanguageRuntime.h" 230b57cec5SDimitry Andric #include "lldb/lldb-private.h" 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric #include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h" 260b57cec5SDimitry Andric 275ffd83dbSDimitry Andric namespace clang { 285ffd83dbSDimitry Andric class TargetOptions; 295ffd83dbSDimitry Andric } 305ffd83dbSDimitry Andric 310b57cec5SDimitry Andric namespace lldb_private { 320b57cec5SDimitry Andric namespace lldb_renderscript { 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric typedef uint32_t RSSlot; 350b57cec5SDimitry Andric class RSModuleDescriptor; 360b57cec5SDimitry Andric struct RSGlobalDescriptor; 370b57cec5SDimitry Andric struct RSKernelDescriptor; 380b57cec5SDimitry Andric struct RSReductionDescriptor; 390b57cec5SDimitry Andric struct RSScriptGroupDescriptor; 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric typedef std::shared_ptr<RSModuleDescriptor> RSModuleDescriptorSP; 420b57cec5SDimitry Andric typedef std::shared_ptr<RSGlobalDescriptor> RSGlobalDescriptorSP; 430b57cec5SDimitry Andric typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP; 440b57cec5SDimitry Andric typedef std::shared_ptr<RSScriptGroupDescriptor> RSScriptGroupDescriptorSP; 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric struct RSCoordinate { 47*5f7ddb14SDimitry Andric uint32_t x = 0, y = 0, z = 0; 480b57cec5SDimitry Andric 49*5f7ddb14SDimitry Andric RSCoordinate() = default; 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric bool operator==(const lldb_renderscript::RSCoordinate &rhs) { 520b57cec5SDimitry Andric return x == rhs.x && y == rhs.y && z == rhs.z; 530b57cec5SDimitry Andric } 540b57cec5SDimitry Andric }; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric // Breakpoint Resolvers decide where a breakpoint is placed, so having our own 570b57cec5SDimitry Andric // allows us to limit the search scope to RS kernel modules. As well as check 580b57cec5SDimitry Andric // for .expand kernels as a fallback. 590b57cec5SDimitry Andric class RSBreakpointResolver : public BreakpointResolver { 600b57cec5SDimitry Andric public: RSBreakpointResolver(const lldb::BreakpointSP & bp,ConstString name)615ffd83dbSDimitry Andric RSBreakpointResolver(const lldb::BreakpointSP &bp, ConstString name) 620b57cec5SDimitry Andric : BreakpointResolver(bp, BreakpointResolver::NameResolver), 630b57cec5SDimitry Andric m_kernel_name(name) {} 640b57cec5SDimitry Andric GetDescription(Stream * strm)650b57cec5SDimitry Andric void GetDescription(Stream *strm) override { 660b57cec5SDimitry Andric if (strm) 670b57cec5SDimitry Andric strm->Printf("RenderScript kernel breakpoint for '%s'", 680b57cec5SDimitry Andric m_kernel_name.AsCString()); 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric Dump(Stream * s)710b57cec5SDimitry Andric void Dump(Stream *s) const override {} 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric Searcher::CallbackReturn SearchCallback(SearchFilter &filter, 749dba64beSDimitry Andric SymbolContext &context, 759dba64beSDimitry Andric Address *addr) override; 760b57cec5SDimitry Andric GetDepth()770b57cec5SDimitry Andric lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric lldb::BreakpointResolverSP CopyForBreakpoint(lldb::BreakpointSP & breakpoint)805ffd83dbSDimitry Andric CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override { 810b57cec5SDimitry Andric lldb::BreakpointResolverSP ret_sp( 825ffd83dbSDimitry Andric new RSBreakpointResolver(breakpoint, m_kernel_name)); 830b57cec5SDimitry Andric return ret_sp; 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric protected: 870b57cec5SDimitry Andric ConstString m_kernel_name; 880b57cec5SDimitry Andric }; 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric class RSReduceBreakpointResolver : public BreakpointResolver { 910b57cec5SDimitry Andric public: 920b57cec5SDimitry Andric enum ReduceKernelTypeFlags { 930b57cec5SDimitry Andric eKernelTypeAll = ~(0), 940b57cec5SDimitry Andric eKernelTypeNone = 0, 950b57cec5SDimitry Andric eKernelTypeAccum = (1 << 0), 960b57cec5SDimitry Andric eKernelTypeInit = (1 << 1), 970b57cec5SDimitry Andric eKernelTypeComb = (1 << 2), 980b57cec5SDimitry Andric eKernelTypeOutC = (1 << 3), 990b57cec5SDimitry Andric eKernelTypeHalter = (1 << 4) 1000b57cec5SDimitry Andric }; 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric RSReduceBreakpointResolver( 1035ffd83dbSDimitry Andric const lldb::BreakpointSP &breakpoint, ConstString reduce_name, 1040b57cec5SDimitry Andric std::vector<lldb_renderscript::RSModuleDescriptorSP> *rs_modules, 1050b57cec5SDimitry Andric int kernel_types = eKernelTypeAll) BreakpointResolver(breakpoint,BreakpointResolver::NameResolver)1060b57cec5SDimitry Andric : BreakpointResolver(breakpoint, BreakpointResolver::NameResolver), 1070b57cec5SDimitry Andric m_reduce_name(reduce_name), m_rsmodules(rs_modules), 1080b57cec5SDimitry Andric m_kernel_types(kernel_types) { 1090b57cec5SDimitry Andric // The reduce breakpoint resolver handles adding breakpoints for named 1100b57cec5SDimitry Andric // reductions. 1110b57cec5SDimitry Andric // Breakpoints will be resolved for all constituent kernels in the named 1120b57cec5SDimitry Andric // reduction 1130b57cec5SDimitry Andric } 1140b57cec5SDimitry Andric GetDescription(Stream * strm)1150b57cec5SDimitry Andric void GetDescription(Stream *strm) override { 1160b57cec5SDimitry Andric if (strm) 1170b57cec5SDimitry Andric strm->Printf("RenderScript reduce breakpoint for '%s'", 1180b57cec5SDimitry Andric m_reduce_name.AsCString()); 1190b57cec5SDimitry Andric } 1200b57cec5SDimitry Andric Dump(Stream * s)1210b57cec5SDimitry Andric void Dump(Stream *s) const override {} 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric Searcher::CallbackReturn SearchCallback(SearchFilter &filter, 1249dba64beSDimitry Andric SymbolContext &context, 1259dba64beSDimitry Andric Address *addr) override; 1260b57cec5SDimitry Andric GetDepth()1270b57cec5SDimitry Andric lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric lldb::BreakpointResolverSP CopyForBreakpoint(lldb::BreakpointSP & breakpoint)1305ffd83dbSDimitry Andric CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override { 1310b57cec5SDimitry Andric lldb::BreakpointResolverSP ret_sp(new RSReduceBreakpointResolver( 1325ffd83dbSDimitry Andric breakpoint, m_reduce_name, m_rsmodules, m_kernel_types)); 1330b57cec5SDimitry Andric return ret_sp; 1340b57cec5SDimitry Andric } 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric private: 1370b57cec5SDimitry Andric ConstString m_reduce_name; // The name of the reduction 1380b57cec5SDimitry Andric std::vector<lldb_renderscript::RSModuleDescriptorSP> *m_rsmodules; 1390b57cec5SDimitry Andric int m_kernel_types; 1400b57cec5SDimitry Andric }; 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric struct RSKernelDescriptor { 1430b57cec5SDimitry Andric public: RSKernelDescriptorRSKernelDescriptor1440b57cec5SDimitry Andric RSKernelDescriptor(const RSModuleDescriptor *module, llvm::StringRef name, 1450b57cec5SDimitry Andric uint32_t slot) 1460b57cec5SDimitry Andric : m_module(module), m_name(name), m_slot(slot) {} 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric void Dump(Stream &strm) const; 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric const RSModuleDescriptor *m_module; 1510b57cec5SDimitry Andric ConstString m_name; 1520b57cec5SDimitry Andric RSSlot m_slot; 1530b57cec5SDimitry Andric }; 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric struct RSGlobalDescriptor { 1560b57cec5SDimitry Andric public: RSGlobalDescriptorRSGlobalDescriptor1570b57cec5SDimitry Andric RSGlobalDescriptor(const RSModuleDescriptor *module, llvm::StringRef name) 1580b57cec5SDimitry Andric : m_module(module), m_name(name) {} 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric void Dump(Stream &strm) const; 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric const RSModuleDescriptor *m_module; 1630b57cec5SDimitry Andric ConstString m_name; 1640b57cec5SDimitry Andric }; 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric struct RSReductionDescriptor { 1670b57cec5SDimitry Andric RSReductionDescriptor(const RSModuleDescriptor *module, uint32_t sig, 1680b57cec5SDimitry Andric uint32_t accum_data_size, llvm::StringRef name, 1690b57cec5SDimitry Andric llvm::StringRef init_name, llvm::StringRef accum_name, 1700b57cec5SDimitry Andric llvm::StringRef comb_name, llvm::StringRef outc_name, 1710b57cec5SDimitry Andric llvm::StringRef halter_name = ".") m_moduleRSReductionDescriptor1720b57cec5SDimitry Andric : m_module(module), m_reduce_name(name), m_init_name(init_name), 1730b57cec5SDimitry Andric m_accum_name(accum_name), m_comb_name(comb_name), 1740b57cec5SDimitry Andric m_outc_name(outc_name), m_halter_name(halter_name) { 1750b57cec5SDimitry Andric // TODO Check whether the combiner is an autogenerated name, and track 1760b57cec5SDimitry Andric // this 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric void Dump(Stream &strm) const; 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric const RSModuleDescriptor *m_module; 1820b57cec5SDimitry Andric ConstString m_reduce_name; // This is the name given to the general reduction 1830b57cec5SDimitry Andric // as a group as passed to pragma 1840b57cec5SDimitry Andric // reduce(m_reduce_name). There is no kernel function with this name 1850b57cec5SDimitry Andric ConstString m_init_name; // The name of the initializer name. "." if no 1860b57cec5SDimitry Andric // initializer given 1870b57cec5SDimitry Andric ConstString m_accum_name; // The accumulator function name. "." if not given 1880b57cec5SDimitry Andric ConstString m_comb_name; // The name of the combiner function. If this was not 1890b57cec5SDimitry Andric // given, a name is generated by the 1900b57cec5SDimitry Andric // compiler. TODO 1910b57cec5SDimitry Andric ConstString m_outc_name; // The name of the outconverter 1920b57cec5SDimitry Andric 1930b57cec5SDimitry Andric ConstString m_halter_name; // The name of the halter function. XXX This is not 1940b57cec5SDimitry Andric // yet specified by the RenderScript 1950b57cec5SDimitry Andric // compiler or runtime, and its semantics and existence is still under 1960b57cec5SDimitry Andric // discussion by the 1970b57cec5SDimitry Andric // RenderScript Contributors 1980b57cec5SDimitry Andric RSSlot m_accum_sig; // metatdata signature for this reduction (bitwise mask of 1990b57cec5SDimitry Andric // type information (see 2000b57cec5SDimitry Andric // libbcc/include/bcinfo/MetadataExtractor.h 2010b57cec5SDimitry Andric uint32_t m_accum_data_size; // Data size of the accumulator function input 2020b57cec5SDimitry Andric bool m_comb_name_generated; // Was the combiner name generated by the compiler 2030b57cec5SDimitry Andric }; 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric class RSModuleDescriptor { 2060b57cec5SDimitry Andric std::string m_slang_version; 2070b57cec5SDimitry Andric std::string m_bcc_version; 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric bool ParseVersionInfo(llvm::StringRef *, size_t n_lines); 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric bool ParseExportForeachCount(llvm::StringRef *, size_t n_lines); 2120b57cec5SDimitry Andric 2130b57cec5SDimitry Andric bool ParseExportVarCount(llvm::StringRef *, size_t n_lines); 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric bool ParseExportReduceCount(llvm::StringRef *, size_t n_lines); 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric bool ParseBuildChecksum(llvm::StringRef *, size_t n_lines); 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric bool ParsePragmaCount(llvm::StringRef *, size_t n_lines); 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric public: RSModuleDescriptor(const lldb::ModuleSP & module)2220b57cec5SDimitry Andric RSModuleDescriptor(const lldb::ModuleSP &module) : m_module(module) {} 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric ~RSModuleDescriptor() = default; 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric bool ParseRSInfo(); 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric void Dump(Stream &strm) const; 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric void WarnIfVersionMismatch(Stream *s) const; 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric const lldb::ModuleSP m_module; 2330b57cec5SDimitry Andric std::vector<RSKernelDescriptor> m_kernels; 2340b57cec5SDimitry Andric std::vector<RSGlobalDescriptor> m_globals; 2350b57cec5SDimitry Andric std::vector<RSReductionDescriptor> m_reductions; 2360b57cec5SDimitry Andric std::map<std::string, std::string> m_pragmas; 2370b57cec5SDimitry Andric std::string m_resname; 2380b57cec5SDimitry Andric }; 2390b57cec5SDimitry Andric 2400b57cec5SDimitry Andric struct RSScriptGroupDescriptor { 2410b57cec5SDimitry Andric struct Kernel { 2420b57cec5SDimitry Andric ConstString m_name; 2430b57cec5SDimitry Andric lldb::addr_t m_addr; 2440b57cec5SDimitry Andric }; 2450b57cec5SDimitry Andric ConstString m_name; 2460b57cec5SDimitry Andric std::vector<Kernel> m_kernels; 2470b57cec5SDimitry Andric }; 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andric typedef std::vector<RSScriptGroupDescriptorSP> RSScriptGroupList; 2500b57cec5SDimitry Andric 2510b57cec5SDimitry Andric class RSScriptGroupBreakpointResolver : public BreakpointResolver { 2520b57cec5SDimitry Andric public: RSScriptGroupBreakpointResolver(const lldb::BreakpointSP & bp,ConstString name,const RSScriptGroupList & groups,bool stop_on_all)2535ffd83dbSDimitry Andric RSScriptGroupBreakpointResolver(const lldb::BreakpointSP &bp, 2545ffd83dbSDimitry Andric ConstString name, 2550b57cec5SDimitry Andric const RSScriptGroupList &groups, 2560b57cec5SDimitry Andric bool stop_on_all) 2570b57cec5SDimitry Andric : BreakpointResolver(bp, BreakpointResolver::NameResolver), 2580b57cec5SDimitry Andric m_group_name(name), m_script_groups(groups), 2590b57cec5SDimitry Andric m_stop_on_all(stop_on_all) {} 2600b57cec5SDimitry Andric GetDescription(Stream * strm)2610b57cec5SDimitry Andric void GetDescription(Stream *strm) override { 2620b57cec5SDimitry Andric if (strm) 2630b57cec5SDimitry Andric strm->Printf("RenderScript ScriptGroup breakpoint for '%s'", 2640b57cec5SDimitry Andric m_group_name.AsCString()); 2650b57cec5SDimitry Andric } 2660b57cec5SDimitry Andric Dump(Stream * s)2670b57cec5SDimitry Andric void Dump(Stream *s) const override {} 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric Searcher::CallbackReturn SearchCallback(SearchFilter &filter, 2709dba64beSDimitry Andric SymbolContext &context, 2719dba64beSDimitry Andric Address *addr) override; 2720b57cec5SDimitry Andric GetDepth()2730b57cec5SDimitry Andric lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric lldb::BreakpointResolverSP CopyForBreakpoint(lldb::BreakpointSP & breakpoint)2765ffd83dbSDimitry Andric CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override { 2770b57cec5SDimitry Andric lldb::BreakpointResolverSP ret_sp(new RSScriptGroupBreakpointResolver( 2785ffd83dbSDimitry Andric breakpoint, m_group_name, m_script_groups, m_stop_on_all)); 2790b57cec5SDimitry Andric return ret_sp; 2800b57cec5SDimitry Andric } 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric protected: 2830b57cec5SDimitry Andric const RSScriptGroupDescriptorSP FindScriptGroup(ConstString name)2840b57cec5SDimitry Andric FindScriptGroup(ConstString name) const { 2850b57cec5SDimitry Andric for (auto sg : m_script_groups) { 2860b57cec5SDimitry Andric if (ConstString::Compare(sg->m_name, name) == 0) 2870b57cec5SDimitry Andric return sg; 2880b57cec5SDimitry Andric } 2890b57cec5SDimitry Andric return RSScriptGroupDescriptorSP(); 2900b57cec5SDimitry Andric } 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric ConstString m_group_name; 2930b57cec5SDimitry Andric const RSScriptGroupList &m_script_groups; 2940b57cec5SDimitry Andric bool m_stop_on_all; 2950b57cec5SDimitry Andric }; 2960b57cec5SDimitry Andric } // namespace lldb_renderscript 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric class RenderScriptRuntime : public lldb_private::CPPLanguageRuntime { 2990b57cec5SDimitry Andric public: 3000b57cec5SDimitry Andric enum ModuleKind { 3010b57cec5SDimitry Andric eModuleKindIgnored, 3020b57cec5SDimitry Andric eModuleKindLibRS, 3030b57cec5SDimitry Andric eModuleKindDriver, 3040b57cec5SDimitry Andric eModuleKindImpl, 3050b57cec5SDimitry Andric eModuleKindKernelObj 3060b57cec5SDimitry Andric }; 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric ~RenderScriptRuntime() override; 3090b57cec5SDimitry Andric 3100b57cec5SDimitry Andric // Static Functions 3110b57cec5SDimitry Andric static void Initialize(); 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric static void Terminate(); 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric static lldb_private::LanguageRuntime * 3160b57cec5SDimitry Andric CreateInstance(Process *process, lldb::LanguageType language); 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric static lldb::CommandObjectSP 3190b57cec5SDimitry Andric GetCommandObject(CommandInterpreter &interpreter); 3200b57cec5SDimitry Andric 3210b57cec5SDimitry Andric static lldb_private::ConstString GetPluginNameStatic(); 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric static char ID; 3240b57cec5SDimitry Andric isA(const void * ClassID)3250b57cec5SDimitry Andric bool isA(const void *ClassID) const override { 3260b57cec5SDimitry Andric return ClassID == &ID || CPPLanguageRuntime::isA(ClassID); 3270b57cec5SDimitry Andric } 3280b57cec5SDimitry Andric classof(const LanguageRuntime * runtime)3290b57cec5SDimitry Andric static bool classof(const LanguageRuntime *runtime) { 3300b57cec5SDimitry Andric return runtime->isA(&ID); 3310b57cec5SDimitry Andric } 3320b57cec5SDimitry Andric 3330b57cec5SDimitry Andric static bool IsRenderScriptModule(const lldb::ModuleSP &module_sp); 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric static ModuleKind GetModuleKind(const lldb::ModuleSP &module_sp); 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric static void ModulesDidLoad(const lldb::ProcessSP &process_sp, 3380b57cec5SDimitry Andric const ModuleList &module_list); 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric bool GetDynamicTypeAndAddress(ValueObject &in_value, 3410b57cec5SDimitry Andric lldb::DynamicValueType use_dynamic, 3420b57cec5SDimitry Andric TypeAndOrName &class_type_or_name, 3430b57cec5SDimitry Andric Address &address, 3440b57cec5SDimitry Andric Value::ValueType &value_type) override; 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name, 3470b57cec5SDimitry Andric ValueObject &static_value) override; 3480b57cec5SDimitry Andric 3490b57cec5SDimitry Andric bool CouldHaveDynamicValue(ValueObject &in_value) override; 3500b57cec5SDimitry Andric 3515ffd83dbSDimitry Andric lldb::BreakpointResolverSP 3525ffd83dbSDimitry Andric CreateExceptionResolver(const lldb::BreakpointSP &bp, 3535ffd83dbSDimitry Andric bool catch_bp, bool throw_bp) override; 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric bool LoadModule(const lldb::ModuleSP &module_sp); 3560b57cec5SDimitry Andric 3570b57cec5SDimitry Andric void DumpModules(Stream &strm) const; 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric void DumpContexts(Stream &strm) const; 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric void DumpKernels(Stream &strm) const; 3620b57cec5SDimitry Andric 3630b57cec5SDimitry Andric bool DumpAllocation(Stream &strm, StackFrame *frame_ptr, const uint32_t id); 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric void ListAllocations(Stream &strm, StackFrame *frame_ptr, 3660b57cec5SDimitry Andric const uint32_t index); 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric bool RecomputeAllAllocations(Stream &strm, StackFrame *frame_ptr); 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric bool PlaceBreakpointOnKernel( 3710b57cec5SDimitry Andric lldb::TargetSP target, Stream &messages, const char *name, 3720b57cec5SDimitry Andric const lldb_renderscript::RSCoordinate *coords = nullptr); 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric bool PlaceBreakpointOnReduction( 3750b57cec5SDimitry Andric lldb::TargetSP target, Stream &messages, const char *reduce_name, 3760b57cec5SDimitry Andric const lldb_renderscript::RSCoordinate *coords = nullptr, 3770b57cec5SDimitry Andric int kernel_types = ~(0)); 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric bool PlaceBreakpointOnScriptGroup(lldb::TargetSP target, Stream &strm, 3800b57cec5SDimitry Andric ConstString name, bool stop_on_all); 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric void SetBreakAllKernels(bool do_break, lldb::TargetSP target); 3830b57cec5SDimitry Andric 3840b57cec5SDimitry Andric void DumpStatus(Stream &strm) const; 3850b57cec5SDimitry Andric 3860b57cec5SDimitry Andric void ModulesDidLoad(const ModuleList &module_list) override; 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric bool LoadAllocation(Stream &strm, const uint32_t alloc_id, 3890b57cec5SDimitry Andric const char *filename, StackFrame *frame_ptr); 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andric bool SaveAllocation(Stream &strm, const uint32_t alloc_id, 3920b57cec5SDimitry Andric const char *filename, StackFrame *frame_ptr); 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric void Update(); 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric void Initiate(); 3970b57cec5SDimitry Andric GetScriptGroups()3980b57cec5SDimitry Andric const lldb_renderscript::RSScriptGroupList &GetScriptGroups() const { 3990b57cec5SDimitry Andric return m_scriptGroups; 4000b57cec5SDimitry Andric }; 4010b57cec5SDimitry Andric IsKnownKernel(ConstString name)4020b57cec5SDimitry Andric bool IsKnownKernel(ConstString name) { 4030b57cec5SDimitry Andric for (const auto &module : m_rsmodules) 4040b57cec5SDimitry Andric for (const auto &kernel : module->m_kernels) 4050b57cec5SDimitry Andric if (kernel.m_name == name) 4060b57cec5SDimitry Andric return true; 4070b57cec5SDimitry Andric return false; 4080b57cec5SDimitry Andric } 4090b57cec5SDimitry Andric 4105ffd83dbSDimitry Andric bool GetOverrideExprOptions(clang::TargetOptions &prototype); 4115ffd83dbSDimitry Andric 4120b57cec5SDimitry Andric // PluginInterface protocol 4130b57cec5SDimitry Andric lldb_private::ConstString GetPluginName() override; 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric uint32_t GetPluginVersion() override; 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric static bool GetKernelCoordinate(lldb_renderscript::RSCoordinate &coord, 4180b57cec5SDimitry Andric Thread *thread_ptr); 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric bool ResolveKernelName(lldb::addr_t kernel_address, ConstString &name); 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric protected: 4230b57cec5SDimitry Andric struct ScriptDetails; 4240b57cec5SDimitry Andric struct AllocationDetails; 4250b57cec5SDimitry Andric struct Element; 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric lldb_renderscript::RSScriptGroupList m_scriptGroups; 4280b57cec5SDimitry Andric InitSearchFilter(lldb::TargetSP target)4290b57cec5SDimitry Andric void InitSearchFilter(lldb::TargetSP target) { 4300b57cec5SDimitry Andric if (!m_filtersp) 4315ffd83dbSDimitry Andric m_filtersp = 4325ffd83dbSDimitry Andric std::make_shared<SearchFilterForUnconstrainedSearches>(target); 4330b57cec5SDimitry Andric } 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andric void FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp); 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric void LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind); 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric bool RefreshAllocation(AllocationDetails *alloc, StackFrame *frame_ptr); 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andric bool EvalRSExpression(const char *expression, StackFrame *frame_ptr, 4420b57cec5SDimitry Andric uint64_t *result); 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric lldb::BreakpointSP CreateScriptGroupBreakpoint(ConstString name, 4450b57cec5SDimitry Andric bool multi); 4460b57cec5SDimitry Andric 4470b57cec5SDimitry Andric lldb::BreakpointSP CreateKernelBreakpoint(ConstString name); 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric lldb::BreakpointSP CreateReductionBreakpoint(ConstString name, 4500b57cec5SDimitry Andric int kernel_types); 4510b57cec5SDimitry Andric 4520b57cec5SDimitry Andric void BreakOnModuleKernels( 4530b57cec5SDimitry Andric const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp); 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric struct RuntimeHook; 4560b57cec5SDimitry Andric typedef void (RenderScriptRuntime::*CaptureStateFn)( 4570b57cec5SDimitry Andric RuntimeHook *hook_info, 4580b57cec5SDimitry Andric ExecutionContext &context); // Please do this! 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric struct HookDefn { 4610b57cec5SDimitry Andric const char *name; 4620b57cec5SDimitry Andric const char *symbol_name_m32; // mangled name for the 32 bit architectures 4630b57cec5SDimitry Andric const char *symbol_name_m64; // mangled name for the 64 bit archs 4640b57cec5SDimitry Andric uint32_t version; 4650b57cec5SDimitry Andric ModuleKind kind; 4660b57cec5SDimitry Andric CaptureStateFn grabber; 4670b57cec5SDimitry Andric }; 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric struct RuntimeHook { 4700b57cec5SDimitry Andric lldb::addr_t address; 4710b57cec5SDimitry Andric const HookDefn *defn; 4720b57cec5SDimitry Andric lldb::BreakpointSP bp_sp; 4730b57cec5SDimitry Andric }; 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andric typedef std::shared_ptr<RuntimeHook> RuntimeHookSP; 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andric lldb::ModuleSP m_libRS; 4780b57cec5SDimitry Andric lldb::ModuleSP m_libRSDriver; 4790b57cec5SDimitry Andric lldb::ModuleSP m_libRSCpuRef; 4800b57cec5SDimitry Andric std::vector<lldb_renderscript::RSModuleDescriptorSP> m_rsmodules; 4810b57cec5SDimitry Andric 4820b57cec5SDimitry Andric std::vector<std::unique_ptr<ScriptDetails>> m_scripts; 4830b57cec5SDimitry Andric std::vector<std::unique_ptr<AllocationDetails>> m_allocations; 4840b57cec5SDimitry Andric 4850b57cec5SDimitry Andric std::map<lldb::addr_t, lldb_renderscript::RSModuleDescriptorSP> 4860b57cec5SDimitry Andric m_scriptMappings; 4870b57cec5SDimitry Andric std::map<lldb::addr_t, RuntimeHookSP> m_runtimeHooks; 4880b57cec5SDimitry Andric std::map<lldb::user_id_t, std::unique_ptr<lldb_renderscript::RSCoordinate>> 4890b57cec5SDimitry Andric m_conditional_breaks; 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andric lldb::SearchFilterSP 4920b57cec5SDimitry Andric m_filtersp; // Needed to create breakpoints through Target API 4930b57cec5SDimitry Andric 4940b57cec5SDimitry Andric bool m_initiated; 4950b57cec5SDimitry Andric bool m_debuggerPresentFlagged; 4960b57cec5SDimitry Andric bool m_breakAllKernels; 4970b57cec5SDimitry Andric static const HookDefn s_runtimeHookDefns[]; 4980b57cec5SDimitry Andric static const size_t s_runtimeHookCount; 4990b57cec5SDimitry Andric LLVMUserExpression::IRPasses *m_ir_passes; 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric private: 5020b57cec5SDimitry Andric RenderScriptRuntime(Process *process); // Call CreateInstance instead. 5030b57cec5SDimitry Andric 5040b57cec5SDimitry Andric static bool HookCallback(void *baton, StoppointCallbackContext *ctx, 5050b57cec5SDimitry Andric lldb::user_id_t break_id, 5060b57cec5SDimitry Andric lldb::user_id_t break_loc_id); 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric static bool KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx, 5090b57cec5SDimitry Andric lldb::user_id_t break_id, 5100b57cec5SDimitry Andric lldb::user_id_t break_loc_id); 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric void HookCallback(RuntimeHook *hook_info, ExecutionContext &context); 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric // Callback function when 'debugHintScriptGroup2' executes on the target. 5150b57cec5SDimitry Andric void CaptureDebugHintScriptGroup2(RuntimeHook *hook_info, 5160b57cec5SDimitry Andric ExecutionContext &context); 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric void CaptureScriptInit(RuntimeHook *hook_info, ExecutionContext &context); 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric void CaptureAllocationInit(RuntimeHook *hook_info, ExecutionContext &context); 5210b57cec5SDimitry Andric 5220b57cec5SDimitry Andric void CaptureAllocationDestroy(RuntimeHook *hook_info, 5230b57cec5SDimitry Andric ExecutionContext &context); 5240b57cec5SDimitry Andric 5250b57cec5SDimitry Andric void CaptureSetGlobalVar(RuntimeHook *hook_info, ExecutionContext &context); 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric void CaptureScriptInvokeForEachMulti(RuntimeHook *hook_info, 5280b57cec5SDimitry Andric ExecutionContext &context); 5290b57cec5SDimitry Andric 5300b57cec5SDimitry Andric AllocationDetails *FindAllocByID(Stream &strm, const uint32_t alloc_id); 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric std::shared_ptr<uint8_t> GetAllocationData(AllocationDetails *alloc, 5330b57cec5SDimitry Andric StackFrame *frame_ptr); 5340b57cec5SDimitry Andric 5350b57cec5SDimitry Andric void SetElementSize(Element &elem); 5360b57cec5SDimitry Andric 5370b57cec5SDimitry Andric static bool GetFrameVarAsUnsigned(const lldb::StackFrameSP, 5380b57cec5SDimitry Andric const char *var_name, uint64_t &val); 5390b57cec5SDimitry Andric 5400b57cec5SDimitry Andric void FindStructTypeName(Element &elem, StackFrame *frame_ptr); 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andric size_t PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer, 5430b57cec5SDimitry Andric size_t offset, const Element &elem); 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric size_t CalculateElementHeaderSize(const Element &elem); 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andric void SetConditional(lldb::BreakpointSP bp, lldb_private::Stream &messages, 5480b57cec5SDimitry Andric const lldb_renderscript::RSCoordinate &coord); 5490b57cec5SDimitry Andric // 5500b57cec5SDimitry Andric // Helper functions for jitting the runtime 5510b57cec5SDimitry Andric // 5520b57cec5SDimitry Andric 5530b57cec5SDimitry Andric bool JITDataPointer(AllocationDetails *alloc, StackFrame *frame_ptr, 5540b57cec5SDimitry Andric uint32_t x = 0, uint32_t y = 0, uint32_t z = 0); 5550b57cec5SDimitry Andric 5560b57cec5SDimitry Andric bool JITTypePointer(AllocationDetails *alloc, StackFrame *frame_ptr); 5570b57cec5SDimitry Andric 5580b57cec5SDimitry Andric bool JITTypePacked(AllocationDetails *alloc, StackFrame *frame_ptr); 5590b57cec5SDimitry Andric 5600b57cec5SDimitry Andric bool JITElementPacked(Element &elem, const lldb::addr_t context, 5610b57cec5SDimitry Andric StackFrame *frame_ptr); 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric bool JITAllocationSize(AllocationDetails *alloc, StackFrame *frame_ptr); 5640b57cec5SDimitry Andric 5650b57cec5SDimitry Andric bool JITSubelements(Element &elem, const lldb::addr_t context, 5660b57cec5SDimitry Andric StackFrame *frame_ptr); 5670b57cec5SDimitry Andric 5680b57cec5SDimitry Andric bool JITAllocationStride(AllocationDetails *alloc, StackFrame *frame_ptr); 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric // Search for a script detail object using a target address. 5710b57cec5SDimitry Andric // If a script does not currently exist this function will return nullptr. 5720b57cec5SDimitry Andric // If 'create' is true and there is no previous script with this address, 5730b57cec5SDimitry Andric // then a new Script detail object will be created for this address and 5740b57cec5SDimitry Andric // returned. 5750b57cec5SDimitry Andric ScriptDetails *LookUpScript(lldb::addr_t address, bool create); 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric // Search for a previously saved allocation detail object using a target 5780b57cec5SDimitry Andric // address. 5790b57cec5SDimitry Andric // If an allocation does not exist for this address then nullptr will be 5800b57cec5SDimitry Andric // returned. 5810b57cec5SDimitry Andric AllocationDetails *LookUpAllocation(lldb::addr_t address); 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andric // Creates a new allocation with the specified address assigning a new ID and 5840b57cec5SDimitry Andric // removes 5850b57cec5SDimitry Andric // any previous stored allocation which has the same address. 5860b57cec5SDimitry Andric AllocationDetails *CreateAllocation(lldb::addr_t address); 5870b57cec5SDimitry Andric 5880b57cec5SDimitry Andric bool GetIRPasses(LLVMUserExpression::IRPasses &passes) override; 5890b57cec5SDimitry Andric }; 5900b57cec5SDimitry Andric 5910b57cec5SDimitry Andric } // namespace lldb_private 5920b57cec5SDimitry Andric 5935ffd83dbSDimitry Andric #endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H 594