blob: b8342e0fd0779c42b90daafaa9178961447c3259 [file] [log] [blame]
Colin Riley5ec532a2015-04-09 16:49:25 +00001//===-- 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
22namespace lldb_private
23{
24
Ewan Crawford98156582015-09-04 08:56:52 +000025namespace lldb_renderscript
26{
27
Colin Riley5ec532a2015-04-09 16:49:25 +000028typedef uint32_t RSSlot;
29class RSModuleDescriptor;
Colin Riley4640cde2015-06-01 18:23:41 +000030struct RSGlobalDescriptor;
31struct RSKernelDescriptor;
32
33typedef std::shared_ptr<RSModuleDescriptor> RSModuleDescriptorSP;
34typedef std::shared_ptr<RSGlobalDescriptor> RSGlobalDescriptorSP;
35typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP;
36
Ewan Crawford98156582015-09-04 08:56:52 +000037// Breakpoint Resolvers decide where a breakpoint is placed,
38// so having our own allows us to limit the search scope to RS kernel modules.
39// As well as check for .expand kernels as a fallback.
40class RSBreakpointResolver : public BreakpointResolver
41{
42 public:
Colin Riley4640cde2015-06-01 18:23:41 +000043
Ewan Crawford98156582015-09-04 08:56:52 +000044 RSBreakpointResolver(Breakpoint *bkpt, ConstString name):
45 BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
46 m_kernel_name(name)
47 {
48 }
49
50 void
51 GetDescription(Stream *strm) override
52 {
53 if (strm)
54 strm->Printf("RenderScript kernel breakpoint for '%s'", m_kernel_name.AsCString());
55 }
56
57 void
58 Dump(Stream *s) const override
59 {
60 }
61
62 Searcher::CallbackReturn
63 SearchCallback(SearchFilter &filter,
64 SymbolContext &context,
65 Address *addr,
66 bool containing) override;
67
68 Searcher::Depth
69 GetDepth() override
70 {
71 return Searcher::eDepthModule;
72 }
73
74 lldb::BreakpointResolverSP
75 CopyForBreakpoint(Breakpoint &breakpoint) override
76 {
77 lldb::BreakpointResolverSP ret_sp(new RSBreakpointResolver(&breakpoint, m_kernel_name));
78 return ret_sp;
79 }
80
81 protected:
82 ConstString m_kernel_name;
83};
Colin Riley5ec532a2015-04-09 16:49:25 +000084
85struct RSKernelDescriptor
86{
87 public:
Colin Riley4640cde2015-06-01 18:23:41 +000088 RSKernelDescriptor(const RSModuleDescriptor *module, const char *name, uint32_t slot)
Colin Riley5ec532a2015-04-09 16:49:25 +000089 : m_module(module)
90 , m_name(name)
91 , m_slot(slot)
92 {
93 }
94
95 void Dump(Stream &strm) const;
96
Colin Riley4640cde2015-06-01 18:23:41 +000097 const RSModuleDescriptor *m_module;
Colin Riley5ec532a2015-04-09 16:49:25 +000098 ConstString m_name;
99 RSSlot m_slot;
100};
101
102struct RSGlobalDescriptor
103{
104 public:
Colin Riley4640cde2015-06-01 18:23:41 +0000105 RSGlobalDescriptor(const RSModuleDescriptor *module, const char *name )
Colin Riley5ec532a2015-04-09 16:49:25 +0000106 : m_module(module)
107 , m_name(name)
108 {
109 }
110
111 void Dump(Stream &strm) const;
112
Colin Riley4640cde2015-06-01 18:23:41 +0000113 const RSModuleDescriptor *m_module;
Colin Riley5ec532a2015-04-09 16:49:25 +0000114 ConstString m_name;
Colin Riley5ec532a2015-04-09 16:49:25 +0000115};
116
117class RSModuleDescriptor
118{
119 public:
120 RSModuleDescriptor(const lldb::ModuleSP &module)
121 : m_module(module)
122 {
123 }
124
125 ~RSModuleDescriptor() {}
126
127 bool ParseRSInfo();
128
129 void Dump(Stream &strm) const;
130
131 const lldb::ModuleSP m_module;
132 std::vector<RSKernelDescriptor> m_kernels;
133 std::vector<RSGlobalDescriptor> m_globals;
Colin Riley4640cde2015-06-01 18:23:41 +0000134 std::map<std::string, std::string> m_pragmas;
135 std::string m_resname;
Colin Riley5ec532a2015-04-09 16:49:25 +0000136};
137
Ewan Crawford98156582015-09-04 08:56:52 +0000138} // end lldb_renderscript namespace
139
Colin Riley5ec532a2015-04-09 16:49:25 +0000140class RenderScriptRuntime : public lldb_private::CPPLanguageRuntime
141{
142 public:
Colin Rileyef20b082015-04-14 07:39:24 +0000143
144 enum ModuleKind
145 {
146 eModuleKindIgnored,
147 eModuleKindLibRS,
148 eModuleKindDriver,
149 eModuleKindImpl,
150 eModuleKindKernelObj
151 };
152
Ewan Crawford78f339d2015-09-21 10:53:18 +0000153 ~RenderScriptRuntime();
Colin Riley5ec532a2015-04-09 16:49:25 +0000154
155 //------------------------------------------------------------------
156 // Static Functions
157 //------------------------------------------------------------------
158 static void Initialize();
159
160 static void Terminate();
161
162 static lldb_private::LanguageRuntime *CreateInstance(Process *process, lldb::LanguageType language);
163
Colin Riley4640cde2015-06-01 18:23:41 +0000164 static lldb::CommandObjectSP GetCommandObject(CommandInterpreter& interpreter);
165
Colin Riley5ec532a2015-04-09 16:49:25 +0000166 static lldb_private::ConstString GetPluginNameStatic();
167
Colin Rileyef20b082015-04-14 07:39:24 +0000168 static bool IsRenderScriptModule(const lldb::ModuleSP &module_sp);
169
170 static ModuleKind GetModuleKind(const lldb::ModuleSP &module_sp);
171
172 static void ModulesDidLoad(const lldb::ProcessSP& process_sp, const ModuleList &module_list );
173
Colin Riley5ec532a2015-04-09 16:49:25 +0000174 //------------------------------------------------------------------
175 // PluginInterface protocol
176 //------------------------------------------------------------------
177 virtual lldb_private::ConstString GetPluginName();
178
179 virtual uint32_t GetPluginVersion();
180
181 virtual bool IsVTableName(const char *name);
182
183 virtual bool GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
Enrico Granata0b6003f2015-09-17 22:56:38 +0000184 TypeAndOrName &class_type_or_name, Address &address,
185 Value::ValueType &value_type);
Enrico Granatac74275b2015-09-22 19:45:52 +0000186
187 virtual TypeAndOrName
Enrico Granata7eed4872015-09-22 19:58:02 +0000188 FixUpDynamicType (const TypeAndOrName& type_and_or_name,
189 ValueObject& static_value);
Colin Riley5ec532a2015-04-09 16:49:25 +0000190
191 virtual bool CouldHaveDynamicValue(ValueObject &in_value);
192
193 virtual lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp);
194
195 bool LoadModule(const lldb::ModuleSP &module_sp);
196
197 bool ProbeModules(const ModuleList module_list);
198
199 void DumpModules(Stream &strm) const;
200
Colin Riley4640cde2015-06-01 18:23:41 +0000201 void DumpContexts(Stream &strm) const;
202
203 void DumpKernels(Stream &strm) const;
204
Ewan Crawforda0f08672015-10-16 08:28:47 +0000205 bool DumpAllocation(Stream &strm, StackFrame* frame_ptr, const uint32_t id);
206
Ewan Crawford15f2bd92015-10-06 08:42:32 +0000207 void ListAllocations(Stream &strm, StackFrame* frame_ptr, bool recompute);
208
Ewan Crawford98156582015-09-04 08:56:52 +0000209 void AttemptBreakpointAtKernelName(Stream &strm, const char *name, Error &error, lldb::TargetSP target);
Colin Riley4640cde2015-06-01 18:23:41 +0000210
Ewan Crawford7dc77712015-09-10 10:08:48 +0000211 void SetBreakAllKernels(bool do_break, lldb::TargetSP target);
212
Colin Riley4640cde2015-06-01 18:23:41 +0000213 void Status(Stream &strm) const;
214
Siva Chandra92935952015-04-09 19:13:54 +0000215 virtual size_t GetAlternateManglings(const ConstString &mangled, std::vector<ConstString> &alternates) {
216 return static_cast<size_t>(0);
217 }
218
Colin Rileyef20b082015-04-14 07:39:24 +0000219 virtual void ModulesDidLoad(const ModuleList &module_list );
220
Ewan Crawford55232f02015-10-21 08:50:42 +0000221 bool LoadAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr);
222
223 bool SaveAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr);
224
Colin Rileyef20b082015-04-14 07:39:24 +0000225 void Update();
226
227 void Initiate();
Colin Riley4640cde2015-06-01 18:23:41 +0000228
Colin Riley5ec532a2015-04-09 16:49:25 +0000229 protected:
Ewan Crawford7dc77712015-09-10 10:08:48 +0000230
Ewan Crawford15f2bd92015-10-06 08:42:32 +0000231 struct ScriptDetails;
232 struct AllocationDetails;
233
Ewan Crawford7dc77712015-09-10 10:08:48 +0000234 void InitSearchFilter(lldb::TargetSP target)
235 {
236 if (!m_filtersp)
237 m_filtersp.reset(new SearchFilterForUnconstrainedSearches(target));
238 }
Colin Riley4640cde2015-06-01 18:23:41 +0000239
Ewan Crawford98156582015-09-04 08:56:52 +0000240 void FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
Colin Riley4640cde2015-06-01 18:23:41 +0000241
242 void LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind);
Ewan Crawford7dc77712015-09-10 10:08:48 +0000243
Ewan Crawford15f2bd92015-10-06 08:42:32 +0000244 bool RefreshAllocation(AllocationDetails* allocation, StackFrame* frame_ptr);
245
246 bool EvalRSExpression(const char* expression, StackFrame* frame_ptr, uint64_t* result);
247
Ewan Crawford7dc77712015-09-10 10:08:48 +0000248 lldb::BreakpointSP CreateKernelBreakpoint(const ConstString& name);
249
250 void BreakOnModuleKernels(const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp);
Colin Riley4640cde2015-06-01 18:23:41 +0000251
252 struct RuntimeHook;
253 typedef void (RenderScriptRuntime::*CaptureStateFn)(RuntimeHook* hook_info, ExecutionContext &context); // Please do this!
254
255 struct HookDefn
256 {
257 const char * name;
Aidan Dodds82780282015-09-18 16:49:39 +0000258 const char * symbol_name_m32; // mangled name for the 32 bit architectures
259 const char * symbol_name_m64; // mangled name for the 64 bit archs
Colin Riley4640cde2015-06-01 18:23:41 +0000260 uint32_t version;
261 ModuleKind kind;
262 CaptureStateFn grabber;
263 };
264
265 struct RuntimeHook
266 {
267 lldb::addr_t address;
268 const HookDefn *defn;
269 lldb::BreakpointSP bp_sp;
270 };
Ewan Crawford55232f02015-10-21 08:50:42 +0000271
Colin Riley4640cde2015-06-01 18:23:41 +0000272 typedef std::shared_ptr<RuntimeHook> RuntimeHookSP;
273
Colin Riley4640cde2015-06-01 18:23:41 +0000274 lldb::ModuleSP m_libRS;
275 lldb::ModuleSP m_libRSDriver;
276 lldb::ModuleSP m_libRSCpuRef;
Ewan Crawford98156582015-09-04 08:56:52 +0000277 std::vector<lldb_renderscript::RSModuleDescriptorSP> m_rsmodules;
Ewan Crawford78f339d2015-09-21 10:53:18 +0000278
279 std::vector<std::unique_ptr<ScriptDetails>> m_scripts;
280 std::vector<std::unique_ptr<AllocationDetails>> m_allocations;
Colin Riley4640cde2015-06-01 18:23:41 +0000281
Ewan Crawford98156582015-09-04 08:56:52 +0000282 std::map<lldb::addr_t, lldb_renderscript::RSModuleDescriptorSP> m_scriptMappings;
Colin Riley4640cde2015-06-01 18:23:41 +0000283 std::map<lldb::addr_t, RuntimeHookSP> m_runtimeHooks;
284
Ewan Crawford7dc77712015-09-10 10:08:48 +0000285 lldb::SearchFilterSP m_filtersp; // Needed to create breakpoints through Target API
286
Colin Rileyef20b082015-04-14 07:39:24 +0000287 bool m_initiated;
Colin Riley4640cde2015-06-01 18:23:41 +0000288 bool m_debuggerPresentFlagged;
Ewan Crawford7dc77712015-09-10 10:08:48 +0000289 bool m_breakAllKernels;
Colin Riley4640cde2015-06-01 18:23:41 +0000290 static const HookDefn s_runtimeHookDefns[];
291 static const size_t s_runtimeHookCount;
292
Colin Riley5ec532a2015-04-09 16:49:25 +0000293 private:
294 RenderScriptRuntime(Process *process); // Call CreateInstance instead.
Colin Riley4640cde2015-06-01 18:23:41 +0000295
296 static bool HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id,
297 lldb::user_id_t break_loc_id);
298
299 void HookCallback(RuntimeHook* hook_info, ExecutionContext& context);
300
Aidan Dodds82780282015-09-18 16:49:39 +0000301 bool GetArgSimple(ExecutionContext& context, uint32_t arg, uint64_t* data);
Colin Riley4640cde2015-06-01 18:23:41 +0000302
303 void CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context);
304 void CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context);
305 void CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context);
306
Ewan Crawforda0f08672015-10-16 08:28:47 +0000307 AllocationDetails* FindAllocByID(Stream &strm, const uint32_t alloc_id);
Ewan Crawford55232f02015-10-21 08:50:42 +0000308 std::shared_ptr<uint8_t> GetAllocationData(AllocationDetails* allocation, StackFrame* frame_ptr);
309 unsigned int GetElementSize(const AllocationDetails* allocation);
Ewan Crawforda0f08672015-10-16 08:28:47 +0000310
Ewan Crawford15f2bd92015-10-06 08:42:32 +0000311 //
312 // Helper functions for jitting the runtime
313 //
314 bool JITDataPointer(AllocationDetails* allocation, StackFrame* frame_ptr,
315 unsigned int x = 0, unsigned int y = 0, unsigned int z = 0);
316
317 bool JITTypePointer(AllocationDetails* allocation, StackFrame* frame_ptr);
318
319 bool JITTypePacked(AllocationDetails* allocation, StackFrame* frame_ptr);
320
321 bool JITElementPacked(AllocationDetails* allocation, StackFrame* frame_ptr);
322
Ewan Crawforda0f08672015-10-16 08:28:47 +0000323 bool JITAllocationSize(AllocationDetails* allocation, StackFrame* frame_ptr, const uint32_t elem_size);
324
325 bool JITAllocationStride(AllocationDetails* allocation, StackFrame* frame_ptr);
326
Ewan Crawford78f339d2015-09-21 10:53:18 +0000327 // Search for a script detail object using a target address.
328 // If a script does not currently exist this function will return nullptr.
329 // If 'create' is true and there is no previous script with this address,
330 // then a new Script detail object will be created for this address and returned.
331 ScriptDetails* LookUpScript(lldb::addr_t address, bool create);
332
333 // Search for a previously saved allocation detail object using a target address.
334 // If an allocation does not exist for this address then nullptr will be returned.
335 // If 'create' is true and there is no previous allocation then a new allocation
336 // detail object will be created for this address and returned.
337 AllocationDetails* LookUpAllocation(lldb::addr_t address, bool create);
Colin Riley5ec532a2015-04-09 16:49:25 +0000338};
339
340} // namespace lldb_private
341
342#endif // liblldb_RenderScriptRuntime_h_