1 //===-- 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" 18 #include "lldb/Symbol/Type.h" 19 #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" 26 #include "lldb/Breakpoint/StoppointCallbackContext.h" 27 #include "lldb/Target/RegisterContext.h" 28 29 #include "lldb/Symbol/VariableList.h" 30 31 using namespace lldb; 32 using namespace lldb_private; 33 34 //------------------------------------------------------------------ 35 // Static Functions 36 //------------------------------------------------------------------ 37 LanguageRuntime * 38 RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType language) 39 { 40 41 if (language == eLanguageTypeExtRenderScript) 42 return new RenderScriptRuntime(process); 43 else 44 return NULL; 45 } 46 47 void 48 RenderScriptRuntime::Initialize() 49 { 50 PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance, GetCommandObject); 51 } 52 53 void 54 RenderScriptRuntime::Terminate() 55 { 56 PluginManager::UnregisterPlugin(CreateInstance); 57 } 58 59 lldb_private::ConstString 60 RenderScriptRuntime::GetPluginNameStatic() 61 { 62 static ConstString g_name("renderscript"); 63 return g_name; 64 } 65 66 RenderScriptRuntime::ModuleKind 67 RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp) 68 { 69 if (module_sp) 70 { 71 // Is this a module containing renderscript kernels? 72 const Symbol *info_sym = module_sp->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData); 73 if (info_sym) 74 { 75 return eModuleKindKernelObj; 76 } 77 78 // Is this the main RS runtime library 79 const ConstString rs_lib("libRS.so"); 80 if (module_sp->GetFileSpec().GetFilename() == rs_lib) 81 { 82 return eModuleKindLibRS; 83 } 84 85 const ConstString rs_driverlib("libRSDriver.so"); 86 if (module_sp->GetFileSpec().GetFilename() == rs_driverlib) 87 { 88 return eModuleKindDriver; 89 } 90 91 const ConstString rs_cpureflib("libRSCPURef.so"); 92 if (module_sp->GetFileSpec().GetFilename() == rs_cpureflib) 93 { 94 return eModuleKindImpl; 95 } 96 97 } 98 return eModuleKindIgnored; 99 } 100 101 bool 102 RenderScriptRuntime::IsRenderScriptModule(const lldb::ModuleSP &module_sp) 103 { 104 return GetModuleKind(module_sp) != eModuleKindIgnored; 105 } 106 107 108 void 109 RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list ) 110 { 111 Mutex::Locker locker (module_list.GetMutex ()); 112 113 size_t num_modules = module_list.GetSize(); 114 for (size_t i = 0; i < num_modules; i++) 115 { 116 auto mod = module_list.GetModuleAtIndex (i); 117 if (IsRenderScriptModule (mod)) 118 { 119 LoadModule(mod); 120 } 121 } 122 } 123 124 125 //------------------------------------------------------------------ 126 // PluginInterface protocol 127 //------------------------------------------------------------------ 128 lldb_private::ConstString 129 RenderScriptRuntime::GetPluginName() 130 { 131 return GetPluginNameStatic(); 132 } 133 134 uint32_t 135 RenderScriptRuntime::GetPluginVersion() 136 { 137 return 1; 138 } 139 140 bool 141 RenderScriptRuntime::IsVTableName(const char *name) 142 { 143 return false; 144 } 145 146 bool 147 RenderScriptRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic, 148 TypeAndOrName &class_type_or_name, Address &address) 149 { 150 return false; 151 } 152 153 bool 154 RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value) 155 { 156 return false; 157 } 158 159 lldb::BreakpointResolverSP 160 RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) 161 { 162 BreakpointResolverSP resolver_sp; 163 return resolver_sp; 164 } 165 166 167 const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] = 168 { 169 //rsdScript 170 {"rsdScriptInit", "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhjj", 0, RenderScriptRuntime::eModuleKindDriver, &lldb_private::RenderScriptRuntime::CaptureScriptInit1}, 171 {"rsdScriptInvokeForEach", "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvjPK12RsScriptCall", 0, RenderScriptRuntime::eModuleKindDriver, nullptr}, 172 {"rsdScriptInvokeForEachMulti", "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall", 0, RenderScriptRuntime::eModuleKindDriver, nullptr}, 173 {"rsdScriptInvokeFunction", "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvj", 0, RenderScriptRuntime::eModuleKindDriver, nullptr}, 174 {"rsdScriptSetGlobalVar", "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvj", 0, RenderScriptRuntime::eModuleKindDriver, &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar1}, 175 176 //rsdAllocation 177 {"rsdAllocationInit", "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", 0, RenderScriptRuntime::eModuleKindDriver, &lldb_private::RenderScriptRuntime::CaptureAllocationInit1}, 178 {"rsdAllocationRead2D", "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvjj", 0, RenderScriptRuntime::eModuleKindDriver, nullptr}, 179 }; 180 const size_t RenderScriptRuntime::s_runtimeHookCount = sizeof(s_runtimeHookDefns)/sizeof(s_runtimeHookDefns[0]); 181 182 183 bool 184 RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, lldb::user_id_t break_loc_id) 185 { 186 RuntimeHook* hook_info = (RuntimeHook*)baton; 187 ExecutionContext context(ctx->exe_ctx_ref); 188 189 RenderScriptRuntime *lang_rt = (RenderScriptRuntime *)context.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 190 191 lang_rt->HookCallback(hook_info, context); 192 193 return false; 194 } 195 196 197 void 198 RenderScriptRuntime::HookCallback(RuntimeHook* hook_info, ExecutionContext& context) 199 { 200 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 201 202 if(log) 203 log->Printf ("RenderScriptRuntime::HookCallback - '%s' .", hook_info->defn->name); 204 205 if (hook_info->defn->grabber) 206 { 207 (this->*(hook_info->defn->grabber))(hook_info, context); 208 } 209 } 210 211 212 bool 213 RenderScriptRuntime::GetArg32Simple(ExecutionContext& context, uint32_t arg, uint32_t *data) 214 { 215 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 216 217 if (!data) 218 return false; 219 220 Error error; 221 RegisterContext* reg_ctx = context.GetRegisterContext(); 222 Process* process = context.GetProcessPtr(); 223 224 if (context.GetTargetPtr()->GetArchitecture().GetMachine() == llvm::Triple::ArchType::x86) 225 { 226 uint64_t sp = reg_ctx->GetSP(); 227 { 228 uint32_t offset = (1 + arg) * sizeof(uint32_t); 229 process->ReadMemory(sp + offset, data, sizeof(uint32_t), error); 230 if(error.Fail()) 231 { 232 if(log) 233 log->Printf ("RenderScriptRuntime:: GetArg32Simple - error reading X86 stack: %s.", error.AsCString()); 234 } 235 } 236 } 237 else if (context.GetTargetPtr()->GetArchitecture().GetMachine() == llvm::Triple::ArchType::arm) 238 { 239 if (arg < 4) 240 { 241 const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg); 242 RegisterValue rVal; 243 reg_ctx->ReadRegister(rArg, rVal); 244 (*data) = rVal.GetAsUInt32(); 245 } 246 else 247 { 248 uint64_t sp = reg_ctx->GetSP(); 249 { 250 uint32_t offset = (arg-4) * sizeof(uint32_t); 251 process->ReadMemory(sp + offset, &data, sizeof(uint32_t), error); 252 if(error.Fail()) 253 { 254 if(log) 255 log->Printf ("RenderScriptRuntime:: GetArg32Simple - error reading ARM stack: %s.", error.AsCString()); 256 } 257 } 258 } 259 } 260 return true; 261 } 262 263 void 264 RenderScriptRuntime::CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context) 265 { 266 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 267 268 //Context, Script, int, data, length 269 270 Error error; 271 272 uint32_t rs_context_u32 = 0U; 273 uint32_t rs_script_u32 = 0U; 274 uint32_t rs_id_u32 = 0U; 275 uint32_t rs_data_u32 = 0U; 276 uint32_t rs_length_u32 = 0U; 277 278 std::string resname; 279 std::string cachedir; 280 281 GetArg32Simple(context, 0, &rs_context_u32); 282 GetArg32Simple(context, 1, &rs_script_u32); 283 GetArg32Simple(context, 2, &rs_id_u32); 284 GetArg32Simple(context, 3, &rs_data_u32); 285 GetArg32Simple(context, 4, &rs_length_u32); 286 287 if(log) 288 { 289 log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 ":%" PRIu64 "bytes.", 290 (uint64_t)rs_context_u32, (uint64_t)rs_script_u32, (uint64_t)rs_id_u32, (uint64_t)rs_data_u32, (uint64_t)rs_length_u32); 291 292 addr_t script_addr = (addr_t)rs_script_u32; 293 if (m_scriptMappings.find( script_addr ) != m_scriptMappings.end()) 294 { 295 auto rsm = m_scriptMappings[script_addr]; 296 if (rs_id_u32 < rsm->m_globals.size()) 297 { 298 auto rsg = rsm->m_globals[rs_id_u32]; 299 log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - Setting of '%s' within '%s' inferred", rsg.m_name.AsCString(), 300 rsm->m_module->GetFileSpec().GetFilename().AsCString()); 301 } 302 } 303 } 304 } 305 306 void 307 RenderScriptRuntime::CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context) 308 { 309 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 310 311 //Context, Alloc, bool 312 313 Error error; 314 315 uint32_t rs_context_u32 = 0U; 316 uint32_t rs_alloc_u32 = 0U; 317 uint32_t rs_forceZero_u32 = 0U; 318 319 GetArg32Simple(context, 0, &rs_context_u32); 320 GetArg32Simple(context, 1, &rs_alloc_u32); 321 GetArg32Simple(context, 2, &rs_forceZero_u32); 322 323 if(log) 324 log->Printf ("RenderScriptRuntime::CaptureAllocationInit1 - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .", 325 (uint64_t)rs_context_u32, (uint64_t)rs_alloc_u32, (uint64_t)rs_forceZero_u32); 326 } 327 328 void 329 RenderScriptRuntime::CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context) 330 { 331 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 332 333 //Context, Script, resname Str, cachedir Str 334 Error error; 335 Process* process = context.GetProcessPtr(); 336 337 uint32_t rs_context_u32 = 0U; 338 uint32_t rs_script_u32 = 0U; 339 uint32_t rs_resnameptr_u32 = 0U; 340 uint32_t rs_cachedirptr_u32 = 0U; 341 342 std::string resname; 343 std::string cachedir; 344 345 GetArg32Simple(context, 0, &rs_context_u32); 346 GetArg32Simple(context, 1, &rs_script_u32); 347 GetArg32Simple(context, 2, &rs_resnameptr_u32); 348 GetArg32Simple(context, 3, &rs_cachedirptr_u32); 349 350 process->ReadCStringFromMemory((lldb::addr_t)rs_resnameptr_u32, resname, error); 351 if (error.Fail()) 352 { 353 if(log) 354 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading resname: %s.", error.AsCString()); 355 356 } 357 358 process->ReadCStringFromMemory((lldb::addr_t)rs_cachedirptr_u32, cachedir, error); 359 if (error.Fail()) 360 { 361 if(log) 362 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading cachedir: %s.", error.AsCString()); 363 } 364 365 if (log) 366 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .", 367 (uint64_t)rs_context_u32, (uint64_t)rs_script_u32, resname.c_str(), cachedir.c_str()); 368 369 if (resname.size() > 0) 370 { 371 StreamString strm; 372 strm.Printf("librs.%s.so", resname.c_str()); 373 374 ScriptDetails script; 375 script.cachedir = cachedir; 376 script.resname = resname; 377 script.scriptDyLib.assign(strm.GetData()); 378 script.script = rs_script_u32; 379 script.context = rs_context_u32; 380 381 m_scripts.push_back(script); 382 383 if (log) 384 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - '%s' tagged with context 0x%" PRIx64 " and script 0x%" PRIx64 ".", 385 strm.GetData(), (uint64_t)rs_context_u32, (uint64_t)rs_script_u32); 386 } 387 else if (log) 388 { 389 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - resource name invalid, Script not tagged"); 390 } 391 392 } 393 394 395 void 396 RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind) 397 { 398 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 399 400 if (!module) 401 { 402 return; 403 } 404 405 if ((GetProcess()->GetTarget().GetArchitecture().GetMachine() != llvm::Triple::ArchType::x86) 406 && (GetProcess()->GetTarget().GetArchitecture().GetMachine() != llvm::Triple::ArchType::arm)) 407 { 408 if (log) 409 log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to hook runtime. Only X86, ARM supported currently."); 410 411 return; 412 } 413 414 Target &target = GetProcess()->GetTarget(); 415 416 for (size_t idx = 0; idx < s_runtimeHookCount; idx++) 417 { 418 const HookDefn* hook_defn = &s_runtimeHookDefns[idx]; 419 if (hook_defn->kind != kind) { 420 continue; 421 } 422 423 const Symbol *sym = module->FindFirstSymbolWithNameAndType(ConstString(hook_defn->symbol_name), eSymbolTypeCode); 424 425 addr_t addr = sym->GetLoadAddress(&target); 426 if (addr == LLDB_INVALID_ADDRESS) 427 { 428 if(log) 429 log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to resolve the address of hook function '%s' with symbol '%s'.", 430 hook_defn->name, hook_defn->symbol_name); 431 continue; 432 } 433 434 RuntimeHookSP hook(new RuntimeHook()); 435 hook->address = addr; 436 hook->defn = hook_defn; 437 hook->bp_sp = target.CreateBreakpoint(addr, true, false); 438 hook->bp_sp->SetCallback(HookCallback, hook.get(), true); 439 m_runtimeHooks[addr] = hook; 440 if (log) 441 { 442 log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Successfully hooked '%s' in '%s' version %" PRIu64 " at 0x%" PRIx64 ".", 443 hook_defn->name, module->GetFileSpec().GetFilename().AsCString(), (uint64_t)hook_defn->version, (uint64_t)addr); 444 } 445 } 446 } 447 448 void 449 RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp) 450 { 451 if (!rsmodule_sp) 452 return; 453 454 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 455 456 const ModuleSP module = rsmodule_sp->m_module; 457 const FileSpec& file = module->GetPlatformFileSpec(); 458 459 for (const auto &rs_script : m_scripts) 460 { 461 if (file.GetFilename() == ConstString(rs_script.scriptDyLib.c_str())) 462 { 463 if (m_scriptMappings.find( rs_script.script ) != m_scriptMappings.end()) 464 { 465 if (m_scriptMappings[rs_script.script] != rsmodule_sp) 466 { 467 if (log) 468 { 469 log->Printf ("RenderScriptRuntime::FixupScriptDetails - Error: script %" PRIx64 " wants reassigned to new rsmodule '%s'.", 470 (uint64_t)rs_script.script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString()); 471 } 472 } 473 } 474 else 475 { 476 m_scriptMappings[rs_script.script] = rsmodule_sp; 477 rsmodule_sp->m_resname = rs_script.resname; 478 if (log) 479 { 480 log->Printf ("RenderScriptRuntime::FixupScriptDetails - script %" PRIx64 " associated with rsmodule '%s'.", 481 (uint64_t)rs_script.script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString()); 482 } 483 } 484 } 485 } 486 487 } 488 489 bool 490 RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp) 491 { 492 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 493 494 if (module_sp) 495 { 496 for (const auto &rs_module : m_rsmodules) 497 { 498 if (rs_module->m_module == module_sp) 499 return false; 500 } 501 bool module_loaded = false; 502 switch (GetModuleKind(module_sp)) 503 { 504 case eModuleKindKernelObj: 505 { 506 RSModuleDescriptorSP module_desc; 507 module_desc.reset(new RSModuleDescriptor(module_sp)); 508 if (module_desc->ParseRSInfo()) 509 { 510 m_rsmodules.push_back(module_desc); 511 module_loaded = true; 512 } 513 if (module_loaded) 514 { 515 FixupScriptDetails(module_desc); 516 } 517 break; 518 } 519 case eModuleKindDriver: 520 { 521 if (!m_libRSDriver) 522 { 523 m_libRSDriver = module_sp; 524 LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver); 525 } 526 break; 527 } 528 case eModuleKindImpl: 529 { 530 m_libRSCpuRef = module_sp; 531 break; 532 } 533 case eModuleKindLibRS: 534 { 535 if (!m_libRS) 536 { 537 m_libRS = module_sp; 538 static ConstString gDbgPresentStr("gDebuggerPresent"); 539 const Symbol* debug_present = m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData); 540 if (debug_present) 541 { 542 Error error; 543 uint32_t flag = 0x00000001U; 544 Target &target = GetProcess()->GetTarget(); 545 addr_t addr = debug_present->GetLoadAddress(&target); 546 GetProcess()->WriteMemory(addr, &flag, sizeof(flag), error); 547 if(error.Success()) 548 { 549 if (log) 550 log->Printf ("RenderScriptRuntime::LoadModule - Debugger present flag set on debugee"); 551 552 m_debuggerPresentFlagged = true; 553 } 554 else if (log) 555 { 556 log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags '%s' ", error.AsCString()); 557 } 558 } 559 else if (log) 560 { 561 log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags - symbol not found"); 562 } 563 } 564 break; 565 } 566 default: 567 break; 568 } 569 if (module_loaded) 570 Update(); 571 return module_loaded; 572 } 573 return false; 574 } 575 576 void 577 RenderScriptRuntime::Update() 578 { 579 if (m_rsmodules.size() > 0) 580 { 581 if (!m_initiated) 582 { 583 Initiate(); 584 } 585 } 586 } 587 588 589 // The maximum line length of an .rs.info packet 590 #define MAXLINE 500 591 592 // The .rs.info symbol in renderscript modules contains a string which needs to be parsed. 593 // The string is basic and is parsed on a line by line basis. 594 bool 595 RSModuleDescriptor::ParseRSInfo() 596 { 597 const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData); 598 if (info_sym) 599 { 600 const addr_t addr = info_sym->GetAddressRef().GetFileAddress(); 601 const addr_t size = info_sym->GetByteSize(); 602 const FileSpec fs = m_module->GetFileSpec(); 603 604 DataBufferSP buffer = fs.ReadFileContents(addr, size); 605 606 if (!buffer) 607 return false; 608 609 std::string info((const char *)buffer->GetBytes()); 610 611 std::vector<std::string> info_lines; 612 size_t lpos = info.find_first_of("\n"); 613 while (lpos != std::string::npos) 614 { 615 info_lines.push_back(info.substr(0, lpos)); 616 info = info.substr(lpos + 1); 617 lpos = info.find_first_of("\n"); 618 } 619 size_t offset = 0; 620 while (offset < info_lines.size()) 621 { 622 std::string line = info_lines[offset]; 623 // Parse directives 624 uint32_t numDefns = 0; 625 if (sscanf(line.c_str(), "exportVarCount: %u", &numDefns) == 1) 626 { 627 while (numDefns--) 628 m_globals.push_back(RSGlobalDescriptor(this, info_lines[++offset].c_str())); 629 } 630 else if (sscanf(line.c_str(), "exportFuncCount: %u", &numDefns) == 1) 631 { 632 } 633 else if (sscanf(line.c_str(), "exportForEachCount: %u", &numDefns) == 1) 634 { 635 char name[MAXLINE]; 636 while (numDefns--) 637 { 638 uint32_t slot = 0; 639 name[0] = '\0'; 640 if (sscanf(info_lines[++offset].c_str(), "%u - %s", &slot, &name[0]) == 2) 641 { 642 m_kernels.push_back(RSKernelDescriptor(this, name, slot)); 643 } 644 } 645 } 646 else if (sscanf(line.c_str(), "pragmaCount: %u", &numDefns) == 1) 647 { 648 char name[MAXLINE]; 649 char value[MAXLINE]; 650 while (numDefns--) 651 { 652 name[0] = '\0'; 653 value[0] = '\0'; 654 if (sscanf(info_lines[++offset].c_str(), "%s - %s", &name[0], &value[0]) != 0 655 && (name[0] != '\0')) 656 { 657 m_pragmas[std::string(name)] = value; 658 } 659 } 660 } 661 else if (sscanf(line.c_str(), "objectSlotCount: %u", &numDefns) == 1) 662 { 663 } 664 665 offset++; 666 } 667 return m_kernels.size() > 0; 668 } 669 return false; 670 } 671 672 bool 673 RenderScriptRuntime::ProbeModules(const ModuleList module_list) 674 { 675 bool rs_found = false; 676 size_t num_modules = module_list.GetSize(); 677 for (size_t i = 0; i < num_modules; i++) 678 { 679 auto module = module_list.GetModuleAtIndex(i); 680 rs_found |= LoadModule(module); 681 } 682 return rs_found; 683 } 684 685 void 686 RenderScriptRuntime::Status(Stream &strm) const 687 { 688 if (m_libRS) 689 { 690 strm.Printf("Runtime Library discovered."); 691 strm.EOL(); 692 } 693 if (m_libRSDriver) 694 { 695 strm.Printf("Runtime Driver discovered."); 696 strm.EOL(); 697 } 698 if (m_libRSCpuRef) 699 { 700 strm.Printf("CPU Reference Implementation discovered."); 701 strm.EOL(); 702 } 703 704 if (m_runtimeHooks.size()) 705 { 706 strm.Printf("Runtime functions hooked:"); 707 strm.EOL(); 708 for (auto b : m_runtimeHooks) 709 { 710 strm.Indent(b.second->defn->name); 711 strm.EOL(); 712 } 713 strm.EOL(); 714 } 715 else 716 { 717 strm.Printf("Runtime is not hooked."); 718 strm.EOL(); 719 } 720 } 721 722 void 723 RenderScriptRuntime::DumpContexts(Stream &strm) const 724 { 725 strm.Printf("Inferred RenderScript Contexts:"); 726 strm.EOL(); 727 strm.IndentMore(); 728 729 std::map<addr_t, uint64_t> contextReferences; 730 731 for (const auto &script : m_scripts) 732 { 733 if (contextReferences.find(script.context) != contextReferences.end()) 734 { 735 contextReferences[script.context]++; 736 } 737 else 738 { 739 contextReferences[script.context] = 1; 740 } 741 } 742 743 for (const auto& cRef : contextReferences) 744 { 745 strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances", cRef.first, cRef.second); 746 strm.EOL(); 747 } 748 strm.IndentLess(); 749 } 750 751 void 752 RenderScriptRuntime::DumpKernels(Stream &strm) const 753 { 754 strm.Printf("RenderScript Kernels:"); 755 strm.EOL(); 756 strm.IndentMore(); 757 for (const auto &module : m_rsmodules) 758 { 759 strm.Printf("Resource '%s':",module->m_resname.c_str()); 760 strm.EOL(); 761 for (const auto &kernel : module->m_kernels) 762 { 763 strm.Indent(kernel.m_name.AsCString()); 764 strm.EOL(); 765 } 766 } 767 strm.IndentLess(); 768 } 769 770 void 771 RenderScriptRuntime::AttemptBreakpointAtKernelName(Stream &strm, const char* name, Error& error) 772 { 773 if (!name) 774 { 775 error.SetErrorString("invalid kernel name"); 776 return; 777 } 778 779 bool kernels_found; 780 ConstString kernel_name(name); 781 for (const auto &module : m_rsmodules) 782 { 783 for (const auto &kernel : module->m_kernels) 784 { 785 if (kernel.m_name == kernel_name) 786 { 787 //Attempt to set a breakpoint on this symbol, within the module library 788 //If it's not found, it's likely debug info is unavailable - set a 789 //breakpoint on <name>.expand and emit a warning. 790 791 const Symbol* kernel_sym = module->m_module->FindFirstSymbolWithNameAndType(kernel_name, eSymbolTypeCode); 792 793 if (!kernel_sym) 794 { 795 std::string kernel_name_expanded(name); 796 kernel_name_expanded.append(".expand"); 797 kernel_sym = module->m_module->FindFirstSymbolWithNameAndType(ConstString(kernel_name_expanded.c_str()), eSymbolTypeCode); 798 799 if (kernel_sym) 800 { 801 strm.Printf("Kernel '%s' could not be found, but expansion exists. ", name); 802 strm.Printf("Breakpoint placed on expanded kernel. Have you compiled in debug mode?"); 803 strm.EOL(); 804 } 805 else 806 { 807 error.SetErrorStringWithFormat("Could not locate symbols for loaded kernel '%s'.", name); 808 return; 809 } 810 } 811 812 addr_t bp_addr = kernel_sym->GetLoadAddress(&GetProcess()->GetTarget()); 813 if (bp_addr == LLDB_INVALID_ADDRESS) 814 { 815 error.SetErrorStringWithFormat("Could not locate load address for symbols of kernel '%s'.", name); 816 return; 817 } 818 819 BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(bp_addr, false, false); 820 strm.Printf("Breakpoint %" PRIu64 ": kernel '%s' within script '%s'", (uint64_t)bp->GetID(), name, module->m_resname.c_str()); 821 strm.EOL(); 822 823 kernels_found = true; 824 } 825 } 826 } 827 828 if (!kernels_found) 829 { 830 error.SetErrorString("kernel name not found"); 831 } 832 return; 833 } 834 835 void 836 RenderScriptRuntime::DumpModules(Stream &strm) const 837 { 838 strm.Printf("RenderScript Modules:"); 839 strm.EOL(); 840 strm.IndentMore(); 841 for (const auto &module : m_rsmodules) 842 { 843 module->Dump(strm); 844 } 845 strm.IndentLess(); 846 } 847 848 void 849 RSModuleDescriptor::Dump(Stream &strm) const 850 { 851 strm.Indent(); 852 m_module->GetFileSpec().Dump(&strm); 853 m_module->ParseAllDebugSymbols(); 854 if(m_module->GetNumCompileUnits()) 855 { 856 strm.Indent("Debug info loaded."); 857 } 858 else 859 { 860 strm.Indent("Debug info does not exist."); 861 } 862 strm.EOL(); 863 strm.IndentMore(); 864 strm.Indent(); 865 strm.Printf("Globals: %" PRIu64, static_cast<uint64_t>(m_globals.size())); 866 strm.EOL(); 867 strm.IndentMore(); 868 for (const auto &global : m_globals) 869 { 870 global.Dump(strm); 871 } 872 strm.IndentLess(); 873 strm.Indent(); 874 strm.Printf("Kernels: %" PRIu64, static_cast<uint64_t>(m_kernels.size())); 875 strm.EOL(); 876 strm.IndentMore(); 877 for (const auto &kernel : m_kernels) 878 { 879 kernel.Dump(strm); 880 } 881 strm.Printf("Pragmas: %" PRIu64 , static_cast<uint64_t>(m_pragmas.size())); 882 strm.EOL(); 883 strm.IndentMore(); 884 for (const auto &key_val : m_pragmas) 885 { 886 strm.Printf("%s: %s", key_val.first.c_str(), key_val.second.c_str()); 887 strm.EOL(); 888 } 889 strm.IndentLess(4); 890 } 891 892 void 893 RSGlobalDescriptor::Dump(Stream &strm) const 894 { 895 strm.Indent(m_name.AsCString()); 896 VariableList var_list; 897 m_module->m_module->FindGlobalVariables(m_name, nullptr, true, 1U, var_list); 898 if (var_list.GetSize() == 1) 899 { 900 auto var = var_list.GetVariableAtIndex(0); 901 auto type = var->GetType(); 902 if(type) 903 { 904 strm.Printf(" - "); 905 type->DumpTypeName(&strm); 906 } 907 else 908 { 909 strm.Printf(" - Unknown Type"); 910 } 911 } 912 else 913 { 914 strm.Printf(" - variable identified, but not found in binary"); 915 const Symbol* s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData); 916 if (s) 917 { 918 strm.Printf(" (symbol exists) "); 919 } 920 } 921 922 strm.EOL(); 923 } 924 925 void 926 RSKernelDescriptor::Dump(Stream &strm) const 927 { 928 strm.Indent(m_name.AsCString()); 929 strm.EOL(); 930 } 931 932 class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed 933 { 934 private: 935 public: 936 CommandObjectRenderScriptRuntimeModuleProbe(CommandInterpreter &interpreter) 937 : CommandObjectParsed(interpreter, "renderscript module probe", 938 "Initiates a Probe of all loaded modules for kernels and other renderscript objects.", 939 "renderscript module probe", 940 eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBeLaunched) 941 { 942 } 943 944 ~CommandObjectRenderScriptRuntimeModuleProbe() {} 945 946 bool 947 DoExecute(Args &command, CommandReturnObject &result) 948 { 949 const size_t argc = command.GetArgumentCount(); 950 if (argc == 0) 951 { 952 Target *target = m_exe_ctx.GetTargetPtr(); 953 RenderScriptRuntime *runtime = 954 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 955 auto module_list = target->GetImages(); 956 bool new_rs_details = runtime->ProbeModules(module_list); 957 if (new_rs_details) 958 { 959 result.AppendMessage("New renderscript modules added to runtime model."); 960 } 961 result.SetStatus(eReturnStatusSuccessFinishResult); 962 return true; 963 } 964 965 result.AppendErrorWithFormat("'%s' takes no arguments", m_cmd_name.c_str()); 966 result.SetStatus(eReturnStatusFailed); 967 return false; 968 } 969 }; 970 971 class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed 972 { 973 private: 974 public: 975 CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter) 976 : CommandObjectParsed(interpreter, "renderscript module dump", 977 "Dumps renderscript specific information for all modules.", "renderscript module dump", 978 eCommandRequiresProcess | eCommandProcessMustBeLaunched) 979 { 980 } 981 982 ~CommandObjectRenderScriptRuntimeModuleDump() {} 983 984 bool 985 DoExecute(Args &command, CommandReturnObject &result) 986 { 987 RenderScriptRuntime *runtime = 988 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 989 runtime->DumpModules(result.GetOutputStream()); 990 result.SetStatus(eReturnStatusSuccessFinishResult); 991 return true; 992 } 993 }; 994 995 class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword 996 { 997 private: 998 public: 999 CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter) 1000 : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with renderscript modules.", 1001 NULL) 1002 { 1003 LoadSubCommand("probe", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleProbe(interpreter))); 1004 LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter))); 1005 } 1006 1007 ~CommandObjectRenderScriptRuntimeModule() {} 1008 }; 1009 1010 class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed 1011 { 1012 private: 1013 public: 1014 CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter) 1015 : CommandObjectParsed(interpreter, "renderscript kernel list", 1016 "Lists renderscript kernel names and associated script resources.", "renderscript kernel list", 1017 eCommandRequiresProcess | eCommandProcessMustBeLaunched) 1018 { 1019 } 1020 1021 ~CommandObjectRenderScriptRuntimeKernelList() {} 1022 1023 bool 1024 DoExecute(Args &command, CommandReturnObject &result) 1025 { 1026 RenderScriptRuntime *runtime = 1027 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 1028 runtime->DumpKernels(result.GetOutputStream()); 1029 result.SetStatus(eReturnStatusSuccessFinishResult); 1030 return true; 1031 } 1032 }; 1033 1034 class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectParsed 1035 { 1036 private: 1037 public: 1038 CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter) 1039 : CommandObjectParsed(interpreter, "renderscript kernel breakpoint", 1040 "Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint", 1041 eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) 1042 { 1043 } 1044 1045 ~CommandObjectRenderScriptRuntimeKernelBreakpoint() {} 1046 1047 bool 1048 DoExecute(Args &command, CommandReturnObject &result) 1049 { 1050 const size_t argc = command.GetArgumentCount(); 1051 if (argc == 1) 1052 { 1053 RenderScriptRuntime *runtime = 1054 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 1055 1056 Error error; 1057 runtime->AttemptBreakpointAtKernelName(result.GetOutputStream(), command.GetArgumentAtIndex(0), error); 1058 1059 if (error.Success()) 1060 { 1061 result.AppendMessage("Breakpoint(s) created"); 1062 result.SetStatus(eReturnStatusSuccessFinishResult); 1063 return true; 1064 } 1065 result.SetStatus(eReturnStatusFailed); 1066 result.AppendErrorWithFormat("Error: %s", error.AsCString()); 1067 return false; 1068 } 1069 1070 result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name", m_cmd_name.c_str()); 1071 result.SetStatus(eReturnStatusFailed); 1072 return false; 1073 } 1074 }; 1075 1076 class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword 1077 { 1078 private: 1079 public: 1080 CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter) 1081 : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with renderscript kernels.", 1082 NULL) 1083 { 1084 LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(interpreter))); 1085 LoadSubCommand("breakpoint", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter))); 1086 } 1087 1088 ~CommandObjectRenderScriptRuntimeKernel() {} 1089 }; 1090 1091 class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed 1092 { 1093 private: 1094 public: 1095 CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter) 1096 : CommandObjectParsed(interpreter, "renderscript context dump", 1097 "Dumps renderscript context information.", "renderscript context dump", 1098 eCommandRequiresProcess | eCommandProcessMustBeLaunched) 1099 { 1100 } 1101 1102 ~CommandObjectRenderScriptRuntimeContextDump() {} 1103 1104 bool 1105 DoExecute(Args &command, CommandReturnObject &result) 1106 { 1107 RenderScriptRuntime *runtime = 1108 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 1109 runtime->DumpContexts(result.GetOutputStream()); 1110 result.SetStatus(eReturnStatusSuccessFinishResult); 1111 return true; 1112 } 1113 }; 1114 1115 class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword 1116 { 1117 private: 1118 public: 1119 CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter) 1120 : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with renderscript contexts.", 1121 NULL) 1122 { 1123 LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(interpreter))); 1124 } 1125 1126 ~CommandObjectRenderScriptRuntimeContext() {} 1127 }; 1128 1129 class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed 1130 { 1131 private: 1132 public: 1133 CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter) 1134 : CommandObjectParsed(interpreter, "renderscript status", 1135 "Displays current renderscript runtime status.", "renderscript status", 1136 eCommandRequiresProcess | eCommandProcessMustBeLaunched) 1137 { 1138 } 1139 1140 ~CommandObjectRenderScriptRuntimeStatus() {} 1141 1142 bool 1143 DoExecute(Args &command, CommandReturnObject &result) 1144 { 1145 RenderScriptRuntime *runtime = 1146 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 1147 runtime->Status(result.GetOutputStream()); 1148 result.SetStatus(eReturnStatusSuccessFinishResult); 1149 return true; 1150 } 1151 }; 1152 1153 class CommandObjectRenderScriptRuntime : public CommandObjectMultiword 1154 { 1155 public: 1156 CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter) 1157 : CommandObjectMultiword(interpreter, "renderscript", "A set of commands for operating on renderscript.", 1158 "renderscript <subcommand> [<subcommand-options>]") 1159 { 1160 LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter))); 1161 LoadSubCommand("status", CommandObjectSP(new CommandObjectRenderScriptRuntimeStatus(interpreter))); 1162 LoadSubCommand("kernel", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernel(interpreter))); 1163 LoadSubCommand("context", CommandObjectSP(new CommandObjectRenderScriptRuntimeContext(interpreter))); 1164 } 1165 1166 ~CommandObjectRenderScriptRuntime() {} 1167 }; 1168 1169 void 1170 RenderScriptRuntime::Initiate() 1171 { 1172 assert(!m_initiated); 1173 } 1174 1175 RenderScriptRuntime::RenderScriptRuntime(Process *process) 1176 : lldb_private::CPPLanguageRuntime(process), m_initiated(false), m_debuggerPresentFlagged(false) 1177 { 1178 ModulesDidLoad(process->GetTarget().GetImages()); 1179 } 1180 1181 lldb::CommandObjectSP 1182 RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter& interpreter) 1183 { 1184 static CommandObjectSP command_object; 1185 if(!command_object) 1186 { 1187 command_object.reset(new CommandObjectRenderScriptRuntime(interpreter)); 1188 } 1189 return command_object; 1190 } 1191 1192