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 void ModulesDidLoad(const ModuleList &module_list) override; 211ef20b08fSColin Riley 21255232f09SEwan Crawford bool LoadAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr); 21355232f09SEwan Crawford 21455232f09SEwan Crawford bool SaveAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr); 21555232f09SEwan Crawford 216ef20b08fSColin Riley void Update(); 217ef20b08fSColin Riley 218ef20b08fSColin Riley void Initiate(); 219ef20b08fSColin Riley 220222b937cSEugene Zelenko //------------------------------------------------------------------ 221222b937cSEugene Zelenko // PluginInterface protocol 222222b937cSEugene Zelenko //------------------------------------------------------------------ 223222b937cSEugene Zelenko lldb_private::ConstString GetPluginName() override; 2244640cde1SColin Riley 225222b937cSEugene Zelenko uint32_t GetPluginVersion() override; 226222b937cSEugene Zelenko 227222b937cSEugene Zelenko protected: 22815f2bd95SEwan Crawford struct ScriptDetails; 22915f2bd95SEwan Crawford struct AllocationDetails; 2308b244e21SEwan Crawford struct Element; 23115f2bd95SEwan Crawford 2327dc7771cSEwan Crawford void InitSearchFilter(lldb::TargetSP target) 2337dc7771cSEwan Crawford { 2347dc7771cSEwan Crawford if (!m_filtersp) 2357dc7771cSEwan Crawford m_filtersp.reset(new SearchFilterForUnconstrainedSearches(target)); 2367dc7771cSEwan Crawford } 2377dc7771cSEwan Crawford 23898156583SEwan Crawford void FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp); 2394640cde1SColin Riley 2404640cde1SColin Riley void LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind); 2414640cde1SColin Riley 24215f2bd95SEwan Crawford bool RefreshAllocation(AllocationDetails* allocation, StackFrame* frame_ptr); 24315f2bd95SEwan Crawford 24415f2bd95SEwan Crawford bool EvalRSExpression(const char* expression, StackFrame* frame_ptr, uint64_t* result); 24515f2bd95SEwan Crawford 2467dc7771cSEwan Crawford lldb::BreakpointSP CreateKernelBreakpoint(const ConstString& name); 2477dc7771cSEwan Crawford 2487dc7771cSEwan Crawford void BreakOnModuleKernels(const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp); 2497dc7771cSEwan Crawford 2504640cde1SColin Riley struct RuntimeHook; 2514640cde1SColin Riley typedef void (RenderScriptRuntime::*CaptureStateFn)(RuntimeHook* hook_info, ExecutionContext &context); // Please do this! 2524640cde1SColin Riley 2534640cde1SColin Riley struct HookDefn 2544640cde1SColin Riley { 2554640cde1SColin Riley const char * name; 25682780287SAidan Dodds const char * symbol_name_m32; // mangled name for the 32 bit architectures 25782780287SAidan Dodds const char * symbol_name_m64; // mangled name for the 64 bit archs 2584640cde1SColin Riley uint32_t version; 2594640cde1SColin Riley ModuleKind kind; 2604640cde1SColin Riley CaptureStateFn grabber; 2614640cde1SColin Riley }; 2624640cde1SColin Riley 2634640cde1SColin Riley struct RuntimeHook 2644640cde1SColin Riley { 2654640cde1SColin Riley lldb::addr_t address; 2664640cde1SColin Riley const HookDefn *defn; 2674640cde1SColin Riley lldb::BreakpointSP bp_sp; 2684640cde1SColin Riley }; 2694640cde1SColin Riley 2704640cde1SColin Riley typedef std::shared_ptr<RuntimeHook> RuntimeHookSP; 2714640cde1SColin Riley 2724640cde1SColin Riley lldb::ModuleSP m_libRS; 2734640cde1SColin Riley lldb::ModuleSP m_libRSDriver; 2744640cde1SColin Riley lldb::ModuleSP m_libRSCpuRef; 27598156583SEwan Crawford std::vector<lldb_renderscript::RSModuleDescriptorSP> m_rsmodules; 27678f339d1SEwan Crawford 27778f339d1SEwan Crawford std::vector<std::unique_ptr<ScriptDetails>> m_scripts; 27878f339d1SEwan Crawford std::vector<std::unique_ptr<AllocationDetails>> m_allocations; 2794640cde1SColin Riley 28098156583SEwan Crawford std::map<lldb::addr_t, lldb_renderscript::RSModuleDescriptorSP> m_scriptMappings; 2814640cde1SColin Riley std::map<lldb::addr_t, RuntimeHookSP> m_runtimeHooks; 282018f5a7eSEwan Crawford std::map<lldb::user_id_t, std::shared_ptr<int>> m_conditional_breaks; 2834640cde1SColin Riley 2847dc7771cSEwan Crawford lldb::SearchFilterSP m_filtersp; // Needed to create breakpoints through Target API 2857dc7771cSEwan Crawford 286ef20b08fSColin Riley bool m_initiated; 2874640cde1SColin Riley bool m_debuggerPresentFlagged; 2887dc7771cSEwan Crawford bool m_breakAllKernels; 2894640cde1SColin Riley static const HookDefn s_runtimeHookDefns[]; 2904640cde1SColin Riley static const size_t s_runtimeHookCount; 2914640cde1SColin Riley 2925ec532a9SColin Riley private: 293b1651b8dSEwan Crawford // Used to index expression format strings 294b1651b8dSEwan Crawford enum ExpressionStrings 295b1651b8dSEwan Crawford { 296b1651b8dSEwan Crawford eExprGetOffsetPtr = 0, 297b1651b8dSEwan Crawford eExprAllocGetType, 298b1651b8dSEwan Crawford eExprTypeDimX, 299b1651b8dSEwan Crawford eExprTypeDimY, 300b1651b8dSEwan Crawford eExprTypeDimZ, 301b1651b8dSEwan Crawford eExprTypeElemPtr, 302b1651b8dSEwan Crawford eExprElementType, 303b1651b8dSEwan Crawford eExprElementKind, 304b1651b8dSEwan Crawford eExprElementVec, 305b1651b8dSEwan Crawford eExprElementFieldCount, 306b1651b8dSEwan Crawford eExprSubelementsId, 307b1651b8dSEwan Crawford eExprSubelementsName, 308b1651b8dSEwan Crawford eExprSubelementsArrSize 309b1651b8dSEwan Crawford }; 310b1651b8dSEwan Crawford 3115ec532a9SColin Riley RenderScriptRuntime(Process *process); // Call CreateInstance instead. 3124640cde1SColin Riley 3134640cde1SColin Riley static bool HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, 3144640cde1SColin Riley lldb::user_id_t break_loc_id); 3154640cde1SColin Riley 316018f5a7eSEwan Crawford static bool KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx, 317018f5a7eSEwan Crawford lldb::user_id_t break_id, lldb::user_id_t break_loc_id); 318018f5a7eSEwan Crawford 3194640cde1SColin Riley void HookCallback(RuntimeHook* hook_info, ExecutionContext& context); 3204640cde1SColin Riley 32182780287SAidan Dodds bool GetArgSimple(ExecutionContext& context, uint32_t arg, uint64_t* data); 3224640cde1SColin Riley 3234640cde1SColin Riley void CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context); 3244640cde1SColin Riley void CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context); 325e69df382SEwan Crawford void CaptureAllocationDestroy(RuntimeHook* hook_info, ExecutionContext& context); 3264640cde1SColin Riley void CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context); 327*e09c44b6SAidan Dodds void CaptureScriptInvokeForEachMulti(RuntimeHook* hook_info, ExecutionContext& context); 3284640cde1SColin Riley 329a0f08674SEwan Crawford AllocationDetails* FindAllocByID(Stream &strm, const uint32_t alloc_id); 33055232f09SEwan Crawford std::shared_ptr<uint8_t> GetAllocationData(AllocationDetails* allocation, StackFrame* frame_ptr); 3318b244e21SEwan Crawford void SetElementSize(Element& elem); 332018f5a7eSEwan Crawford static bool GetFrameVarAsUnsigned(const lldb::StackFrameSP, const char* var_name, uint64_t& val); 3338b244e21SEwan Crawford void FindStructTypeName(Element& elem, StackFrame* frame_ptr); 334a0f08674SEwan Crawford 33526e52a70SEwan Crawford size_t PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer, size_t offset, const Element& elem); 33626e52a70SEwan Crawford size_t CalculateElementHeaderSize(const Element& elem); 33726e52a70SEwan Crawford 33815f2bd95SEwan Crawford // 33915f2bd95SEwan Crawford // Helper functions for jitting the runtime 34015f2bd95SEwan Crawford // 341b1651b8dSEwan Crawford const char* JITTemplate(ExpressionStrings e); 342b1651b8dSEwan Crawford 34315f2bd95SEwan Crawford bool JITDataPointer(AllocationDetails* allocation, StackFrame* frame_ptr, 34415f2bd95SEwan Crawford unsigned int x = 0, unsigned int y = 0, unsigned int z = 0); 34515f2bd95SEwan Crawford 34615f2bd95SEwan Crawford bool JITTypePointer(AllocationDetails* allocation, StackFrame* frame_ptr); 34715f2bd95SEwan Crawford 34815f2bd95SEwan Crawford bool JITTypePacked(AllocationDetails* allocation, StackFrame* frame_ptr); 34915f2bd95SEwan Crawford 3508b244e21SEwan Crawford bool JITElementPacked(Element& elem, const lldb::addr_t context, StackFrame* frame_ptr); 35115f2bd95SEwan Crawford 3528b244e21SEwan Crawford bool JITAllocationSize(AllocationDetails* allocation, StackFrame* frame_ptr); 3538b244e21SEwan Crawford 3548b244e21SEwan Crawford bool JITSubelements(Element& elem, const lldb::addr_t context, StackFrame* frame_ptr); 355a0f08674SEwan Crawford 356a0f08674SEwan Crawford bool JITAllocationStride(AllocationDetails* allocation, StackFrame* frame_ptr); 357a0f08674SEwan Crawford 35878f339d1SEwan Crawford // Search for a script detail object using a target address. 35978f339d1SEwan Crawford // If a script does not currently exist this function will return nullptr. 36078f339d1SEwan Crawford // If 'create' is true and there is no previous script with this address, 36178f339d1SEwan Crawford // then a new Script detail object will be created for this address and returned. 36278f339d1SEwan Crawford ScriptDetails* LookUpScript(lldb::addr_t address, bool create); 36378f339d1SEwan Crawford 36478f339d1SEwan Crawford // Search for a previously saved allocation detail object using a target address. 36578f339d1SEwan Crawford // If an allocation does not exist for this address then nullptr will be returned. 36678f339d1SEwan Crawford // If 'create' is true and there is no previous allocation then a new allocation 36778f339d1SEwan Crawford // detail object will be created for this address and returned. 36878f339d1SEwan Crawford AllocationDetails* LookUpAllocation(lldb::addr_t address, bool create); 3695ec532a9SColin Riley }; 3705ec532a9SColin Riley 3715ec532a9SColin Riley } // namespace lldb_private 3725ec532a9SColin Riley 3735ec532a9SColin Riley #endif // liblldb_RenderScriptRuntime_h_ 374