blob: 558cf7e4dd3a1b02b7b274e5d03c6266729e7770 [file] [log] [blame]
Colin Riley5ec532a2015-04-09 16:49:25 +00001//===-- RenderScriptRuntime.cpp ---------------------------------*- 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#include "RenderScriptRuntime.h"
11
12#include "lldb/Core/ConstString.h"
13#include "lldb/Core/Debugger.h"
14#include "lldb/Core/Error.h"
15#include "lldb/Core/Log.h"
16#include "lldb/Core/PluginManager.h"
17#include "lldb/Symbol/Symbol.h"
Colin Riley4640cde2015-06-01 18:23:41 +000018#include "lldb/Symbol/Type.h"
Colin Riley5ec532a2015-04-09 16:49:25 +000019#include "lldb/Target/Process.h"
20#include "lldb/Target/Target.h"
21#include "lldb/Interpreter/Args.h"
22#include "lldb/Interpreter/Options.h"
23#include "lldb/Interpreter/CommandInterpreter.h"
24#include "lldb/Interpreter/CommandReturnObject.h"
25#include "lldb/Interpreter/CommandObjectMultiword.h"
Colin Riley4640cde2015-06-01 18:23:41 +000026#include "lldb/Breakpoint/StoppointCallbackContext.h"
27#include "lldb/Target/RegisterContext.h"
28
29#include "lldb/Symbol/VariableList.h"
Colin Riley5ec532a2015-04-09 16:49:25 +000030
31using namespace lldb;
32using namespace lldb_private;
Ewan Crawford98156582015-09-04 08:56:52 +000033using namespace lldb_renderscript;
Colin Riley5ec532a2015-04-09 16:49:25 +000034
35//------------------------------------------------------------------
36// Static Functions
37//------------------------------------------------------------------
38LanguageRuntime *
39RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType language)
40{
41
42 if (language == eLanguageTypeExtRenderScript)
43 return new RenderScriptRuntime(process);
44 else
45 return NULL;
46}
47
Ewan Crawford98156582015-09-04 08:56:52 +000048// Callback with a module to search for matching symbols.
49// We first check that the module contains RS kernels.
50// Then look for a symbol which matches our kernel name.
51// The breakpoint address is finally set using the address of this symbol.
52Searcher::CallbackReturn
53RSBreakpointResolver::SearchCallback(SearchFilter &filter,
54 SymbolContext &context,
55 Address*,
56 bool)
57{
58 ModuleSP module = context.module_sp;
59
60 if (!module)
61 return Searcher::eCallbackReturnContinue;
62
63 // Is this a module containing renderscript kernels?
64 if (nullptr == module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData))
65 return Searcher::eCallbackReturnContinue;
66
67 // Attempt to set a breakpoint on the kernel name symbol within the module library.
68 // If it's not found, it's likely debug info is unavailable - try to set a
69 // breakpoint on <name>.expand.
70
71 const Symbol* kernel_sym = module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode);
72 if (!kernel_sym)
73 {
74 std::string kernel_name_expanded(m_kernel_name.AsCString());
75 kernel_name_expanded.append(".expand");
76 kernel_sym = module->FindFirstSymbolWithNameAndType(ConstString(kernel_name_expanded.c_str()), eSymbolTypeCode);
77 }
78
79 if (kernel_sym)
80 {
81 Address bp_addr = kernel_sym->GetAddress();
82 if (filter.AddressPasses(bp_addr))
83 m_breakpoint->AddLocation(bp_addr);
84 }
85
86 return Searcher::eCallbackReturnContinue;
87}
88
Colin Riley5ec532a2015-04-09 16:49:25 +000089void
90RenderScriptRuntime::Initialize()
91{
Colin Riley4640cde2015-06-01 18:23:41 +000092 PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance, GetCommandObject);
Colin Riley5ec532a2015-04-09 16:49:25 +000093}
94
95void
96RenderScriptRuntime::Terminate()
97{
98 PluginManager::UnregisterPlugin(CreateInstance);
99}
100
101lldb_private::ConstString
102RenderScriptRuntime::GetPluginNameStatic()
103{
104 static ConstString g_name("renderscript");
105 return g_name;
106}
107
Colin Rileyef20b082015-04-14 07:39:24 +0000108RenderScriptRuntime::ModuleKind
109RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp)
110{
111 if (module_sp)
112 {
113 // Is this a module containing renderscript kernels?
114 const Symbol *info_sym = module_sp->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
115 if (info_sym)
116 {
117 return eModuleKindKernelObj;
118 }
Colin Riley4640cde2015-06-01 18:23:41 +0000119
120 // Is this the main RS runtime library
121 const ConstString rs_lib("libRS.so");
122 if (module_sp->GetFileSpec().GetFilename() == rs_lib)
123 {
124 return eModuleKindLibRS;
125 }
126
127 const ConstString rs_driverlib("libRSDriver.so");
128 if (module_sp->GetFileSpec().GetFilename() == rs_driverlib)
129 {
130 return eModuleKindDriver;
131 }
132
133 const ConstString rs_cpureflib("libRSCPURef.so");
134 if (module_sp->GetFileSpec().GetFilename() == rs_cpureflib)
135 {
136 return eModuleKindImpl;
137 }
138
Colin Rileyef20b082015-04-14 07:39:24 +0000139 }
140 return eModuleKindIgnored;
141}
142
143bool
144RenderScriptRuntime::IsRenderScriptModule(const lldb::ModuleSP &module_sp)
145{
146 return GetModuleKind(module_sp) != eModuleKindIgnored;
147}
148
149
150void
151RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list )
152{
153 Mutex::Locker locker (module_list.GetMutex ());
154
155 size_t num_modules = module_list.GetSize();
156 for (size_t i = 0; i < num_modules; i++)
157 {
158 auto mod = module_list.GetModuleAtIndex (i);
159 if (IsRenderScriptModule (mod))
160 {
161 LoadModule(mod);
162 }
163 }
164}
165
166
Colin Riley5ec532a2015-04-09 16:49:25 +0000167//------------------------------------------------------------------
168// PluginInterface protocol
169//------------------------------------------------------------------
170lldb_private::ConstString
171RenderScriptRuntime::GetPluginName()
172{
173 return GetPluginNameStatic();
174}
175
176uint32_t
177RenderScriptRuntime::GetPluginVersion()
178{
179 return 1;
180}
181
182bool
183RenderScriptRuntime::IsVTableName(const char *name)
184{
185 return false;
186}
187
188bool
189RenderScriptRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic,
Enrico Granata0b6003f2015-09-17 22:56:38 +0000190 TypeAndOrName &class_type_or_name, Address &address,
191 Value::ValueType &value_type)
Colin Riley5ec532a2015-04-09 16:49:25 +0000192{
193 return false;
194}
195
196bool
197RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value)
198{
199 return false;
200}
201
202lldb::BreakpointResolverSP
203RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp)
204{
205 BreakpointResolverSP resolver_sp;
206 return resolver_sp;
207}
208
Colin Riley4640cde2015-06-01 18:23:41 +0000209
210const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] =
211{
212 //rsdScript
Aidan Dodds82780282015-09-18 16:49:39 +0000213 {
214 "rsdScriptInit", //name
215 "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhjj", // symbol name 32 bit
216 "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhmj", // symbol name 64 bit
217 0, // version
218 RenderScriptRuntime::eModuleKindDriver, // type
219 &lldb_private::RenderScriptRuntime::CaptureScriptInit1 // handler
220 },
221 {
222 "rsdScriptInvokeForEach", // name
223 "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvjPK12RsScriptCall", // symbol name 32bit
224 "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvmPK12RsScriptCall", // symbol name 64bit
225 0, // version
226 RenderScriptRuntime::eModuleKindDriver, // type
227 nullptr // handler
228 },
229 {
230 "rsdScriptInvokeForEachMulti", // name
231 "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall", // symbol name 32bit
232 "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEmPS6_PKvmPK12RsScriptCall", // symbol name 64bit
233 0, // version
234 RenderScriptRuntime::eModuleKindDriver, // type
235 nullptr // handler
236 },
237 {
238 "rsdScriptInvokeFunction", // name
239 "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvj", // symbol name 32bit
240 "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvm", // symbol name 64bit
241 0, // version
242 RenderScriptRuntime::eModuleKindDriver, // type
243 nullptr // handler
244 },
245 {
246 "rsdScriptSetGlobalVar", // name
247 "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvj", // symbol name 32bit
248 "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvm", // symbol name 64bit
249 0, // version
250 RenderScriptRuntime::eModuleKindDriver, // type
251 &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar1 // handler
252 },
Colin Riley4640cde2015-06-01 18:23:41 +0000253
254 //rsdAllocation
Aidan Dodds82780282015-09-18 16:49:39 +0000255 {
256 "rsdAllocationInit", // name
257 "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 32bit
258 "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 64bit
259 0, // version
260 RenderScriptRuntime::eModuleKindDriver, // type
261 &lldb_private::RenderScriptRuntime::CaptureAllocationInit1 // handler
262 },
263 {
264 "rsdAllocationRead2D", //name
265 "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvjj", // symbol name 32bit
266 "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvmm", // symbol name 64bit
267 0, // version
268 RenderScriptRuntime::eModuleKindDriver, // type
269 nullptr // handler
270 },
Colin Riley4640cde2015-06-01 18:23:41 +0000271};
272const size_t RenderScriptRuntime::s_runtimeHookCount = sizeof(s_runtimeHookDefns)/sizeof(s_runtimeHookDefns[0]);
273
274
275bool
276RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
277{
278 RuntimeHook* hook_info = (RuntimeHook*)baton;
279 ExecutionContext context(ctx->exe_ctx_ref);
280
281 RenderScriptRuntime *lang_rt = (RenderScriptRuntime *)context.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
282
283 lang_rt->HookCallback(hook_info, context);
284
285 return false;
286}
287
288
289void
290RenderScriptRuntime::HookCallback(RuntimeHook* hook_info, ExecutionContext& context)
291{
292 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
293
Aidan Dodds82780282015-09-18 16:49:39 +0000294 if (log)
Colin Riley4640cde2015-06-01 18:23:41 +0000295 log->Printf ("RenderScriptRuntime::HookCallback - '%s' .", hook_info->defn->name);
296
297 if (hook_info->defn->grabber)
298 {
299 (this->*(hook_info->defn->grabber))(hook_info, context);
300 }
301}
302
303
304bool
Aidan Dodds82780282015-09-18 16:49:39 +0000305RenderScriptRuntime::GetArgSimple(ExecutionContext &context, uint32_t arg, uint64_t *data)
Colin Riley4640cde2015-06-01 18:23:41 +0000306{
Colin Riley4640cde2015-06-01 18:23:41 +0000307 if (!data)
308 return false;
309
Aidan Dodds82780282015-09-18 16:49:39 +0000310 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
Colin Riley4640cde2015-06-01 18:23:41 +0000311 Error error;
312 RegisterContext* reg_ctx = context.GetRegisterContext();
313 Process* process = context.GetProcessPtr();
Aidan Dodds82780282015-09-18 16:49:39 +0000314 bool success = false; // return value
Colin Riley4640cde2015-06-01 18:23:41 +0000315
Aidan Dodds82780282015-09-18 16:49:39 +0000316 if (!context.GetTargetPtr())
Colin Riley4640cde2015-06-01 18:23:41 +0000317 {
Aidan Dodds82780282015-09-18 16:49:39 +0000318 if (log)
319 log->Printf("RenderScriptRuntime::GetArgSimple - Invalid target");
320
321 return false;
Colin Riley4640cde2015-06-01 18:23:41 +0000322 }
Aidan Dodds82780282015-09-18 16:49:39 +0000323
324 switch (context.GetTargetPtr()->GetArchitecture().GetMachine())
Colin Riley4640cde2015-06-01 18:23:41 +0000325 {
Aidan Dodds82780282015-09-18 16:49:39 +0000326 case llvm::Triple::ArchType::x86:
Colin Riley4640cde2015-06-01 18:23:41 +0000327 {
328 uint64_t sp = reg_ctx->GetSP();
Aidan Dodds82780282015-09-18 16:49:39 +0000329 uint32_t offset = (1 + arg) * sizeof(uint32_t);
330 uint32_t result = 0;
331 process->ReadMemory(sp + offset, &result, sizeof(uint32_t), error);
332 if (error.Fail())
Colin Riley4640cde2015-06-01 18:23:41 +0000333 {
Aidan Dodds82780282015-09-18 16:49:39 +0000334 if (log)
335 log->Printf ("RenderScriptRuntime:: GetArgSimple - error reading X86 stack: %s.", error.AsCString());
336 }
337 else
338 {
339 *data = result;
340 success = true;
341 }
342
343 break;
344 }
345 case llvm::Triple::ArchType::arm:
346 {
347 // arm 32 bit
348 if (arg < 4)
349 {
350 const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg);
351 RegisterValue rVal;
352 reg_ctx->ReadRegister(rArg, rVal);
353 (*data) = rVal.GetAsUInt32();
354 success = true;
355 }
356 else
357 {
358 uint64_t sp = reg_ctx->GetSP();
Colin Riley4640cde2015-06-01 18:23:41 +0000359 {
Aidan Dodds82780282015-09-18 16:49:39 +0000360 uint32_t offset = (arg-4) * sizeof(uint32_t);
361 process->ReadMemory(sp + offset, &data, sizeof(uint32_t), error);
362 if (error.Fail())
363 {
364 if (log)
365 log->Printf ("RenderScriptRuntime:: GetArgSimple - error reading ARM stack: %s.", error.AsCString());
366 }
367 else
368 {
369 success = true;
370 }
Colin Riley4640cde2015-06-01 18:23:41 +0000371 }
372 }
Aidan Dodds82780282015-09-18 16:49:39 +0000373
374 break;
375 }
376 case llvm::Triple::ArchType::aarch64:
377 {
378 // arm 64 bit
379 // first 8 arguments are in the registers
380 if (arg < 8)
381 {
382 const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg);
383 RegisterValue rVal;
384 success = reg_ctx->ReadRegister(rArg, rVal);
385 if (success)
386 {
387 *data = rVal.GetAsUInt64();
388 }
389 else
390 {
391 if (log)
392 log->Printf("RenderScriptRuntime::GetArgSimple() - AARCH64 - Error while reading the argument #%d", arg);
393 }
394 }
395 else
396 {
397 // @TODO: need to find the argument in the stack
398 if (log)
399 log->Printf("RenderScriptRuntime::GetArgSimple - AARCH64 - FOR #ARG >= 8 NOT IMPLEMENTED YET. Argument number: %d", arg);
400 }
401 break;
402 }
403 default:
404 {
405 // invalid architecture
406 if (log)
407 log->Printf("RenderScriptRuntime::GetArgSimple - Architecture not supported");
408
409 }
Colin Riley4640cde2015-06-01 18:23:41 +0000410 }
Aidan Dodds82780282015-09-18 16:49:39 +0000411
412
413 return success;
Colin Riley4640cde2015-06-01 18:23:41 +0000414}
415
416void
417RenderScriptRuntime::CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context)
418{
419 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
420
421 //Context, Script, int, data, length
422
Aidan Dodds82780282015-09-18 16:49:39 +0000423 uint64_t rs_context_u64 = 0U;
424 uint64_t rs_script_u64 = 0U;
425 uint64_t rs_id_u64 = 0U;
426 uint64_t rs_data_u64 = 0U;
427 uint64_t rs_length_u64 = 0U;
Colin Riley4640cde2015-06-01 18:23:41 +0000428
Aidan Dodds82780282015-09-18 16:49:39 +0000429 bool success =
430 GetArgSimple(context, 0, &rs_context_u64) &&
431 GetArgSimple(context, 1, &rs_script_u64) &&
432 GetArgSimple(context, 2, &rs_id_u64) &&
433 GetArgSimple(context, 3, &rs_data_u64) &&
434 GetArgSimple(context, 4, &rs_length_u64);
Colin Riley4640cde2015-06-01 18:23:41 +0000435
Aidan Dodds82780282015-09-18 16:49:39 +0000436 if (!success)
437 {
438 if (log)
439 log->Printf("RenderScriptRuntime::CaptureSetGlobalVar1 - Error while reading the function parameters");
440 return;
441 }
Colin Riley4640cde2015-06-01 18:23:41 +0000442
Aidan Dodds82780282015-09-18 16:49:39 +0000443 if (log)
Colin Riley4640cde2015-06-01 18:23:41 +0000444 {
445 log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 ":%" PRIu64 "bytes.",
Aidan Dodds82780282015-09-18 16:49:39 +0000446 rs_context_u64, rs_script_u64, rs_id_u64, rs_data_u64, rs_length_u64);
Colin Riley4640cde2015-06-01 18:23:41 +0000447
Aidan Dodds82780282015-09-18 16:49:39 +0000448 addr_t script_addr = (addr_t)rs_script_u64;
Colin Riley4640cde2015-06-01 18:23:41 +0000449 if (m_scriptMappings.find( script_addr ) != m_scriptMappings.end())
450 {
451 auto rsm = m_scriptMappings[script_addr];
Aidan Dodds82780282015-09-18 16:49:39 +0000452 if (rs_id_u64 < rsm->m_globals.size())
Colin Riley4640cde2015-06-01 18:23:41 +0000453 {
Aidan Dodds82780282015-09-18 16:49:39 +0000454 auto rsg = rsm->m_globals[rs_id_u64];
Colin Riley4640cde2015-06-01 18:23:41 +0000455 log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - Setting of '%s' within '%s' inferred", rsg.m_name.AsCString(),
456 rsm->m_module->GetFileSpec().GetFilename().AsCString());
457 }
458 }
459 }
460}
461
462void
463RenderScriptRuntime::CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context)
464{
465 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
466
467 //Context, Alloc, bool
468
Aidan Dodds82780282015-09-18 16:49:39 +0000469 uint64_t rs_context_u64 = 0U;
470 uint64_t rs_alloc_u64 = 0U;
471 uint64_t rs_forceZero_u64 = 0U;
Colin Riley4640cde2015-06-01 18:23:41 +0000472
Aidan Dodds82780282015-09-18 16:49:39 +0000473 bool success =
474 GetArgSimple(context, 0, &rs_context_u64) &&
475 GetArgSimple(context, 1, &rs_alloc_u64) &&
476 GetArgSimple(context, 2, &rs_forceZero_u64);
477 if (!success) // error case
478 {
479 if (log)
480 log->Printf("RenderScriptRuntime::CaptureAllocationInit1 - Error while reading the function parameters");
481 return; // abort
482 }
483
484 if (log)
Colin Riley4640cde2015-06-01 18:23:41 +0000485 log->Printf ("RenderScriptRuntime::CaptureAllocationInit1 - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .",
Aidan Dodds82780282015-09-18 16:49:39 +0000486 rs_context_u64, rs_alloc_u64, rs_forceZero_u64);
Colin Riley4640cde2015-06-01 18:23:41 +0000487}
488
489void
490RenderScriptRuntime::CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context)
491{
492 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
493
494 //Context, Script, resname Str, cachedir Str
495 Error error;
496 Process* process = context.GetProcessPtr();
497
Aidan Dodds82780282015-09-18 16:49:39 +0000498 uint64_t rs_context_u64 = 0U;
499 uint64_t rs_script_u64 = 0U;
500 uint64_t rs_resnameptr_u64 = 0U;
501 uint64_t rs_cachedirptr_u64 = 0U;
Colin Riley4640cde2015-06-01 18:23:41 +0000502
503 std::string resname;
504 std::string cachedir;
505
Aidan Dodds82780282015-09-18 16:49:39 +0000506 // read the function parameters
507 bool success =
508 GetArgSimple(context, 0, &rs_context_u64) &&
509 GetArgSimple(context, 1, &rs_script_u64) &&
510 GetArgSimple(context, 2, &rs_resnameptr_u64) &&
511 GetArgSimple(context, 3, &rs_cachedirptr_u64);
Colin Riley4640cde2015-06-01 18:23:41 +0000512
Aidan Dodds82780282015-09-18 16:49:39 +0000513 if (!success)
514 {
515 if (log)
516 log->Printf("RenderScriptRuntime::CaptureScriptInit1 - Error while reading the function parameters");
517 return;
518 }
519
520 process->ReadCStringFromMemory((lldb::addr_t)rs_resnameptr_u64, resname, error);
Colin Riley4640cde2015-06-01 18:23:41 +0000521 if (error.Fail())
522 {
Aidan Dodds82780282015-09-18 16:49:39 +0000523 if (log)
Colin Riley4640cde2015-06-01 18:23:41 +0000524 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading resname: %s.", error.AsCString());
525
526 }
527
Aidan Dodds82780282015-09-18 16:49:39 +0000528 process->ReadCStringFromMemory((lldb::addr_t)rs_cachedirptr_u64, cachedir, error);
Colin Riley4640cde2015-06-01 18:23:41 +0000529 if (error.Fail())
530 {
Aidan Dodds82780282015-09-18 16:49:39 +0000531 if (log)
Colin Riley4640cde2015-06-01 18:23:41 +0000532 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading cachedir: %s.", error.AsCString());
533 }
534
535 if (log)
536 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .",
Aidan Dodds82780282015-09-18 16:49:39 +0000537 rs_context_u64, rs_script_u64, resname.c_str(), cachedir.c_str());
Colin Riley4640cde2015-06-01 18:23:41 +0000538
539 if (resname.size() > 0)
540 {
541 StreamString strm;
542 strm.Printf("librs.%s.so", resname.c_str());
543
544 ScriptDetails script;
545 script.cachedir = cachedir;
546 script.resname = resname;
547 script.scriptDyLib.assign(strm.GetData());
Aidan Dodds82780282015-09-18 16:49:39 +0000548 script.script = (addr_t) rs_script_u64;
549 script.context = (addr_t) rs_context_u64;
Colin Riley4640cde2015-06-01 18:23:41 +0000550
551 m_scripts.push_back(script);
552
553 if (log)
554 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - '%s' tagged with context 0x%" PRIx64 " and script 0x%" PRIx64 ".",
Aidan Dodds82780282015-09-18 16:49:39 +0000555 strm.GetData(), rs_context_u64, rs_script_u64);
Colin Riley4640cde2015-06-01 18:23:41 +0000556 }
557 else if (log)
558 {
559 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - resource name invalid, Script not tagged");
560 }
561
562}
563
564
565void
566RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
567{
568 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
569
570 if (!module)
571 {
572 return;
573 }
574
Aidan Dodds82780282015-09-18 16:49:39 +0000575 Target &target = GetProcess()->GetTarget();
576 llvm::Triple::ArchType targetArchType = target.GetArchitecture().GetMachine();
577
578 if (targetArchType != llvm::Triple::ArchType::x86
579 && targetArchType != llvm::Triple::ArchType::arm
580 && targetArchType != llvm::Triple::ArchType::aarch64)
Colin Riley4640cde2015-06-01 18:23:41 +0000581 {
582 if (log)
583 log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to hook runtime. Only X86, ARM supported currently.");
584
585 return;
586 }
587
Aidan Dodds82780282015-09-18 16:49:39 +0000588 uint32_t archByteSize = target.GetArchitecture().GetAddressByteSize();
Colin Riley4640cde2015-06-01 18:23:41 +0000589
590 for (size_t idx = 0; idx < s_runtimeHookCount; idx++)
591 {
592 const HookDefn* hook_defn = &s_runtimeHookDefns[idx];
593 if (hook_defn->kind != kind) {
594 continue;
595 }
596
Aidan Dodds82780282015-09-18 16:49:39 +0000597 const char* symbol_name = (archByteSize == 4) ? hook_defn->symbol_name_m32 : hook_defn->symbol_name_m64;
598
599 const Symbol *sym = module->FindFirstSymbolWithNameAndType(ConstString(symbol_name), eSymbolTypeCode);
600 if (!sym){
601 if (log){
602 log->Printf("RenderScriptRuntime::LoadRuntimeHooks - ERROR: Symbol '%s' related to the function %s not found", symbol_name, hook_defn->name);
603 }
604 continue;
605 }
Colin Riley4640cde2015-06-01 18:23:41 +0000606
Greg Clayton358cf1e2015-06-25 21:46:34 +0000607 addr_t addr = sym->GetLoadAddress(&target);
Colin Riley4640cde2015-06-01 18:23:41 +0000608 if (addr == LLDB_INVALID_ADDRESS)
609 {
Aidan Dodds82780282015-09-18 16:49:39 +0000610 if (log)
Colin Riley4640cde2015-06-01 18:23:41 +0000611 log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to resolve the address of hook function '%s' with symbol '%s'.",
Aidan Dodds82780282015-09-18 16:49:39 +0000612 hook_defn->name, symbol_name);
Colin Riley4640cde2015-06-01 18:23:41 +0000613 continue;
614 }
Aidan Dodds82780282015-09-18 16:49:39 +0000615 else
616 {
617 if (log)
618 log->Printf("RenderScriptRuntime::LoadRuntimeHooks - Function %s, address resolved at 0x%" PRIx64, hook_defn->name, addr);
619 }
Colin Riley4640cde2015-06-01 18:23:41 +0000620
621 RuntimeHookSP hook(new RuntimeHook());
622 hook->address = addr;
623 hook->defn = hook_defn;
624 hook->bp_sp = target.CreateBreakpoint(addr, true, false);
625 hook->bp_sp->SetCallback(HookCallback, hook.get(), true);
626 m_runtimeHooks[addr] = hook;
627 if (log)
628 {
629 log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Successfully hooked '%s' in '%s' version %" PRIu64 " at 0x%" PRIx64 ".",
630 hook_defn->name, module->GetFileSpec().GetFilename().AsCString(), (uint64_t)hook_defn->version, (uint64_t)addr);
631 }
632 }
633}
634
635void
636RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp)
637{
638 if (!rsmodule_sp)
639 return;
640
641 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
642
643 const ModuleSP module = rsmodule_sp->m_module;
644 const FileSpec& file = module->GetPlatformFileSpec();
645
646 for (const auto &rs_script : m_scripts)
647 {
648 if (file.GetFilename() == ConstString(rs_script.scriptDyLib.c_str()))
649 {
650 if (m_scriptMappings.find( rs_script.script ) != m_scriptMappings.end())
651 {
652 if (m_scriptMappings[rs_script.script] != rsmodule_sp)
653 {
654 if (log)
655 {
656 log->Printf ("RenderScriptRuntime::FixupScriptDetails - Error: script %" PRIx64 " wants reassigned to new rsmodule '%s'.",
657 (uint64_t)rs_script.script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
658 }
659 }
660 }
661 else
662 {
663 m_scriptMappings[rs_script.script] = rsmodule_sp;
664 rsmodule_sp->m_resname = rs_script.resname;
665 if (log)
666 {
667 log->Printf ("RenderScriptRuntime::FixupScriptDetails - script %" PRIx64 " associated with rsmodule '%s'.",
668 (uint64_t)rs_script.script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString());
669 }
670 }
671 }
672 }
673
674}
675
Colin Riley5ec532a2015-04-09 16:49:25 +0000676bool
677RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
678{
Colin Riley4640cde2015-06-01 18:23:41 +0000679 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE));
680
Colin Riley5ec532a2015-04-09 16:49:25 +0000681 if (module_sp)
682 {
683 for (const auto &rs_module : m_rsmodules)
684 {
Colin Riley4640cde2015-06-01 18:23:41 +0000685 if (rs_module->m_module == module_sp)
Ewan Crawford7dc77712015-09-10 10:08:48 +0000686 {
687 // Check if the user has enabled automatically breaking on
688 // all RS kernels.
689 if (m_breakAllKernels)
690 BreakOnModuleKernels(rs_module);
691
Colin Riley5ec532a2015-04-09 16:49:25 +0000692 return false;
Ewan Crawford7dc77712015-09-10 10:08:48 +0000693 }
Colin Riley5ec532a2015-04-09 16:49:25 +0000694 }
Colin Rileyef20b082015-04-14 07:39:24 +0000695 bool module_loaded = false;
696 switch (GetModuleKind(module_sp))
Colin Riley5ec532a2015-04-09 16:49:25 +0000697 {
Colin Rileyef20b082015-04-14 07:39:24 +0000698 case eModuleKindKernelObj:
699 {
Colin Riley4640cde2015-06-01 18:23:41 +0000700 RSModuleDescriptorSP module_desc;
701 module_desc.reset(new RSModuleDescriptor(module_sp));
702 if (module_desc->ParseRSInfo())
Colin Rileyef20b082015-04-14 07:39:24 +0000703 {
704 m_rsmodules.push_back(module_desc);
705 module_loaded = true;
706 }
Colin Riley4640cde2015-06-01 18:23:41 +0000707 if (module_loaded)
708 {
709 FixupScriptDetails(module_desc);
710 }
Colin Rileyef20b082015-04-14 07:39:24 +0000711 break;
712 }
713 case eModuleKindDriver:
Colin Riley4640cde2015-06-01 18:23:41 +0000714 {
715 if (!m_libRSDriver)
716 {
717 m_libRSDriver = module_sp;
718 LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver);
719 }
720 break;
721 }
Colin Rileyef20b082015-04-14 07:39:24 +0000722 case eModuleKindImpl:
Colin Riley4640cde2015-06-01 18:23:41 +0000723 {
724 m_libRSCpuRef = module_sp;
725 break;
726 }
Colin Rileyef20b082015-04-14 07:39:24 +0000727 case eModuleKindLibRS:
Colin Riley4640cde2015-06-01 18:23:41 +0000728 {
729 if (!m_libRS)
730 {
731 m_libRS = module_sp;
732 static ConstString gDbgPresentStr("gDebuggerPresent");
733 const Symbol* debug_present = m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData);
734 if (debug_present)
735 {
736 Error error;
737 uint32_t flag = 0x00000001U;
738 Target &target = GetProcess()->GetTarget();
Greg Clayton358cf1e2015-06-25 21:46:34 +0000739 addr_t addr = debug_present->GetLoadAddress(&target);
Colin Riley4640cde2015-06-01 18:23:41 +0000740 GetProcess()->WriteMemory(addr, &flag, sizeof(flag), error);
741 if(error.Success())
742 {
743 if (log)
744 log->Printf ("RenderScriptRuntime::LoadModule - Debugger present flag set on debugee");
745
746 m_debuggerPresentFlagged = true;
747 }
748 else if (log)
749 {
750 log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags '%s' ", error.AsCString());
751 }
752 }
753 else if (log)
754 {
755 log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags - symbol not found");
756 }
757 }
758 break;
759 }
Colin Rileyef20b082015-04-14 07:39:24 +0000760 default:
761 break;
Colin Riley5ec532a2015-04-09 16:49:25 +0000762 }
Colin Rileyef20b082015-04-14 07:39:24 +0000763 if (module_loaded)
764 Update();
765 return module_loaded;
Colin Riley5ec532a2015-04-09 16:49:25 +0000766 }
767 return false;
768}
769
Colin Rileyef20b082015-04-14 07:39:24 +0000770void
771RenderScriptRuntime::Update()
772{
773 if (m_rsmodules.size() > 0)
774 {
775 if (!m_initiated)
776 {
777 Initiate();
778 }
779 }
780}
781
782
Colin Riley5ec532a2015-04-09 16:49:25 +0000783// The maximum line length of an .rs.info packet
784#define MAXLINE 500
785
786// The .rs.info symbol in renderscript modules contains a string which needs to be parsed.
787// The string is basic and is parsed on a line by line basis.
788bool
789RSModuleDescriptor::ParseRSInfo()
790{
791 const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
792 if (info_sym)
793 {
Greg Clayton358cf1e2015-06-25 21:46:34 +0000794 const addr_t addr = info_sym->GetAddressRef().GetFileAddress();
Colin Riley5ec532a2015-04-09 16:49:25 +0000795 const addr_t size = info_sym->GetByteSize();
796 const FileSpec fs = m_module->GetFileSpec();
797
798 DataBufferSP buffer = fs.ReadFileContents(addr, size);
799
800 if (!buffer)
801 return false;
802
803 std::string info((const char *)buffer->GetBytes());
804
805 std::vector<std::string> info_lines;
Bruce Mitchenere8433cc2015-09-01 23:57:17 +0000806 size_t lpos = info.find('\n');
Colin Riley5ec532a2015-04-09 16:49:25 +0000807 while (lpos != std::string::npos)
808 {
809 info_lines.push_back(info.substr(0, lpos));
810 info = info.substr(lpos + 1);
Bruce Mitchenere8433cc2015-09-01 23:57:17 +0000811 lpos = info.find('\n');
Colin Riley5ec532a2015-04-09 16:49:25 +0000812 }
813 size_t offset = 0;
814 while (offset < info_lines.size())
815 {
816 std::string line = info_lines[offset];
817 // Parse directives
818 uint32_t numDefns = 0;
819 if (sscanf(line.c_str(), "exportVarCount: %u", &numDefns) == 1)
820 {
821 while (numDefns--)
Colin Riley4640cde2015-06-01 18:23:41 +0000822 m_globals.push_back(RSGlobalDescriptor(this, info_lines[++offset].c_str()));
Colin Riley5ec532a2015-04-09 16:49:25 +0000823 }
824 else if (sscanf(line.c_str(), "exportFuncCount: %u", &numDefns) == 1)
825 {
826 }
827 else if (sscanf(line.c_str(), "exportForEachCount: %u", &numDefns) == 1)
828 {
829 char name[MAXLINE];
830 while (numDefns--)
831 {
832 uint32_t slot = 0;
833 name[0] = '\0';
834 if (sscanf(info_lines[++offset].c_str(), "%u - %s", &slot, &name[0]) == 2)
835 {
Colin Riley4640cde2015-06-01 18:23:41 +0000836 m_kernels.push_back(RSKernelDescriptor(this, name, slot));
837 }
838 }
839 }
840 else if (sscanf(line.c_str(), "pragmaCount: %u", &numDefns) == 1)
841 {
842 char name[MAXLINE];
843 char value[MAXLINE];
844 while (numDefns--)
845 {
846 name[0] = '\0';
847 value[0] = '\0';
848 if (sscanf(info_lines[++offset].c_str(), "%s - %s", &name[0], &value[0]) != 0
849 && (name[0] != '\0'))
850 {
851 m_pragmas[std::string(name)] = value;
Colin Riley5ec532a2015-04-09 16:49:25 +0000852 }
853 }
854 }
855 else if (sscanf(line.c_str(), "objectSlotCount: %u", &numDefns) == 1)
856 {
857 }
858
859 offset++;
860 }
861 return m_kernels.size() > 0;
862 }
863 return false;
864}
865
866bool
867RenderScriptRuntime::ProbeModules(const ModuleList module_list)
868{
869 bool rs_found = false;
870 size_t num_modules = module_list.GetSize();
871 for (size_t i = 0; i < num_modules; i++)
872 {
873 auto module = module_list.GetModuleAtIndex(i);
874 rs_found |= LoadModule(module);
875 }
876 return rs_found;
877}
878
879void
Colin Riley4640cde2015-06-01 18:23:41 +0000880RenderScriptRuntime::Status(Stream &strm) const
881{
882 if (m_libRS)
883 {
884 strm.Printf("Runtime Library discovered.");
885 strm.EOL();
886 }
887 if (m_libRSDriver)
888 {
889 strm.Printf("Runtime Driver discovered.");
890 strm.EOL();
891 }
892 if (m_libRSCpuRef)
893 {
894 strm.Printf("CPU Reference Implementation discovered.");
895 strm.EOL();
896 }
897
898 if (m_runtimeHooks.size())
899 {
900 strm.Printf("Runtime functions hooked:");
901 strm.EOL();
902 for (auto b : m_runtimeHooks)
903 {
904 strm.Indent(b.second->defn->name);
905 strm.EOL();
906 }
907 strm.EOL();
908 }
909 else
910 {
911 strm.Printf("Runtime is not hooked.");
912 strm.EOL();
913 }
914}
915
916void
917RenderScriptRuntime::DumpContexts(Stream &strm) const
918{
919 strm.Printf("Inferred RenderScript Contexts:");
920 strm.EOL();
921 strm.IndentMore();
922
923 std::map<addr_t, uint64_t> contextReferences;
924
925 for (const auto &script : m_scripts)
926 {
927 if (contextReferences.find(script.context) != contextReferences.end())
928 {
929 contextReferences[script.context]++;
930 }
931 else
932 {
933 contextReferences[script.context] = 1;
934 }
935 }
936
937 for (const auto& cRef : contextReferences)
938 {
939 strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances", cRef.first, cRef.second);
940 strm.EOL();
941 }
942 strm.IndentLess();
943}
944
945void
946RenderScriptRuntime::DumpKernels(Stream &strm) const
947{
948 strm.Printf("RenderScript Kernels:");
949 strm.EOL();
950 strm.IndentMore();
951 for (const auto &module : m_rsmodules)
952 {
953 strm.Printf("Resource '%s':",module->m_resname.c_str());
954 strm.EOL();
955 for (const auto &kernel : module->m_kernels)
956 {
957 strm.Indent(kernel.m_name.AsCString());
958 strm.EOL();
959 }
960 }
961 strm.IndentLess();
962}
963
Ewan Crawford7dc77712015-09-10 10:08:48 +0000964// Set breakpoints on every kernel found in RS module
965void
966RenderScriptRuntime::BreakOnModuleKernels(const RSModuleDescriptorSP rsmodule_sp)
967{
968 for (const auto &kernel : rsmodule_sp->m_kernels)
969 {
970 // Don't set breakpoint on 'root' kernel
971 if (strcmp(kernel.m_name.AsCString(), "root") == 0)
972 continue;
973
974 CreateKernelBreakpoint(kernel.m_name);
975 }
976}
977
978// Method is internally called by the 'kernel breakpoint all' command to
979// enable or disable breaking on all kernels.
980//
981// When do_break is true we want to enable this functionality.
982// When do_break is false we want to disable it.
983void
984RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target)
985{
Ewan Crawford54782db2015-09-16 10:02:57 +0000986 Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
Ewan Crawford7dc77712015-09-10 10:08:48 +0000987
988 InitSearchFilter(target);
989
990 // Set breakpoints on all the kernels
991 if (do_break && !m_breakAllKernels)
992 {
993 m_breakAllKernels = true;
994
995 for (const auto &module : m_rsmodules)
996 BreakOnModuleKernels(module);
997
998 if (log)
999 log->Printf("RenderScriptRuntime::SetBreakAllKernels(True)"
1000 "- breakpoints set on all currently loaded kernels");
1001 }
1002 else if (!do_break && m_breakAllKernels) // Breakpoints won't be set on any new kernels.
1003 {
1004 m_breakAllKernels = false;
1005
1006 if (log)
1007 log->Printf("RenderScriptRuntime::SetBreakAllKernels(False) - breakpoints no longer automatically set");
1008 }
1009}
1010
1011// Given the name of a kernel this function creates a breakpoint using our
1012// own breakpoint resolver, and returns the Breakpoint shared pointer.
1013BreakpointSP
1014RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name)
1015{
Ewan Crawford54782db2015-09-16 10:02:57 +00001016 Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS));
Ewan Crawford7dc77712015-09-10 10:08:48 +00001017
1018 if (!m_filtersp)
1019 {
1020 if (log)
1021 log->Printf("RenderScriptRuntime::CreateKernelBreakpoint - Error: No breakpoint search filter set");
1022 return nullptr;
1023 }
1024
1025 BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name));
1026 BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(m_filtersp, resolver_sp, false, false, false);
1027
Ewan Crawford54782db2015-09-16 10:02:57 +00001028 // Give RS breakpoints a specific name, so the user can manipulate them as a group.
1029 Error err;
1030 if (!bp->AddName("RenderScriptKernel", err) && log)
1031 log->Printf("RenderScriptRuntime::CreateKernelBreakpoint: Error setting break name, %s", err.AsCString());
1032
Ewan Crawford7dc77712015-09-10 10:08:48 +00001033 return bp;
1034}
1035
Ewan Crawford98156582015-09-04 08:56:52 +00001036void
1037RenderScriptRuntime::AttemptBreakpointAtKernelName(Stream &strm, const char* name, Error& error, TargetSP target)
Colin Riley4640cde2015-06-01 18:23:41 +00001038{
Ewan Crawford98156582015-09-04 08:56:52 +00001039 if (!name)
Colin Riley4640cde2015-06-01 18:23:41 +00001040 {
1041 error.SetErrorString("invalid kernel name");
1042 return;
1043 }
1044
Ewan Crawford7dc77712015-09-10 10:08:48 +00001045 InitSearchFilter(target);
Ewan Crawford98156582015-09-04 08:56:52 +00001046
Colin Riley4640cde2015-06-01 18:23:41 +00001047 ConstString kernel_name(name);
Ewan Crawford7dc77712015-09-10 10:08:48 +00001048 BreakpointSP bp = CreateKernelBreakpoint(kernel_name);
Ewan Crawford98156582015-09-04 08:56:52 +00001049 if (bp)
1050 bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false);
Colin Riley4640cde2015-06-01 18:23:41 +00001051
Colin Riley4640cde2015-06-01 18:23:41 +00001052 return;
1053}
1054
1055void
Colin Riley5ec532a2015-04-09 16:49:25 +00001056RenderScriptRuntime::DumpModules(Stream &strm) const
1057{
1058 strm.Printf("RenderScript Modules:");
1059 strm.EOL();
1060 strm.IndentMore();
1061 for (const auto &module : m_rsmodules)
1062 {
Colin Riley4640cde2015-06-01 18:23:41 +00001063 module->Dump(strm);
Colin Riley5ec532a2015-04-09 16:49:25 +00001064 }
1065 strm.IndentLess();
1066}
1067
1068void
1069RSModuleDescriptor::Dump(Stream &strm) const
1070{
1071 strm.Indent();
1072 m_module->GetFileSpec().Dump(&strm);
Colin Riley4640cde2015-06-01 18:23:41 +00001073 m_module->ParseAllDebugSymbols();
1074 if(m_module->GetNumCompileUnits())
1075 {
1076 strm.Indent("Debug info loaded.");
1077 }
1078 else
1079 {
1080 strm.Indent("Debug info does not exist.");
1081 }
Colin Riley5ec532a2015-04-09 16:49:25 +00001082 strm.EOL();
1083 strm.IndentMore();
1084 strm.Indent();
Colin Riley189598e2015-04-12 22:05:58 +00001085 strm.Printf("Globals: %" PRIu64, static_cast<uint64_t>(m_globals.size()));
Colin Riley5ec532a2015-04-09 16:49:25 +00001086 strm.EOL();
1087 strm.IndentMore();
1088 for (const auto &global : m_globals)
1089 {
1090 global.Dump(strm);
1091 }
1092 strm.IndentLess();
1093 strm.Indent();
Colin Riley189598e2015-04-12 22:05:58 +00001094 strm.Printf("Kernels: %" PRIu64, static_cast<uint64_t>(m_kernels.size()));
Colin Riley5ec532a2015-04-09 16:49:25 +00001095 strm.EOL();
1096 strm.IndentMore();
1097 for (const auto &kernel : m_kernels)
1098 {
1099 kernel.Dump(strm);
1100 }
Colin Riley4640cde2015-06-01 18:23:41 +00001101 strm.Printf("Pragmas: %" PRIu64 , static_cast<uint64_t>(m_pragmas.size()));
1102 strm.EOL();
1103 strm.IndentMore();
1104 for (const auto &key_val : m_pragmas)
1105 {
1106 strm.Printf("%s: %s", key_val.first.c_str(), key_val.second.c_str());
1107 strm.EOL();
1108 }
Colin Riley5ec532a2015-04-09 16:49:25 +00001109 strm.IndentLess(4);
1110}
1111
1112void
1113RSGlobalDescriptor::Dump(Stream &strm) const
1114{
1115 strm.Indent(m_name.AsCString());
Colin Riley4640cde2015-06-01 18:23:41 +00001116 VariableList var_list;
1117 m_module->m_module->FindGlobalVariables(m_name, nullptr, true, 1U, var_list);
1118 if (var_list.GetSize() == 1)
1119 {
1120 auto var = var_list.GetVariableAtIndex(0);
1121 auto type = var->GetType();
1122 if(type)
1123 {
1124 strm.Printf(" - ");
1125 type->DumpTypeName(&strm);
1126 }
1127 else
1128 {
1129 strm.Printf(" - Unknown Type");
1130 }
1131 }
1132 else
1133 {
1134 strm.Printf(" - variable identified, but not found in binary");
1135 const Symbol* s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData);
1136 if (s)
1137 {
1138 strm.Printf(" (symbol exists) ");
1139 }
1140 }
1141
Colin Riley5ec532a2015-04-09 16:49:25 +00001142 strm.EOL();
1143}
1144
1145void
1146RSKernelDescriptor::Dump(Stream &strm) const
1147{
1148 strm.Indent(m_name.AsCString());
1149 strm.EOL();
1150}
1151
1152class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed
1153{
1154 private:
1155 public:
1156 CommandObjectRenderScriptRuntimeModuleProbe(CommandInterpreter &interpreter)
1157 : CommandObjectParsed(interpreter, "renderscript module probe",
1158 "Initiates a Probe of all loaded modules for kernels and other renderscript objects.",
1159 "renderscript module probe",
Enrico Granatae87764f2015-05-27 05:04:35 +00001160 eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBeLaunched)
Colin Riley5ec532a2015-04-09 16:49:25 +00001161 {
1162 }
1163
1164 ~CommandObjectRenderScriptRuntimeModuleProbe() {}
1165
1166 bool
1167 DoExecute(Args &command, CommandReturnObject &result)
1168 {
1169 const size_t argc = command.GetArgumentCount();
1170 if (argc == 0)
1171 {
1172 Target *target = m_exe_ctx.GetTargetPtr();
1173 RenderScriptRuntime *runtime =
1174 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
1175 auto module_list = target->GetImages();
1176 bool new_rs_details = runtime->ProbeModules(module_list);
1177 if (new_rs_details)
1178 {
1179 result.AppendMessage("New renderscript modules added to runtime model.");
1180 }
1181 result.SetStatus(eReturnStatusSuccessFinishResult);
1182 return true;
1183 }
1184
1185 result.AppendErrorWithFormat("'%s' takes no arguments", m_cmd_name.c_str());
1186 result.SetStatus(eReturnStatusFailed);
1187 return false;
1188 }
1189};
1190
1191class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed
1192{
1193 private:
1194 public:
1195 CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter)
1196 : CommandObjectParsed(interpreter, "renderscript module dump",
1197 "Dumps renderscript specific information for all modules.", "renderscript module dump",
Enrico Granatae87764f2015-05-27 05:04:35 +00001198 eCommandRequiresProcess | eCommandProcessMustBeLaunched)
Colin Riley5ec532a2015-04-09 16:49:25 +00001199 {
1200 }
1201
1202 ~CommandObjectRenderScriptRuntimeModuleDump() {}
1203
1204 bool
1205 DoExecute(Args &command, CommandReturnObject &result)
1206 {
1207 RenderScriptRuntime *runtime =
1208 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
1209 runtime->DumpModules(result.GetOutputStream());
1210 result.SetStatus(eReturnStatusSuccessFinishResult);
1211 return true;
1212 }
1213};
1214
1215class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword
1216{
1217 private:
1218 public:
1219 CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter)
1220 : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with renderscript modules.",
1221 NULL)
1222 {
1223 LoadSubCommand("probe", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleProbe(interpreter)));
1224 LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter)));
1225 }
1226
1227 ~CommandObjectRenderScriptRuntimeModule() {}
1228};
1229
Colin Riley4640cde2015-06-01 18:23:41 +00001230class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed
1231{
1232 private:
1233 public:
1234 CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter)
1235 : CommandObjectParsed(interpreter, "renderscript kernel list",
1236 "Lists renderscript kernel names and associated script resources.", "renderscript kernel list",
1237 eCommandRequiresProcess | eCommandProcessMustBeLaunched)
1238 {
1239 }
1240
1241 ~CommandObjectRenderScriptRuntimeKernelList() {}
1242
1243 bool
1244 DoExecute(Args &command, CommandReturnObject &result)
1245 {
1246 RenderScriptRuntime *runtime =
1247 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
1248 runtime->DumpKernels(result.GetOutputStream());
1249 result.SetStatus(eReturnStatusSuccessFinishResult);
1250 return true;
1251 }
1252};
1253
Ewan Crawford7dc77712015-09-10 10:08:48 +00001254class CommandObjectRenderScriptRuntimeKernelBreakpointSet : public CommandObjectParsed
Colin Riley4640cde2015-06-01 18:23:41 +00001255{
1256 private:
1257 public:
Ewan Crawford7dc77712015-09-10 10:08:48 +00001258 CommandObjectRenderScriptRuntimeKernelBreakpointSet(CommandInterpreter &interpreter)
1259 : CommandObjectParsed(interpreter, "renderscript kernel breakpoint set",
1260 "Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint set <kernel_name>",
Colin Riley4640cde2015-06-01 18:23:41 +00001261 eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
1262 {
1263 }
1264
Ewan Crawford7dc77712015-09-10 10:08:48 +00001265 ~CommandObjectRenderScriptRuntimeKernelBreakpointSet() {}
Colin Riley4640cde2015-06-01 18:23:41 +00001266
1267 bool
1268 DoExecute(Args &command, CommandReturnObject &result)
1269 {
1270 const size_t argc = command.GetArgumentCount();
1271 if (argc == 1)
1272 {
1273 RenderScriptRuntime *runtime =
1274 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
1275
1276 Error error;
Ewan Crawford98156582015-09-04 08:56:52 +00001277 runtime->AttemptBreakpointAtKernelName(result.GetOutputStream(), command.GetArgumentAtIndex(0),
1278 error, m_exe_ctx.GetTargetSP());
Colin Riley4640cde2015-06-01 18:23:41 +00001279
1280 if (error.Success())
1281 {
1282 result.AppendMessage("Breakpoint(s) created");
1283 result.SetStatus(eReturnStatusSuccessFinishResult);
1284 return true;
1285 }
1286 result.SetStatus(eReturnStatusFailed);
1287 result.AppendErrorWithFormat("Error: %s", error.AsCString());
1288 return false;
1289 }
1290
1291 result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name", m_cmd_name.c_str());
1292 result.SetStatus(eReturnStatusFailed);
1293 return false;
1294 }
1295};
1296
Ewan Crawford7dc77712015-09-10 10:08:48 +00001297class CommandObjectRenderScriptRuntimeKernelBreakpointAll : public CommandObjectParsed
1298{
1299 private:
1300 public:
1301 CommandObjectRenderScriptRuntimeKernelBreakpointAll(CommandInterpreter &interpreter)
1302 : CommandObjectParsed(interpreter, "renderscript kernel breakpoint all",
1303 "Automatically sets a breakpoint on all renderscript kernels that are or will be loaded.\n"
1304 "Disabling option means breakpoints will no longer be set on any kernels loaded in the future, "
1305 "but does not remove currently set breakpoints.",
1306 "renderscript kernel breakpoint all <enable/disable>",
1307 eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused)
1308 {
1309 }
1310
1311 ~CommandObjectRenderScriptRuntimeKernelBreakpointAll() {}
1312
1313 bool
1314 DoExecute(Args &command, CommandReturnObject &result)
1315 {
1316 const size_t argc = command.GetArgumentCount();
1317 if (argc != 1)
1318 {
1319 result.AppendErrorWithFormat("'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str());
1320 result.SetStatus(eReturnStatusFailed);
1321 return false;
1322 }
1323
1324 RenderScriptRuntime *runtime =
1325 static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript));
1326
1327 bool do_break = false;
1328 const char* argument = command.GetArgumentAtIndex(0);
1329 if (strcmp(argument, "enable") == 0)
1330 {
1331 do_break = true;
1332 result.AppendMessage("Breakpoints will be set on all kernels.");
1333 }
1334 else if (strcmp(argument, "disable") == 0)
1335 {
1336 do_break = false;
1337 result.AppendMessage("Breakpoints will not be set on any new kernels.");
1338 }
1339 else
1340 {
1341 result.AppendErrorWithFormat("Argument must be either 'enable' or 'disable'");
1342 result.SetStatus(eReturnStatusFailed);
1343 return false;
1344 }
1345
1346 runtime->SetBreakAllKernels(do_break, m_exe_ctx.GetTargetSP());
1347
1348 result.SetStatus(eReturnStatusSuccessFinishResult);
1349 return true;
1350 }
1351};
1352
1353class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectMultiword
1354{
1355 private:
1356 public:
1357 CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter)
1358 : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that generate breakpoints on renderscript kernels.",
1359 nullptr)
1360 {
1361 LoadSubCommand("set", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointSet(interpreter)));
1362 LoadSubCommand("all", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointAll(interpreter)));
1363 }
1364
1365 ~CommandObjectRenderScriptRuntimeKernelBreakpoint() {}
1366};
1367
Colin Riley4640cde2015-06-01 18:23:41 +00001368class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword
1369{
1370 private:
1371 public:
1372 CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter)
1373 : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with renderscript kernels.",
1374 NULL)
1375 {
1376 LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(interpreter)));
1377 LoadSubCommand("breakpoint", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter)));
1378 }
1379
1380 ~CommandObjectRenderScriptRuntimeKernel() {}
1381};
1382
1383class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed
1384{
1385 private:
1386 public:
1387 CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter)
1388 : CommandObjectParsed(interpreter, "renderscript context dump",
1389 "Dumps renderscript context information.", "renderscript context dump",
1390 eCommandRequiresProcess | eCommandProcessMustBeLaunched)
1391 {
1392 }
1393
1394 ~CommandObjectRenderScriptRuntimeContextDump() {}
1395
1396 bool
1397 DoExecute(Args &command, CommandReturnObject &result)
1398 {
1399 RenderScriptRuntime *runtime =
1400 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
1401 runtime->DumpContexts(result.GetOutputStream());
1402 result.SetStatus(eReturnStatusSuccessFinishResult);
1403 return true;
1404 }
1405};
1406
1407class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword
1408{
1409 private:
1410 public:
1411 CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter)
1412 : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with renderscript contexts.",
1413 NULL)
1414 {
1415 LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(interpreter)));
1416 }
1417
1418 ~CommandObjectRenderScriptRuntimeContext() {}
1419};
1420
1421class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed
1422{
1423 private:
1424 public:
1425 CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter)
1426 : CommandObjectParsed(interpreter, "renderscript status",
1427 "Displays current renderscript runtime status.", "renderscript status",
1428 eCommandRequiresProcess | eCommandProcessMustBeLaunched)
1429 {
1430 }
1431
1432 ~CommandObjectRenderScriptRuntimeStatus() {}
1433
1434 bool
1435 DoExecute(Args &command, CommandReturnObject &result)
1436 {
1437 RenderScriptRuntime *runtime =
1438 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript);
1439 runtime->Status(result.GetOutputStream());
1440 result.SetStatus(eReturnStatusSuccessFinishResult);
1441 return true;
1442 }
1443};
1444
Colin Riley5ec532a2015-04-09 16:49:25 +00001445class CommandObjectRenderScriptRuntime : public CommandObjectMultiword
1446{
1447 public:
1448 CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter)
1449 : CommandObjectMultiword(interpreter, "renderscript", "A set of commands for operating on renderscript.",
1450 "renderscript <subcommand> [<subcommand-options>]")
1451 {
1452 LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter)));
Colin Riley4640cde2015-06-01 18:23:41 +00001453 LoadSubCommand("status", CommandObjectSP(new CommandObjectRenderScriptRuntimeStatus(interpreter)));
1454 LoadSubCommand("kernel", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernel(interpreter)));
1455 LoadSubCommand("context", CommandObjectSP(new CommandObjectRenderScriptRuntimeContext(interpreter)));
Colin Riley5ec532a2015-04-09 16:49:25 +00001456 }
1457
1458 ~CommandObjectRenderScriptRuntime() {}
1459};
Colin Rileyef20b082015-04-14 07:39:24 +00001460
1461void
1462RenderScriptRuntime::Initiate()
Colin Riley5ec532a2015-04-09 16:49:25 +00001463{
Colin Rileyef20b082015-04-14 07:39:24 +00001464 assert(!m_initiated);
Colin Riley5ec532a2015-04-09 16:49:25 +00001465}
Colin Rileyef20b082015-04-14 07:39:24 +00001466
1467RenderScriptRuntime::RenderScriptRuntime(Process *process)
Ewan Crawford7dc77712015-09-10 10:08:48 +00001468 : lldb_private::CPPLanguageRuntime(process), m_initiated(false), m_debuggerPresentFlagged(false),
1469 m_breakAllKernels(false)
Colin Rileyef20b082015-04-14 07:39:24 +00001470{
Colin Riley4640cde2015-06-01 18:23:41 +00001471 ModulesDidLoad(process->GetTarget().GetImages());
Colin Rileyef20b082015-04-14 07:39:24 +00001472}
Colin Riley4640cde2015-06-01 18:23:41 +00001473
1474lldb::CommandObjectSP
1475RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter& interpreter)
1476{
1477 static CommandObjectSP command_object;
1478 if(!command_object)
1479 {
1480 command_object.reset(new CommandObjectRenderScriptRuntime(interpreter));
1481 }
1482 return command_object;
1483}
1484