15ec532a9SColin Riley //===-- RenderScriptRuntime.h -----------------------------------*- C++ -*-===// 25ec532a9SColin Riley // 35ec532a9SColin Riley // The LLVM Compiler Infrastructure 45ec532a9SColin Riley // 55ec532a9SColin Riley // This file is distributed under the University of Illinois Open Source 65ec532a9SColin Riley // License. See LICENSE.TXT for details. 75ec532a9SColin Riley // 85ec532a9SColin Riley //===----------------------------------------------------------------------===// 95ec532a9SColin Riley 105ec532a9SColin Riley #ifndef liblldb_RenderScriptRuntime_h_ 115ec532a9SColin Riley #define liblldb_RenderScriptRuntime_h_ 125ec532a9SColin Riley 135ec532a9SColin Riley // C Includes 145ec532a9SColin Riley // C++ Includes 15222b937cSEugene Zelenko #include <array> 16222b937cSEugene Zelenko #include <map> 17222b937cSEugene Zelenko #include <memory> 18222b937cSEugene Zelenko #include <string> 19222b937cSEugene Zelenko #include <vector> 20222b937cSEugene Zelenko 215ec532a9SColin Riley // Other libraries and framework includes 225ec532a9SColin Riley // Project includes 235ec532a9SColin Riley #include "lldb/lldb-private.h" 245ec532a9SColin Riley #include "lldb/Target/LanguageRuntime.h" 255ec532a9SColin Riley #include "lldb/Target/CPPLanguageRuntime.h" 265ec532a9SColin Riley #include "lldb/Core/Module.h" 275ec532a9SColin Riley 28222b937cSEugene Zelenko namespace lldb_private { 29222b937cSEugene Zelenko namespace lldb_renderscript { 3098156583SEwan Crawford 315ec532a9SColin Riley typedef uint32_t RSSlot; 325ec532a9SColin Riley class RSModuleDescriptor; 334640cde1SColin Riley struct RSGlobalDescriptor; 344640cde1SColin Riley struct RSKernelDescriptor; 354640cde1SColin Riley 364640cde1SColin Riley typedef std::shared_ptr<RSModuleDescriptor> RSModuleDescriptorSP; 374640cde1SColin Riley typedef std::shared_ptr<RSGlobalDescriptor> RSGlobalDescriptorSP; 384640cde1SColin Riley typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP; 394640cde1SColin Riley 4098156583SEwan Crawford // Breakpoint Resolvers decide where a breakpoint is placed, 4198156583SEwan Crawford // so having our own allows us to limit the search scope to RS kernel modules. 4298156583SEwan Crawford // As well as check for .expand kernels as a fallback. 4398156583SEwan Crawford class RSBreakpointResolver : public BreakpointResolver 4498156583SEwan Crawford { 4598156583SEwan Crawford public: 4698156583SEwan Crawford RSBreakpointResolver(Breakpoint *bkpt, ConstString name): 4798156583SEwan Crawford BreakpointResolver (bkpt, BreakpointResolver::NameResolver), 4898156583SEwan Crawford m_kernel_name(name) 4998156583SEwan Crawford { 5098156583SEwan Crawford } 5198156583SEwan Crawford 5298156583SEwan Crawford void 5398156583SEwan Crawford GetDescription(Stream *strm) override 5498156583SEwan Crawford { 5598156583SEwan Crawford if (strm) 5698156583SEwan Crawford strm->Printf("RenderScript kernel breakpoint for '%s'", m_kernel_name.AsCString()); 5798156583SEwan Crawford } 5898156583SEwan Crawford 5998156583SEwan Crawford void 6098156583SEwan Crawford Dump(Stream *s) const override 6198156583SEwan Crawford { 6298156583SEwan Crawford } 6398156583SEwan Crawford 6498156583SEwan Crawford Searcher::CallbackReturn 6598156583SEwan Crawford SearchCallback(SearchFilter &filter, 6698156583SEwan Crawford SymbolContext &context, 6798156583SEwan Crawford Address *addr, 6898156583SEwan Crawford bool containing) override; 6998156583SEwan Crawford 7098156583SEwan Crawford Searcher::Depth 7198156583SEwan Crawford GetDepth() override 7298156583SEwan Crawford { 7398156583SEwan Crawford return Searcher::eDepthModule; 7498156583SEwan Crawford } 7598156583SEwan Crawford 7698156583SEwan Crawford lldb::BreakpointResolverSP 7798156583SEwan Crawford CopyForBreakpoint(Breakpoint &breakpoint) override 7898156583SEwan Crawford { 7998156583SEwan Crawford lldb::BreakpointResolverSP ret_sp(new RSBreakpointResolver(&breakpoint, m_kernel_name)); 8098156583SEwan Crawford return ret_sp; 8198156583SEwan Crawford } 8298156583SEwan Crawford 8398156583SEwan Crawford protected: 8498156583SEwan Crawford ConstString m_kernel_name; 8598156583SEwan Crawford }; 865ec532a9SColin Riley 875ec532a9SColin Riley struct RSKernelDescriptor 885ec532a9SColin Riley { 895ec532a9SColin Riley public: 904640cde1SColin Riley RSKernelDescriptor(const RSModuleDescriptor *module, const char *name, uint32_t slot) 915ec532a9SColin Riley : m_module(module) 925ec532a9SColin Riley , m_name(name) 935ec532a9SColin Riley , m_slot(slot) 945ec532a9SColin Riley { 955ec532a9SColin Riley } 965ec532a9SColin Riley 975ec532a9SColin Riley void Dump(Stream &strm) const; 985ec532a9SColin Riley 994640cde1SColin Riley const RSModuleDescriptor *m_module; 1005ec532a9SColin Riley ConstString m_name; 1015ec532a9SColin Riley RSSlot m_slot; 1025ec532a9SColin Riley }; 1035ec532a9SColin Riley 1045ec532a9SColin Riley struct RSGlobalDescriptor 1055ec532a9SColin Riley { 1065ec532a9SColin Riley public: 1074640cde1SColin Riley RSGlobalDescriptor(const RSModuleDescriptor *module, const char *name ) 1085ec532a9SColin Riley : m_module(module) 1095ec532a9SColin Riley , m_name(name) 1105ec532a9SColin Riley { 1115ec532a9SColin Riley } 1125ec532a9SColin Riley 1135ec532a9SColin Riley void Dump(Stream &strm) const; 1145ec532a9SColin Riley 1154640cde1SColin Riley const RSModuleDescriptor *m_module; 1165ec532a9SColin Riley ConstString m_name; 1175ec532a9SColin Riley }; 1185ec532a9SColin Riley 1195ec532a9SColin Riley class RSModuleDescriptor 1205ec532a9SColin Riley { 1215ec532a9SColin Riley public: 1225ec532a9SColin Riley RSModuleDescriptor(const lldb::ModuleSP &module) 1235ec532a9SColin Riley : m_module(module) 1245ec532a9SColin Riley { 1255ec532a9SColin Riley } 1265ec532a9SColin Riley 127222b937cSEugene Zelenko ~RSModuleDescriptor() = default; 1285ec532a9SColin Riley 1295ec532a9SColin Riley bool ParseRSInfo(); 1305ec532a9SColin Riley 1315ec532a9SColin Riley void Dump(Stream &strm) const; 1325ec532a9SColin Riley 1335ec532a9SColin Riley const lldb::ModuleSP m_module; 1345ec532a9SColin Riley std::vector<RSKernelDescriptor> m_kernels; 1355ec532a9SColin Riley std::vector<RSGlobalDescriptor> m_globals; 1364640cde1SColin Riley std::map<std::string, std::string> m_pragmas; 1374640cde1SColin Riley std::string m_resname; 1385ec532a9SColin Riley }; 1395ec532a9SColin Riley 140222b937cSEugene Zelenko } // namespace lldb_renderscript 14198156583SEwan Crawford 1425ec532a9SColin Riley class RenderScriptRuntime : public lldb_private::CPPLanguageRuntime 1435ec532a9SColin Riley { 1445ec532a9SColin Riley public: 145ef20b08fSColin Riley enum ModuleKind 146ef20b08fSColin Riley { 147ef20b08fSColin Riley eModuleKindIgnored, 148ef20b08fSColin Riley eModuleKindLibRS, 149ef20b08fSColin Riley eModuleKindDriver, 150ef20b08fSColin Riley eModuleKindImpl, 151ef20b08fSColin Riley eModuleKindKernelObj 152ef20b08fSColin Riley }; 153ef20b08fSColin Riley 154222b937cSEugene Zelenko ~RenderScriptRuntime() override; 1555ec532a9SColin Riley 1565ec532a9SColin Riley //------------------------------------------------------------------ 1575ec532a9SColin Riley // Static Functions 1585ec532a9SColin Riley //------------------------------------------------------------------ 1595ec532a9SColin Riley static void Initialize(); 1605ec532a9SColin Riley 1615ec532a9SColin Riley static void Terminate(); 1625ec532a9SColin Riley 1635ec532a9SColin Riley static lldb_private::LanguageRuntime *CreateInstance(Process *process, lldb::LanguageType language); 1645ec532a9SColin Riley 1654640cde1SColin Riley static lldb::CommandObjectSP GetCommandObject(CommandInterpreter& interpreter); 1664640cde1SColin Riley 1675ec532a9SColin Riley static lldb_private::ConstString GetPluginNameStatic(); 1685ec532a9SColin Riley 169ef20b08fSColin Riley static bool IsRenderScriptModule(const lldb::ModuleSP &module_sp); 170ef20b08fSColin Riley 171ef20b08fSColin Riley static ModuleKind GetModuleKind(const lldb::ModuleSP &module_sp); 172ef20b08fSColin Riley 173ef20b08fSColin Riley static void ModulesDidLoad(const lldb::ProcessSP& process_sp, const ModuleList &module_list ); 174ef20b08fSColin Riley 175222b937cSEugene Zelenko bool IsVTableName(const char *name) override; 1765ec532a9SColin Riley 177222b937cSEugene Zelenko bool GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic, 1780b6003f3SEnrico Granata TypeAndOrName &class_type_or_name, Address &address, 179222b937cSEugene Zelenko Value::ValueType &value_type) override; 180c74275bcSEnrico Granata 181222b937cSEugene Zelenko TypeAndOrName 182c74275bcSEnrico Granata FixUpDynamicType(const TypeAndOrName& type_and_or_name, 183222b937cSEugene Zelenko ValueObject& static_value) override; 1845ec532a9SColin Riley 185222b937cSEugene Zelenko bool CouldHaveDynamicValue(ValueObject &in_value) override; 1865ec532a9SColin Riley 187222b937cSEugene Zelenko lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) override; 1885ec532a9SColin Riley 1895ec532a9SColin Riley bool LoadModule(const lldb::ModuleSP &module_sp); 1905ec532a9SColin Riley 1915ec532a9SColin Riley bool ProbeModules(const ModuleList module_list); 1925ec532a9SColin Riley 1935ec532a9SColin Riley void DumpModules(Stream &strm) const; 1945ec532a9SColin Riley 1954640cde1SColin Riley void DumpContexts(Stream &strm) const; 1964640cde1SColin Riley 1974640cde1SColin Riley void DumpKernels(Stream &strm) const; 1984640cde1SColin Riley 199a0f08674SEwan Crawford bool DumpAllocation(Stream &strm, StackFrame* frame_ptr, const uint32_t id); 200a0f08674SEwan Crawford 20115f2bd95SEwan Crawford void ListAllocations(Stream &strm, StackFrame* frame_ptr, bool recompute); 20215f2bd95SEwan Crawford 203018f5a7eSEwan Crawford void PlaceBreakpointOnKernel(Stream &strm, const char *name, const std::array<int,3> coords, 204018f5a7eSEwan Crawford Error &error, lldb::TargetSP target); 2054640cde1SColin Riley 2067dc7771cSEwan Crawford void SetBreakAllKernels(bool do_break, lldb::TargetSP target); 2077dc7771cSEwan Crawford 2084640cde1SColin Riley void Status(Stream &strm) const; 2094640cde1SColin Riley 210222b937cSEugene Zelenko size_t GetAlternateManglings(const ConstString &mangled, std::vector<ConstString> &alternates) override { 21192935952SSiva Chandra return static_cast<size_t>(0); 21292935952SSiva Chandra } 21392935952SSiva Chandra 214222b937cSEugene Zelenko void ModulesDidLoad(const ModuleList &module_list) override; 215ef20b08fSColin Riley 21655232f09SEwan Crawford bool LoadAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr); 21755232f09SEwan Crawford 21855232f09SEwan Crawford bool SaveAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr); 21955232f09SEwan Crawford 220ef20b08fSColin Riley void Update(); 221ef20b08fSColin Riley 222ef20b08fSColin Riley void Initiate(); 223ef20b08fSColin Riley 224222b937cSEugene Zelenko //------------------------------------------------------------------ 225222b937cSEugene Zelenko // PluginInterface protocol 226222b937cSEugene Zelenko //------------------------------------------------------------------ 227222b937cSEugene Zelenko lldb_private::ConstString GetPluginName() override; 2284640cde1SColin Riley 229222b937cSEugene Zelenko uint32_t GetPluginVersion() override; 230222b937cSEugene Zelenko 231222b937cSEugene Zelenko protected: 23215f2bd95SEwan Crawford struct ScriptDetails; 23315f2bd95SEwan Crawford struct AllocationDetails; 2348b244e21SEwan Crawford struct Element; 23515f2bd95SEwan Crawford 2367dc7771cSEwan Crawford void InitSearchFilter(lldb::TargetSP target) 2377dc7771cSEwan Crawford { 2387dc7771cSEwan Crawford if (!m_filtersp) 2397dc7771cSEwan Crawford m_filtersp.reset(new SearchFilterForUnconstrainedSearches(target)); 2407dc7771cSEwan Crawford } 2417dc7771cSEwan Crawford 24298156583SEwan Crawford void FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp); 2434640cde1SColin Riley 2444640cde1SColin Riley void LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind); 2454640cde1SColin Riley 24615f2bd95SEwan Crawford bool RefreshAllocation(AllocationDetails* allocation, StackFrame* frame_ptr); 24715f2bd95SEwan Crawford 24815f2bd95SEwan Crawford bool EvalRSExpression(const char* expression, StackFrame* frame_ptr, uint64_t* result); 24915f2bd95SEwan Crawford 2507dc7771cSEwan Crawford lldb::BreakpointSP CreateKernelBreakpoint(const ConstString& name); 2517dc7771cSEwan Crawford 2527dc7771cSEwan Crawford void BreakOnModuleKernels(const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp); 2537dc7771cSEwan Crawford 2544640cde1SColin Riley struct RuntimeHook; 2554640cde1SColin Riley typedef void (RenderScriptRuntime::*CaptureStateFn)(RuntimeHook* hook_info, ExecutionContext &context); // Please do this! 2564640cde1SColin Riley 2574640cde1SColin Riley struct HookDefn 2584640cde1SColin Riley { 2594640cde1SColin Riley const char * name; 26082780287SAidan Dodds const char * symbol_name_m32; // mangled name for the 32 bit architectures 26182780287SAidan Dodds const char * symbol_name_m64; // mangled name for the 64 bit archs 2624640cde1SColin Riley uint32_t version; 2634640cde1SColin Riley ModuleKind kind; 2644640cde1SColin Riley CaptureStateFn grabber; 2654640cde1SColin Riley }; 2664640cde1SColin Riley 2674640cde1SColin Riley struct RuntimeHook 2684640cde1SColin Riley { 2694640cde1SColin Riley lldb::addr_t address; 2704640cde1SColin Riley const HookDefn *defn; 2714640cde1SColin Riley lldb::BreakpointSP bp_sp; 2724640cde1SColin Riley }; 2734640cde1SColin Riley 2744640cde1SColin Riley typedef std::shared_ptr<RuntimeHook> RuntimeHookSP; 2754640cde1SColin Riley 2764640cde1SColin Riley lldb::ModuleSP m_libRS; 2774640cde1SColin Riley lldb::ModuleSP m_libRSDriver; 2784640cde1SColin Riley lldb::ModuleSP m_libRSCpuRef; 27998156583SEwan Crawford std::vector<lldb_renderscript::RSModuleDescriptorSP> m_rsmodules; 28078f339d1SEwan Crawford 28178f339d1SEwan Crawford std::vector<std::unique_ptr<ScriptDetails>> m_scripts; 28278f339d1SEwan Crawford std::vector<std::unique_ptr<AllocationDetails>> m_allocations; 2834640cde1SColin Riley 28498156583SEwan Crawford std::map<lldb::addr_t, lldb_renderscript::RSModuleDescriptorSP> m_scriptMappings; 2854640cde1SColin Riley std::map<lldb::addr_t, RuntimeHookSP> m_runtimeHooks; 286018f5a7eSEwan Crawford std::map<lldb::user_id_t, std::shared_ptr<int>> m_conditional_breaks; 2874640cde1SColin Riley 2887dc7771cSEwan Crawford lldb::SearchFilterSP m_filtersp; // Needed to create breakpoints through Target API 2897dc7771cSEwan Crawford 290ef20b08fSColin Riley bool m_initiated; 2914640cde1SColin Riley bool m_debuggerPresentFlagged; 2927dc7771cSEwan Crawford bool m_breakAllKernels; 2934640cde1SColin Riley static const HookDefn s_runtimeHookDefns[]; 2944640cde1SColin Riley static const size_t s_runtimeHookCount; 2954640cde1SColin Riley 2965ec532a9SColin Riley private: 297b1651b8dSEwan Crawford // Used to index expression format strings 298b1651b8dSEwan Crawford enum ExpressionStrings 299b1651b8dSEwan Crawford { 300b1651b8dSEwan Crawford eExprGetOffsetPtr = 0, 301b1651b8dSEwan Crawford eExprAllocGetType, 302b1651b8dSEwan Crawford eExprTypeDimX, 303b1651b8dSEwan Crawford eExprTypeDimY, 304b1651b8dSEwan Crawford eExprTypeDimZ, 305b1651b8dSEwan Crawford eExprTypeElemPtr, 306b1651b8dSEwan Crawford eExprElementType, 307b1651b8dSEwan Crawford eExprElementKind, 308b1651b8dSEwan Crawford eExprElementVec, 309b1651b8dSEwan Crawford eExprElementFieldCount, 310b1651b8dSEwan Crawford eExprSubelementsId, 311b1651b8dSEwan Crawford eExprSubelementsName, 312b1651b8dSEwan Crawford eExprSubelementsArrSize 313b1651b8dSEwan Crawford }; 314b1651b8dSEwan Crawford 3155ec532a9SColin Riley RenderScriptRuntime(Process *process); // Call CreateInstance instead. 3164640cde1SColin Riley 3174640cde1SColin Riley static bool HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, 3184640cde1SColin Riley lldb::user_id_t break_loc_id); 3194640cde1SColin Riley 320018f5a7eSEwan Crawford static bool KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx, 321018f5a7eSEwan Crawford lldb::user_id_t break_id, lldb::user_id_t break_loc_id); 322018f5a7eSEwan Crawford 3234640cde1SColin Riley void HookCallback(RuntimeHook* hook_info, ExecutionContext& context); 3244640cde1SColin Riley 32582780287SAidan Dodds bool GetArgSimple(ExecutionContext& context, uint32_t arg, uint64_t* data); 3264640cde1SColin Riley 3274640cde1SColin Riley void CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context); 3284640cde1SColin Riley void CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context); 329e69df382SEwan Crawford void CaptureAllocationDestroy(RuntimeHook* hook_info, ExecutionContext& context); 3304640cde1SColin Riley void CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context); 3314640cde1SColin Riley 332a0f08674SEwan Crawford AllocationDetails* FindAllocByID(Stream &strm, const uint32_t alloc_id); 33355232f09SEwan Crawford std::shared_ptr<uint8_t> GetAllocationData(AllocationDetails* allocation, StackFrame* frame_ptr); 3348b244e21SEwan Crawford void SetElementSize(Element& elem); 335018f5a7eSEwan Crawford static bool GetFrameVarAsUnsigned(const lldb::StackFrameSP, const char* var_name, uint64_t& val); 3368b244e21SEwan Crawford void FindStructTypeName(Element& elem, StackFrame* frame_ptr); 337a0f08674SEwan Crawford 338*26e52a70SEwan Crawford size_t PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer, size_t offset, const Element& elem); 339*26e52a70SEwan Crawford size_t CalculateElementHeaderSize(const Element& elem); 340*26e52a70SEwan Crawford 34115f2bd95SEwan Crawford // 34215f2bd95SEwan Crawford // Helper functions for jitting the runtime 34315f2bd95SEwan Crawford // 344b1651b8dSEwan Crawford const char* JITTemplate(ExpressionStrings e); 345b1651b8dSEwan Crawford 34615f2bd95SEwan Crawford bool JITDataPointer(AllocationDetails* allocation, StackFrame* frame_ptr, 34715f2bd95SEwan Crawford unsigned int x = 0, unsigned int y = 0, unsigned int z = 0); 34815f2bd95SEwan Crawford 34915f2bd95SEwan Crawford bool JITTypePointer(AllocationDetails* allocation, StackFrame* frame_ptr); 35015f2bd95SEwan Crawford 35115f2bd95SEwan Crawford bool JITTypePacked(AllocationDetails* allocation, StackFrame* frame_ptr); 35215f2bd95SEwan Crawford 3538b244e21SEwan Crawford bool JITElementPacked(Element& elem, const lldb::addr_t context, StackFrame* frame_ptr); 35415f2bd95SEwan Crawford 3558b244e21SEwan Crawford bool JITAllocationSize(AllocationDetails* allocation, StackFrame* frame_ptr); 3568b244e21SEwan Crawford 3578b244e21SEwan Crawford bool JITSubelements(Element& elem, const lldb::addr_t context, StackFrame* frame_ptr); 358a0f08674SEwan Crawford 359a0f08674SEwan Crawford bool JITAllocationStride(AllocationDetails* allocation, StackFrame* frame_ptr); 360a0f08674SEwan Crawford 36178f339d1SEwan Crawford // Search for a script detail object using a target address. 36278f339d1SEwan Crawford // If a script does not currently exist this function will return nullptr. 36378f339d1SEwan Crawford // If 'create' is true and there is no previous script with this address, 36478f339d1SEwan Crawford // then a new Script detail object will be created for this address and returned. 36578f339d1SEwan Crawford ScriptDetails* LookUpScript(lldb::addr_t address, bool create); 36678f339d1SEwan Crawford 36778f339d1SEwan Crawford // Search for a previously saved allocation detail object using a target address. 36878f339d1SEwan Crawford // If an allocation does not exist for this address then nullptr will be returned. 36978f339d1SEwan Crawford // If 'create' is true and there is no previous allocation then a new allocation 37078f339d1SEwan Crawford // detail object will be created for this address and returned. 37178f339d1SEwan Crawford AllocationDetails* LookUpAllocation(lldb::addr_t address, bool create); 3725ec532a9SColin Riley }; 3735ec532a9SColin Riley 3745ec532a9SColin Riley } // namespace lldb_private 3755ec532a9SColin Riley 3765ec532a9SColin Riley #endif // liblldb_RenderScriptRuntime_h_ 377