1 //===-- RenderScriptRuntime.h -----------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_RenderScriptRuntime_h_ 11 #define liblldb_RenderScriptRuntime_h_ 12 13 // C Includes 14 // C++ Includes 15 // Other libraries and framework includes 16 // Project includes 17 #include "lldb/lldb-private.h" 18 #include "lldb/Target/LanguageRuntime.h" 19 #include "lldb/Target/CPPLanguageRuntime.h" 20 #include "lldb/Core/Module.h" 21 22 #include <array> 23 namespace lldb_private 24 { 25 26 namespace lldb_renderscript 27 { 28 29 typedef uint32_t RSSlot; 30 class RSModuleDescriptor; 31 struct RSGlobalDescriptor; 32 struct RSKernelDescriptor; 33 34 typedef std::shared_ptr<RSModuleDescriptor> RSModuleDescriptorSP; 35 typedef std::shared_ptr<RSGlobalDescriptor> RSGlobalDescriptorSP; 36 typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP; 37 38 // Breakpoint Resolvers decide where a breakpoint is placed, 39 // so having our own allows us to limit the search scope to RS kernel modules. 40 // As well as check for .expand kernels as a fallback. 41 class RSBreakpointResolver : public BreakpointResolver 42 { 43 public: 44 45 RSBreakpointResolver(Breakpoint *bkpt, ConstString name): 46 BreakpointResolver (bkpt, BreakpointResolver::NameResolver), 47 m_kernel_name(name) 48 { 49 } 50 51 void 52 GetDescription(Stream *strm) override 53 { 54 if (strm) 55 strm->Printf("RenderScript kernel breakpoint for '%s'", m_kernel_name.AsCString()); 56 } 57 58 void 59 Dump(Stream *s) const override 60 { 61 } 62 63 Searcher::CallbackReturn 64 SearchCallback(SearchFilter &filter, 65 SymbolContext &context, 66 Address *addr, 67 bool containing) override; 68 69 Searcher::Depth 70 GetDepth() override 71 { 72 return Searcher::eDepthModule; 73 } 74 75 lldb::BreakpointResolverSP 76 CopyForBreakpoint(Breakpoint &breakpoint) override 77 { 78 lldb::BreakpointResolverSP ret_sp(new RSBreakpointResolver(&breakpoint, m_kernel_name)); 79 return ret_sp; 80 } 81 82 protected: 83 ConstString m_kernel_name; 84 }; 85 86 struct RSKernelDescriptor 87 { 88 public: 89 RSKernelDescriptor(const RSModuleDescriptor *module, const char *name, uint32_t slot) 90 : m_module(module) 91 , m_name(name) 92 , m_slot(slot) 93 { 94 } 95 96 void Dump(Stream &strm) const; 97 98 const RSModuleDescriptor *m_module; 99 ConstString m_name; 100 RSSlot m_slot; 101 }; 102 103 struct RSGlobalDescriptor 104 { 105 public: 106 RSGlobalDescriptor(const RSModuleDescriptor *module, const char *name ) 107 : m_module(module) 108 , m_name(name) 109 { 110 } 111 112 void Dump(Stream &strm) const; 113 114 const RSModuleDescriptor *m_module; 115 ConstString m_name; 116 }; 117 118 class RSModuleDescriptor 119 { 120 public: 121 RSModuleDescriptor(const lldb::ModuleSP &module) 122 : m_module(module) 123 { 124 } 125 126 ~RSModuleDescriptor() {} 127 128 bool ParseRSInfo(); 129 130 void Dump(Stream &strm) const; 131 132 const lldb::ModuleSP m_module; 133 std::vector<RSKernelDescriptor> m_kernels; 134 std::vector<RSGlobalDescriptor> m_globals; 135 std::map<std::string, std::string> m_pragmas; 136 std::string m_resname; 137 }; 138 139 } // end lldb_renderscript namespace 140 141 class RenderScriptRuntime : public lldb_private::CPPLanguageRuntime 142 { 143 public: 144 145 enum ModuleKind 146 { 147 eModuleKindIgnored, 148 eModuleKindLibRS, 149 eModuleKindDriver, 150 eModuleKindImpl, 151 eModuleKindKernelObj 152 }; 153 154 ~RenderScriptRuntime(); 155 156 //------------------------------------------------------------------ 157 // Static Functions 158 //------------------------------------------------------------------ 159 static void Initialize(); 160 161 static void Terminate(); 162 163 static lldb_private::LanguageRuntime *CreateInstance(Process *process, lldb::LanguageType language); 164 165 static lldb::CommandObjectSP GetCommandObject(CommandInterpreter& interpreter); 166 167 static lldb_private::ConstString GetPluginNameStatic(); 168 169 static bool IsRenderScriptModule(const lldb::ModuleSP &module_sp); 170 171 static ModuleKind GetModuleKind(const lldb::ModuleSP &module_sp); 172 173 static void ModulesDidLoad(const lldb::ProcessSP& process_sp, const ModuleList &module_list ); 174 175 //------------------------------------------------------------------ 176 // PluginInterface protocol 177 //------------------------------------------------------------------ 178 virtual lldb_private::ConstString GetPluginName(); 179 180 virtual uint32_t GetPluginVersion(); 181 182 virtual bool IsVTableName(const char *name); 183 184 virtual bool GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic, 185 TypeAndOrName &class_type_or_name, Address &address, 186 Value::ValueType &value_type); 187 188 virtual TypeAndOrName 189 FixUpDynamicType (const TypeAndOrName& type_and_or_name, 190 ValueObject& static_value); 191 192 virtual bool CouldHaveDynamicValue(ValueObject &in_value); 193 194 virtual lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp); 195 196 bool LoadModule(const lldb::ModuleSP &module_sp); 197 198 bool ProbeModules(const ModuleList module_list); 199 200 void DumpModules(Stream &strm) const; 201 202 void DumpContexts(Stream &strm) const; 203 204 void DumpKernels(Stream &strm) const; 205 206 bool DumpAllocation(Stream &strm, StackFrame* frame_ptr, const uint32_t id); 207 208 void ListAllocations(Stream &strm, StackFrame* frame_ptr, bool recompute); 209 210 void PlaceBreakpointOnKernel(Stream &strm, const char *name, const std::array<int,3> coords, 211 Error &error, lldb::TargetSP target); 212 213 void SetBreakAllKernels(bool do_break, lldb::TargetSP target); 214 215 void Status(Stream &strm) const; 216 217 virtual size_t GetAlternateManglings(const ConstString &mangled, std::vector<ConstString> &alternates) { 218 return static_cast<size_t>(0); 219 } 220 221 virtual void ModulesDidLoad(const ModuleList &module_list ); 222 223 bool LoadAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr); 224 225 bool SaveAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr); 226 227 void Update(); 228 229 void Initiate(); 230 231 protected: 232 233 struct ScriptDetails; 234 struct AllocationDetails; 235 236 void InitSearchFilter(lldb::TargetSP target) 237 { 238 if (!m_filtersp) 239 m_filtersp.reset(new SearchFilterForUnconstrainedSearches(target)); 240 } 241 242 void FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp); 243 244 void LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind); 245 246 bool RefreshAllocation(AllocationDetails* allocation, StackFrame* frame_ptr); 247 248 bool EvalRSExpression(const char* expression, StackFrame* frame_ptr, uint64_t* result); 249 250 lldb::BreakpointSP CreateKernelBreakpoint(const ConstString& name); 251 252 void BreakOnModuleKernels(const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp); 253 254 struct RuntimeHook; 255 typedef void (RenderScriptRuntime::*CaptureStateFn)(RuntimeHook* hook_info, ExecutionContext &context); // Please do this! 256 257 struct HookDefn 258 { 259 const char * name; 260 const char * symbol_name_m32; // mangled name for the 32 bit architectures 261 const char * symbol_name_m64; // mangled name for the 64 bit archs 262 uint32_t version; 263 ModuleKind kind; 264 CaptureStateFn grabber; 265 }; 266 267 struct RuntimeHook 268 { 269 lldb::addr_t address; 270 const HookDefn *defn; 271 lldb::BreakpointSP bp_sp; 272 }; 273 274 typedef std::shared_ptr<RuntimeHook> RuntimeHookSP; 275 276 lldb::ModuleSP m_libRS; 277 lldb::ModuleSP m_libRSDriver; 278 lldb::ModuleSP m_libRSCpuRef; 279 std::vector<lldb_renderscript::RSModuleDescriptorSP> m_rsmodules; 280 281 std::vector<std::unique_ptr<ScriptDetails>> m_scripts; 282 std::vector<std::unique_ptr<AllocationDetails>> m_allocations; 283 284 std::map<lldb::addr_t, lldb_renderscript::RSModuleDescriptorSP> m_scriptMappings; 285 std::map<lldb::addr_t, RuntimeHookSP> m_runtimeHooks; 286 std::map<lldb::user_id_t, std::shared_ptr<int>> m_conditional_breaks; 287 288 lldb::SearchFilterSP m_filtersp; // Needed to create breakpoints through Target API 289 290 bool m_initiated; 291 bool m_debuggerPresentFlagged; 292 bool m_breakAllKernels; 293 static const HookDefn s_runtimeHookDefns[]; 294 static const size_t s_runtimeHookCount; 295 296 private: 297 RenderScriptRuntime(Process *process); // Call CreateInstance instead. 298 299 static bool HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, 300 lldb::user_id_t break_loc_id); 301 302 static bool KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx, 303 lldb::user_id_t break_id, lldb::user_id_t break_loc_id); 304 305 void HookCallback(RuntimeHook* hook_info, ExecutionContext& context); 306 307 bool GetArgSimple(ExecutionContext& context, uint32_t arg, uint64_t* data); 308 309 void CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context); 310 void CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context); 311 void CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context); 312 313 AllocationDetails* FindAllocByID(Stream &strm, const uint32_t alloc_id); 314 std::shared_ptr<uint8_t> GetAllocationData(AllocationDetails* allocation, StackFrame* frame_ptr); 315 unsigned int GetElementSize(const AllocationDetails* allocation); 316 static bool GetFrameVarAsUnsigned(const lldb::StackFrameSP, const char* var_name, uint64_t& val); 317 318 // 319 // Helper functions for jitting the runtime 320 // 321 bool JITDataPointer(AllocationDetails* allocation, StackFrame* frame_ptr, 322 unsigned int x = 0, unsigned int y = 0, unsigned int z = 0); 323 324 bool JITTypePointer(AllocationDetails* allocation, StackFrame* frame_ptr); 325 326 bool JITTypePacked(AllocationDetails* allocation, StackFrame* frame_ptr); 327 328 bool JITElementPacked(AllocationDetails* allocation, StackFrame* frame_ptr); 329 330 bool JITAllocationSize(AllocationDetails* allocation, StackFrame* frame_ptr, const uint32_t elem_size); 331 332 bool JITAllocationStride(AllocationDetails* allocation, StackFrame* frame_ptr); 333 334 // Search for a script detail object using a target address. 335 // If a script does not currently exist this function will return nullptr. 336 // If 'create' is true and there is no previous script with this address, 337 // then a new Script detail object will be created for this address and returned. 338 ScriptDetails* LookUpScript(lldb::addr_t address, bool create); 339 340 // Search for a previously saved allocation detail object using a target address. 341 // If an allocation does not exist for this address then nullptr will be returned. 342 // If 'create' is true and there is no previous allocation then a new allocation 343 // detail object will be created for this address and returned. 344 AllocationDetails* LookUpAllocation(lldb::addr_t address, bool create); 345 }; 346 347 } // namespace lldb_private 348 349 #endif // liblldb_RenderScriptRuntime_h_ 350