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 #include "lldb/Expression/UserExpression.h" 29 #include "lldb/Symbol/VariableList.h" 30 31 using namespace lldb; 32 using namespace lldb_private; 33 using namespace lldb_renderscript; 34 35 namespace { 36 37 // The empirical_type adds a basic level of validation to arbitrary data 38 // allowing us to track if data has been discovered and stored or not. 39 // An empirical_type will be marked as valid only if it has been explicitly assigned to. 40 template <typename type_t> 41 class empirical_type 42 { 43 public: 44 // Ctor. Contents is invalid when constructed. 45 empirical_type() 46 : valid(false) 47 {} 48 49 // Return true and copy contents to out if valid, else return false. 50 bool get(type_t& out) const 51 { 52 if (valid) 53 out = data; 54 return valid; 55 } 56 57 // Return a pointer to the contents or nullptr if it was not valid. 58 const type_t* get() const 59 { 60 return valid ? &data : nullptr; 61 } 62 63 // Assign data explicitly. 64 void set(const type_t in) 65 { 66 data = in; 67 valid = true; 68 } 69 70 // Mark contents as invalid. 71 void invalidate() 72 { 73 valid = false; 74 } 75 76 // Returns true if this type contains valid data. 77 bool isValid() const 78 { 79 return valid; 80 } 81 82 // Assignment operator. 83 empirical_type<type_t>& operator = (const type_t in) 84 { 85 set(in); 86 return *this; 87 } 88 89 // Dereference operator returns contents. 90 // Warning: Will assert if not valid so use only when you know data is valid. 91 const type_t& operator * () const 92 { 93 assert(valid); 94 return data; 95 } 96 97 protected: 98 bool valid; 99 type_t data; 100 }; 101 102 } // namespace {} 103 104 // The ScriptDetails class collects data associated with a single script instance. 105 struct RenderScriptRuntime::ScriptDetails 106 { 107 ~ScriptDetails() {}; 108 109 enum ScriptType 110 { 111 eScript, 112 eScriptC 113 }; 114 115 // The derived type of the script. 116 empirical_type<ScriptType> type; 117 // The name of the original source file. 118 empirical_type<std::string> resName; 119 // Path to script .so file on the device. 120 empirical_type<std::string> scriptDyLib; 121 // Directory where kernel objects are cached on device. 122 empirical_type<std::string> cacheDir; 123 // Pointer to the context which owns this script. 124 empirical_type<lldb::addr_t> context; 125 // Pointer to the script object itself. 126 empirical_type<lldb::addr_t> script; 127 }; 128 129 // This AllocationDetails class collects data associated with a single 130 // allocation instance. 131 struct RenderScriptRuntime::AllocationDetails 132 { 133 // Taken from rsDefines.h 134 enum DataKind 135 { 136 RS_KIND_USER, 137 RS_KIND_PIXEL_L = 7, 138 RS_KIND_PIXEL_A, 139 RS_KIND_PIXEL_LA, 140 RS_KIND_PIXEL_RGB, 141 RS_KIND_PIXEL_RGBA, 142 RS_KIND_PIXEL_DEPTH, 143 RS_KIND_PIXEL_YUV, 144 RS_KIND_INVALID = 100 145 }; 146 147 // Taken from rsDefines.h 148 enum DataType 149 { 150 RS_TYPE_NONE = 0, 151 RS_TYPE_FLOAT_16, 152 RS_TYPE_FLOAT_32, 153 RS_TYPE_FLOAT_64, 154 RS_TYPE_SIGNED_8, 155 RS_TYPE_SIGNED_16, 156 RS_TYPE_SIGNED_32, 157 RS_TYPE_SIGNED_64, 158 RS_TYPE_UNSIGNED_8, 159 RS_TYPE_UNSIGNED_16, 160 RS_TYPE_UNSIGNED_32, 161 RS_TYPE_UNSIGNED_64, 162 RS_TYPE_BOOLEAN 163 }; 164 165 struct Dimension 166 { 167 uint32_t dim_1; 168 uint32_t dim_2; 169 uint32_t dim_3; 170 uint32_t cubeMap; 171 172 Dimension() 173 { 174 dim_1 = 0; 175 dim_2 = 0; 176 dim_3 = 0; 177 cubeMap = 0; 178 } 179 }; 180 181 // Monotonically increasing from 1 182 static unsigned int ID; 183 184 // Maps Allocation DataType enum and vector size to printable strings 185 // using mapping from RenderScript numerical types summary documentation 186 static const char* RsDataTypeToString[][4]; 187 188 // Maps Allocation DataKind enum to printable strings 189 static const char* RsDataKindToString[]; 190 191 // Give each allocation an ID as a way 192 // for commands to reference it. 193 const unsigned int id; 194 195 empirical_type<DataType> type; // Type of each data pointer stored by the allocation 196 empirical_type<DataKind> type_kind; // Defines pixel type if Allocation is created from an image 197 empirical_type<uint32_t> type_vec_size; // Vector size of each data point, e.g '4' for uchar4 198 empirical_type<Dimension> dimension; // Dimensions of the Allocation 199 empirical_type<lldb::addr_t> address; // Pointer to address of the RS Allocation 200 empirical_type<lldb::addr_t> data_ptr; // Pointer to the data held by the Allocation 201 empirical_type<lldb::addr_t> type_ptr; // Pointer to the RS Type of the Allocation 202 empirical_type<lldb::addr_t> element_ptr; // Pointer to the RS Element of the Type 203 empirical_type<lldb::addr_t> context; // Pointer to the RS Context of the Allocation 204 205 // Give each allocation an id, so we can reference it in user commands. 206 AllocationDetails(): id(ID++) 207 { 208 } 209 210 }; 211 212 unsigned int RenderScriptRuntime::AllocationDetails::ID = 1; 213 214 const char* RenderScriptRuntime::AllocationDetails::RsDataKindToString[] = 215 { 216 "User", 217 "Undefined", "Undefined", "Undefined", // Enum jumps from 0 to 7 218 "Undefined", "Undefined", "Undefined", 219 "L Pixel", 220 "A Pixel", 221 "LA Pixel", 222 "RGB Pixel", 223 "RGBA Pixel", 224 "Pixel Depth", 225 "YUV Pixel" 226 }; 227 228 const char* RenderScriptRuntime::AllocationDetails::RsDataTypeToString[][4] = 229 { 230 {"None", "None", "None", "None"}, 231 {"half", "half2", "half3", "half4"}, 232 {"float", "float2", "float3", "float4"}, 233 {"double", "double2", "double3", "double4"}, 234 {"char", "char2", "char3", "char4"}, 235 {"short", "short2", "short3", "short4"}, 236 {"int", "int2", "int3", "int4"}, 237 {"long", "long2", "long3", "long4"}, 238 {"uchar", "uchar2", "uchar3", "uchar4"}, 239 {"ushort", "ushort2", "ushort3", "ushort4"}, 240 {"uint", "uint2", "uint3", "uint4"}, 241 {"ulong", "ulong2", "ulong3", "ulong4"}, 242 {"bool", "bool2", "bool3", "bool4"} 243 }; 244 245 //------------------------------------------------------------------ 246 // Static Functions 247 //------------------------------------------------------------------ 248 LanguageRuntime * 249 RenderScriptRuntime::CreateInstance(Process *process, lldb::LanguageType language) 250 { 251 252 if (language == eLanguageTypeExtRenderScript) 253 return new RenderScriptRuntime(process); 254 else 255 return NULL; 256 } 257 258 // Callback with a module to search for matching symbols. 259 // We first check that the module contains RS kernels. 260 // Then look for a symbol which matches our kernel name. 261 // The breakpoint address is finally set using the address of this symbol. 262 Searcher::CallbackReturn 263 RSBreakpointResolver::SearchCallback(SearchFilter &filter, 264 SymbolContext &context, 265 Address*, 266 bool) 267 { 268 ModuleSP module = context.module_sp; 269 270 if (!module) 271 return Searcher::eCallbackReturnContinue; 272 273 // Is this a module containing renderscript kernels? 274 if (nullptr == module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData)) 275 return Searcher::eCallbackReturnContinue; 276 277 // Attempt to set a breakpoint on the kernel name symbol within the module library. 278 // If it's not found, it's likely debug info is unavailable - try to set a 279 // breakpoint on <name>.expand. 280 281 const Symbol* kernel_sym = module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode); 282 if (!kernel_sym) 283 { 284 std::string kernel_name_expanded(m_kernel_name.AsCString()); 285 kernel_name_expanded.append(".expand"); 286 kernel_sym = module->FindFirstSymbolWithNameAndType(ConstString(kernel_name_expanded.c_str()), eSymbolTypeCode); 287 } 288 289 if (kernel_sym) 290 { 291 Address bp_addr = kernel_sym->GetAddress(); 292 if (filter.AddressPasses(bp_addr)) 293 m_breakpoint->AddLocation(bp_addr); 294 } 295 296 return Searcher::eCallbackReturnContinue; 297 } 298 299 void 300 RenderScriptRuntime::Initialize() 301 { 302 PluginManager::RegisterPlugin(GetPluginNameStatic(), "RenderScript language support", CreateInstance, GetCommandObject); 303 } 304 305 void 306 RenderScriptRuntime::Terminate() 307 { 308 PluginManager::UnregisterPlugin(CreateInstance); 309 } 310 311 lldb_private::ConstString 312 RenderScriptRuntime::GetPluginNameStatic() 313 { 314 static ConstString g_name("renderscript"); 315 return g_name; 316 } 317 318 RenderScriptRuntime::ModuleKind 319 RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp) 320 { 321 if (module_sp) 322 { 323 // Is this a module containing renderscript kernels? 324 const Symbol *info_sym = module_sp->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData); 325 if (info_sym) 326 { 327 return eModuleKindKernelObj; 328 } 329 330 // Is this the main RS runtime library 331 const ConstString rs_lib("libRS.so"); 332 if (module_sp->GetFileSpec().GetFilename() == rs_lib) 333 { 334 return eModuleKindLibRS; 335 } 336 337 const ConstString rs_driverlib("libRSDriver.so"); 338 if (module_sp->GetFileSpec().GetFilename() == rs_driverlib) 339 { 340 return eModuleKindDriver; 341 } 342 343 const ConstString rs_cpureflib("libRSCpuRef.so"); 344 if (module_sp->GetFileSpec().GetFilename() == rs_cpureflib) 345 { 346 return eModuleKindImpl; 347 } 348 349 } 350 return eModuleKindIgnored; 351 } 352 353 bool 354 RenderScriptRuntime::IsRenderScriptModule(const lldb::ModuleSP &module_sp) 355 { 356 return GetModuleKind(module_sp) != eModuleKindIgnored; 357 } 358 359 360 void 361 RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list ) 362 { 363 Mutex::Locker locker (module_list.GetMutex ()); 364 365 size_t num_modules = module_list.GetSize(); 366 for (size_t i = 0; i < num_modules; i++) 367 { 368 auto mod = module_list.GetModuleAtIndex (i); 369 if (IsRenderScriptModule (mod)) 370 { 371 LoadModule(mod); 372 } 373 } 374 } 375 376 377 //------------------------------------------------------------------ 378 // PluginInterface protocol 379 //------------------------------------------------------------------ 380 lldb_private::ConstString 381 RenderScriptRuntime::GetPluginName() 382 { 383 return GetPluginNameStatic(); 384 } 385 386 uint32_t 387 RenderScriptRuntime::GetPluginVersion() 388 { 389 return 1; 390 } 391 392 bool 393 RenderScriptRuntime::IsVTableName(const char *name) 394 { 395 return false; 396 } 397 398 bool 399 RenderScriptRuntime::GetDynamicTypeAndAddress(ValueObject &in_value, lldb::DynamicValueType use_dynamic, 400 TypeAndOrName &class_type_or_name, Address &address, 401 Value::ValueType &value_type) 402 { 403 return false; 404 } 405 406 TypeAndOrName 407 RenderScriptRuntime::FixUpDynamicType (const TypeAndOrName& type_and_or_name, 408 ValueObject& static_value) 409 { 410 return type_and_or_name; 411 } 412 413 bool 414 RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value) 415 { 416 return false; 417 } 418 419 lldb::BreakpointResolverSP 420 RenderScriptRuntime::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, bool throw_bp) 421 { 422 BreakpointResolverSP resolver_sp; 423 return resolver_sp; 424 } 425 426 427 const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] = 428 { 429 //rsdScript 430 { 431 "rsdScriptInit", //name 432 "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhjj", // symbol name 32 bit 433 "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_7ScriptCEPKcS7_PKhmj", // symbol name 64 bit 434 0, // version 435 RenderScriptRuntime::eModuleKindDriver, // type 436 &lldb_private::RenderScriptRuntime::CaptureScriptInit1 // handler 437 }, 438 { 439 "rsdScriptInvokeForEach", // name 440 "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvjPK12RsScriptCall", // symbol name 32bit 441 "_Z22rsdScriptInvokeForEachPKN7android12renderscript7ContextEPNS0_6ScriptEjPKNS0_10AllocationEPS6_PKvmPK12RsScriptCall", // symbol name 64bit 442 0, // version 443 RenderScriptRuntime::eModuleKindDriver, // type 444 nullptr // handler 445 }, 446 { 447 "rsdScriptInvokeForEachMulti", // name 448 "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall", // symbol name 32bit 449 "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0_6ScriptEjPPKNS0_10AllocationEmPS6_PKvmPK12RsScriptCall", // symbol name 64bit 450 0, // version 451 RenderScriptRuntime::eModuleKindDriver, // type 452 nullptr // handler 453 }, 454 { 455 "rsdScriptInvokeFunction", // name 456 "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvj", // symbol name 32bit 457 "_Z23rsdScriptInvokeFunctionPKN7android12renderscript7ContextEPNS0_6ScriptEjPKvm", // symbol name 64bit 458 0, // version 459 RenderScriptRuntime::eModuleKindDriver, // type 460 nullptr // handler 461 }, 462 { 463 "rsdScriptSetGlobalVar", // name 464 "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvj", // symbol name 32bit 465 "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_6ScriptEjPvm", // symbol name 64bit 466 0, // version 467 RenderScriptRuntime::eModuleKindDriver, // type 468 &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar1 // handler 469 }, 470 471 //rsdAllocation 472 { 473 "rsdAllocationInit", // name 474 "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 32bit 475 "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_10AllocationEb", // symbol name 64bit 476 0, // version 477 RenderScriptRuntime::eModuleKindDriver, // type 478 &lldb_private::RenderScriptRuntime::CaptureAllocationInit1 // handler 479 }, 480 { 481 "rsdAllocationRead2D", //name 482 "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvjj", // symbol name 32bit 483 "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_10AllocationEjjj23RsAllocationCubemapFacejjPvmm", // symbol name 64bit 484 0, // version 485 RenderScriptRuntime::eModuleKindDriver, // type 486 nullptr // handler 487 }, 488 }; 489 const size_t RenderScriptRuntime::s_runtimeHookCount = sizeof(s_runtimeHookDefns)/sizeof(s_runtimeHookDefns[0]); 490 491 492 bool 493 RenderScriptRuntime::HookCallback(void *baton, StoppointCallbackContext *ctx, lldb::user_id_t break_id, lldb::user_id_t break_loc_id) 494 { 495 RuntimeHook* hook_info = (RuntimeHook*)baton; 496 ExecutionContext context(ctx->exe_ctx_ref); 497 498 RenderScriptRuntime *lang_rt = (RenderScriptRuntime *)context.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 499 500 lang_rt->HookCallback(hook_info, context); 501 502 return false; 503 } 504 505 506 void 507 RenderScriptRuntime::HookCallback(RuntimeHook* hook_info, ExecutionContext& context) 508 { 509 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 510 511 if (log) 512 log->Printf ("RenderScriptRuntime::HookCallback - '%s' .", hook_info->defn->name); 513 514 if (hook_info->defn->grabber) 515 { 516 (this->*(hook_info->defn->grabber))(hook_info, context); 517 } 518 } 519 520 521 bool 522 RenderScriptRuntime::GetArgSimple(ExecutionContext &context, uint32_t arg, uint64_t *data) 523 { 524 if (!data) 525 return false; 526 527 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 528 Error error; 529 RegisterContext* reg_ctx = context.GetRegisterContext(); 530 Process* process = context.GetProcessPtr(); 531 bool success = false; // return value 532 533 if (!context.GetTargetPtr()) 534 { 535 if (log) 536 log->Printf("RenderScriptRuntime::GetArgSimple - Invalid target"); 537 538 return false; 539 } 540 541 switch (context.GetTargetPtr()->GetArchitecture().GetMachine()) 542 { 543 case llvm::Triple::ArchType::x86: 544 { 545 uint64_t sp = reg_ctx->GetSP(); 546 uint32_t offset = (1 + arg) * sizeof(uint32_t); 547 uint32_t result = 0; 548 process->ReadMemory(sp + offset, &result, sizeof(uint32_t), error); 549 if (error.Fail()) 550 { 551 if (log) 552 log->Printf ("RenderScriptRuntime:: GetArgSimple - error reading X86 stack: %s.", error.AsCString()); 553 } 554 else 555 { 556 *data = result; 557 success = true; 558 } 559 560 break; 561 } 562 case llvm::Triple::ArchType::arm: 563 { 564 // arm 32 bit 565 if (arg < 4) 566 { 567 const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg); 568 RegisterValue rVal; 569 reg_ctx->ReadRegister(rArg, rVal); 570 (*data) = rVal.GetAsUInt32(); 571 success = true; 572 } 573 else 574 { 575 uint64_t sp = reg_ctx->GetSP(); 576 { 577 uint32_t offset = (arg-4) * sizeof(uint32_t); 578 process->ReadMemory(sp + offset, &data, sizeof(uint32_t), error); 579 if (error.Fail()) 580 { 581 if (log) 582 log->Printf ("RenderScriptRuntime:: GetArgSimple - error reading ARM stack: %s.", error.AsCString()); 583 } 584 else 585 { 586 success = true; 587 } 588 } 589 } 590 591 break; 592 } 593 case llvm::Triple::ArchType::aarch64: 594 { 595 // arm 64 bit 596 // first 8 arguments are in the registers 597 if (arg < 8) 598 { 599 const RegisterInfo* rArg = reg_ctx->GetRegisterInfoAtIndex(arg); 600 RegisterValue rVal; 601 success = reg_ctx->ReadRegister(rArg, rVal); 602 if (success) 603 { 604 *data = rVal.GetAsUInt64(); 605 } 606 else 607 { 608 if (log) 609 log->Printf("RenderScriptRuntime::GetArgSimple() - AARCH64 - Error while reading the argument #%d", arg); 610 } 611 } 612 else 613 { 614 // @TODO: need to find the argument in the stack 615 if (log) 616 log->Printf("RenderScriptRuntime::GetArgSimple - AARCH64 - FOR #ARG >= 8 NOT IMPLEMENTED YET. Argument number: %d", arg); 617 } 618 break; 619 } 620 default: 621 { 622 // invalid architecture 623 if (log) 624 log->Printf("RenderScriptRuntime::GetArgSimple - Architecture not supported"); 625 626 } 627 } 628 629 630 return success; 631 } 632 633 void 634 RenderScriptRuntime::CaptureSetGlobalVar1(RuntimeHook* hook_info, ExecutionContext& context) 635 { 636 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 637 638 //Context, Script, int, data, length 639 640 uint64_t rs_context_u64 = 0U; 641 uint64_t rs_script_u64 = 0U; 642 uint64_t rs_id_u64 = 0U; 643 uint64_t rs_data_u64 = 0U; 644 uint64_t rs_length_u64 = 0U; 645 646 bool success = 647 GetArgSimple(context, 0, &rs_context_u64) && 648 GetArgSimple(context, 1, &rs_script_u64) && 649 GetArgSimple(context, 2, &rs_id_u64) && 650 GetArgSimple(context, 3, &rs_data_u64) && 651 GetArgSimple(context, 4, &rs_length_u64); 652 653 if (!success) 654 { 655 if (log) 656 log->Printf("RenderScriptRuntime::CaptureSetGlobalVar1 - Error while reading the function parameters"); 657 return; 658 } 659 660 if (log) 661 { 662 log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 ":%" PRIu64 "bytes.", 663 rs_context_u64, rs_script_u64, rs_id_u64, rs_data_u64, rs_length_u64); 664 665 addr_t script_addr = (addr_t)rs_script_u64; 666 if (m_scriptMappings.find( script_addr ) != m_scriptMappings.end()) 667 { 668 auto rsm = m_scriptMappings[script_addr]; 669 if (rs_id_u64 < rsm->m_globals.size()) 670 { 671 auto rsg = rsm->m_globals[rs_id_u64]; 672 log->Printf ("RenderScriptRuntime::CaptureSetGlobalVar1 - Setting of '%s' within '%s' inferred", rsg.m_name.AsCString(), 673 rsm->m_module->GetFileSpec().GetFilename().AsCString()); 674 } 675 } 676 } 677 } 678 679 void 680 RenderScriptRuntime::CaptureAllocationInit1(RuntimeHook* hook_info, ExecutionContext& context) 681 { 682 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 683 684 //Context, Alloc, bool 685 686 uint64_t rs_context_u64 = 0U; 687 uint64_t rs_alloc_u64 = 0U; 688 uint64_t rs_forceZero_u64 = 0U; 689 690 bool success = 691 GetArgSimple(context, 0, &rs_context_u64) && 692 GetArgSimple(context, 1, &rs_alloc_u64) && 693 GetArgSimple(context, 2, &rs_forceZero_u64); 694 if (!success) // error case 695 { 696 if (log) 697 log->Printf("RenderScriptRuntime::CaptureAllocationInit1 - Error while reading the function parameters"); 698 return; // abort 699 } 700 701 if (log) 702 log->Printf ("RenderScriptRuntime::CaptureAllocationInit1 - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .", 703 rs_context_u64, rs_alloc_u64, rs_forceZero_u64); 704 705 AllocationDetails* alloc = LookUpAllocation(rs_alloc_u64, true); 706 if (alloc) 707 alloc->context = rs_context_u64; 708 } 709 710 void 711 RenderScriptRuntime::CaptureScriptInit1(RuntimeHook* hook_info, ExecutionContext& context) 712 { 713 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 714 715 //Context, Script, resname Str, cachedir Str 716 Error error; 717 Process* process = context.GetProcessPtr(); 718 719 uint64_t rs_context_u64 = 0U; 720 uint64_t rs_script_u64 = 0U; 721 uint64_t rs_resnameptr_u64 = 0U; 722 uint64_t rs_cachedirptr_u64 = 0U; 723 724 std::string resname; 725 std::string cachedir; 726 727 // read the function parameters 728 bool success = 729 GetArgSimple(context, 0, &rs_context_u64) && 730 GetArgSimple(context, 1, &rs_script_u64) && 731 GetArgSimple(context, 2, &rs_resnameptr_u64) && 732 GetArgSimple(context, 3, &rs_cachedirptr_u64); 733 734 if (!success) 735 { 736 if (log) 737 log->Printf("RenderScriptRuntime::CaptureScriptInit1 - Error while reading the function parameters"); 738 return; 739 } 740 741 process->ReadCStringFromMemory((lldb::addr_t)rs_resnameptr_u64, resname, error); 742 if (error.Fail()) 743 { 744 if (log) 745 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading resname: %s.", error.AsCString()); 746 747 } 748 749 process->ReadCStringFromMemory((lldb::addr_t)rs_cachedirptr_u64, cachedir, error); 750 if (error.Fail()) 751 { 752 if (log) 753 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - error reading cachedir: %s.", error.AsCString()); 754 } 755 756 if (log) 757 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .", 758 rs_context_u64, rs_script_u64, resname.c_str(), cachedir.c_str()); 759 760 if (resname.size() > 0) 761 { 762 StreamString strm; 763 strm.Printf("librs.%s.so", resname.c_str()); 764 765 ScriptDetails* script = LookUpScript(rs_script_u64, true); 766 if (script) 767 { 768 script->type = ScriptDetails::eScriptC; 769 script->cacheDir = cachedir; 770 script->resName = resname; 771 script->scriptDyLib = strm.GetData(); 772 script->context = addr_t(rs_context_u64); 773 } 774 775 if (log) 776 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - '%s' tagged with context 0x%" PRIx64 " and script 0x%" PRIx64 ".", 777 strm.GetData(), rs_context_u64, rs_script_u64); 778 } 779 else if (log) 780 { 781 log->Printf ("RenderScriptRuntime::CaptureScriptInit1 - resource name invalid, Script not tagged"); 782 } 783 784 } 785 786 void 787 RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind) 788 { 789 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 790 791 if (!module) 792 { 793 return; 794 } 795 796 Target &target = GetProcess()->GetTarget(); 797 llvm::Triple::ArchType targetArchType = target.GetArchitecture().GetMachine(); 798 799 if (targetArchType != llvm::Triple::ArchType::x86 800 && targetArchType != llvm::Triple::ArchType::arm 801 && targetArchType != llvm::Triple::ArchType::aarch64) 802 { 803 if (log) 804 log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to hook runtime. Only X86, ARM supported currently."); 805 806 return; 807 } 808 809 uint32_t archByteSize = target.GetArchitecture().GetAddressByteSize(); 810 811 for (size_t idx = 0; idx < s_runtimeHookCount; idx++) 812 { 813 const HookDefn* hook_defn = &s_runtimeHookDefns[idx]; 814 if (hook_defn->kind != kind) { 815 continue; 816 } 817 818 const char* symbol_name = (archByteSize == 4) ? hook_defn->symbol_name_m32 : hook_defn->symbol_name_m64; 819 820 const Symbol *sym = module->FindFirstSymbolWithNameAndType(ConstString(symbol_name), eSymbolTypeCode); 821 if (!sym){ 822 if (log){ 823 log->Printf("RenderScriptRuntime::LoadRuntimeHooks - ERROR: Symbol '%s' related to the function %s not found", symbol_name, hook_defn->name); 824 } 825 continue; 826 } 827 828 addr_t addr = sym->GetLoadAddress(&target); 829 if (addr == LLDB_INVALID_ADDRESS) 830 { 831 if (log) 832 log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Unable to resolve the address of hook function '%s' with symbol '%s'.", 833 hook_defn->name, symbol_name); 834 continue; 835 } 836 else 837 { 838 if (log) 839 log->Printf("RenderScriptRuntime::LoadRuntimeHooks - Function %s, address resolved at 0x%" PRIx64, hook_defn->name, addr); 840 } 841 842 RuntimeHookSP hook(new RuntimeHook()); 843 hook->address = addr; 844 hook->defn = hook_defn; 845 hook->bp_sp = target.CreateBreakpoint(addr, true, false); 846 hook->bp_sp->SetCallback(HookCallback, hook.get(), true); 847 m_runtimeHooks[addr] = hook; 848 if (log) 849 { 850 log->Printf ("RenderScriptRuntime::LoadRuntimeHooks - Successfully hooked '%s' in '%s' version %" PRIu64 " at 0x%" PRIx64 ".", 851 hook_defn->name, module->GetFileSpec().GetFilename().AsCString(), (uint64_t)hook_defn->version, (uint64_t)addr); 852 } 853 } 854 } 855 856 void 857 RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp) 858 { 859 if (!rsmodule_sp) 860 return; 861 862 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 863 864 const ModuleSP module = rsmodule_sp->m_module; 865 const FileSpec& file = module->GetPlatformFileSpec(); 866 867 // Iterate over all of the scripts that we currently know of. 868 // Note: We cant push or pop to m_scripts here or it may invalidate rs_script. 869 for (const auto & rs_script : m_scripts) 870 { 871 // Extract the expected .so file path for this script. 872 std::string dylib; 873 if (!rs_script->scriptDyLib.get(dylib)) 874 continue; 875 876 // Only proceed if the module that has loaded corresponds to this script. 877 if (file.GetFilename() != ConstString(dylib.c_str())) 878 continue; 879 880 // Obtain the script address which we use as a key. 881 lldb::addr_t script; 882 if (!rs_script->script.get(script)) 883 continue; 884 885 // If we have a script mapping for the current script. 886 if (m_scriptMappings.find(script) != m_scriptMappings.end()) 887 { 888 // if the module we have stored is different to the one we just received. 889 if (m_scriptMappings[script] != rsmodule_sp) 890 { 891 if (log) 892 log->Printf ("RenderScriptRuntime::FixupScriptDetails - Error: script %" PRIx64 " wants reassigned to new rsmodule '%s'.", 893 (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString()); 894 } 895 } 896 // We don't have a script mapping for the current script. 897 else 898 { 899 // Obtain the script resource name. 900 std::string resName; 901 if (rs_script->resName.get(resName)) 902 // Set the modules resource name. 903 rsmodule_sp->m_resname = resName; 904 // Add Script/Module pair to map. 905 m_scriptMappings[script] = rsmodule_sp; 906 if (log) 907 log->Printf ("RenderScriptRuntime::FixupScriptDetails - script %" PRIx64 " associated with rsmodule '%s'.", 908 (uint64_t)script, rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString()); 909 } 910 } 911 } 912 913 // Uses the Target API to evaluate the expression passed as a parameter to the function 914 // The result of that expression is returned an unsigned 64 bit int, via the result* paramter. 915 // Function returns true on success, and false on failure 916 bool 917 RenderScriptRuntime::EvalRSExpression(const char* expression, StackFrame* frame_ptr, uint64_t* result) 918 { 919 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 920 if (log) 921 log->Printf("RenderScriptRuntime::EvalRSExpression(%s)", expression); 922 923 ValueObjectSP expr_result; 924 // Perform the actual expression evaluation 925 GetProcess()->GetTarget().EvaluateExpression(expression, frame_ptr, expr_result); 926 927 if (!expr_result) 928 { 929 if (log) 930 log->Printf("RenderScriptRuntime::EvalRSExpression - Error: Couldn't evaluate expression"); 931 return false; 932 } 933 934 // The result of the expression is invalid 935 if (!expr_result->GetError().Success()) 936 { 937 Error err = expr_result->GetError(); 938 if (err.GetError() == UserExpression::kNoResult) // Expression returned void, so this is actually a success 939 { 940 if (log) 941 log->Printf("RenderScriptRuntime::EvalRSExpression - Expression returned void"); 942 943 result = nullptr; 944 return true; 945 } 946 947 if (log) 948 log->Printf("RenderScriptRuntime::EvalRSExpression - Error evaluating expression result: %s", err.AsCString()); 949 return false; 950 } 951 952 bool success = false; 953 *result = expr_result->GetValueAsUnsigned(0, &success); // We only read the result as an unsigned int. 954 955 if (!success) 956 { 957 if (log) 958 log->Printf("RenderScriptRuntime::EvalRSExpression - Error: Couldn't convert expression result to unsigned int"); 959 return false; 960 } 961 962 return true; 963 } 964 965 // Used to index expression format strings 966 enum ExpressionStrings 967 { 968 eExprGetOffsetPtr = 0, 969 eExprAllocGetType, 970 eExprTypeDimX, 971 eExprTypeDimY, 972 eExprTypeDimZ, 973 eExprTypeElemPtr, 974 eExprElementType, 975 eExprElementKind, 976 eExprElementVec 977 }; 978 979 // Format strings containing the expressions we may need to evaluate. 980 const char runtimeExpressions[][256] = 981 { 982 // Mangled GetOffsetPointer(Allocation*, xoff, yoff, zoff, lod, cubemap) 983 "(int*)_Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocationCubemapFace(0x%lx, %u, %u, %u, 0, 0)", 984 985 // Type* rsaAllocationGetType(Context*, Allocation*) 986 "(void*)rsaAllocationGetType(0x%lx, 0x%lx)", 987 988 // rsaTypeGetNativeData(Context*, Type*, void* typeData, size) 989 // Pack the data in the following way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ; 990 // mHal.state.lodCount; mHal.state.faces; mElement; into typeData 991 // Need to specify 32 or 64 bit for uint_t since this differs between devices 992 "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[0]", // X dim 993 "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[1]", // Y dim 994 "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[2]", // Z dim 995 "uint%u_t data[6]; (void*)rsaTypeGetNativeData(0x%lx, 0x%lx, data, 6); data[5]", // Element ptr 996 997 // rsaElementGetNativeData(Context*, Element*, uint32_t* elemData,size) 998 // Pack mType; mKind; mNormalized; mVectorSize; NumSubElements into elemData 999 "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[0]", // Type 1000 "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[1]", // Kind 1001 "uint32_t data[6]; (void*)rsaElementGetNativeData(0x%lx, 0x%lx, data, 5); data[3]" // Vector Size 1002 }; 1003 1004 // JITs the RS runtime for the internal data pointer of an allocation. 1005 // Is passed x,y,z coordinates for the pointer to a specific element. 1006 // Then sets the data_ptr member in Allocation with the result. 1007 // Returns true on success, false otherwise 1008 bool 1009 RenderScriptRuntime::JITDataPointer(AllocationDetails* allocation, StackFrame* frame_ptr, 1010 unsigned int x, unsigned int y, unsigned int z) 1011 { 1012 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 1013 1014 if (!allocation->address.isValid()) 1015 { 1016 if (log) 1017 log->Printf("RenderScriptRuntime::JITDataPointer - Failed to find allocation details"); 1018 return false; 1019 } 1020 1021 const char* expr_cstr = runtimeExpressions[eExprGetOffsetPtr]; 1022 const int max_expr_size = 512; // Max expression size 1023 char buffer[max_expr_size]; 1024 1025 int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->address.get(), x, y, z); 1026 if (chars_written < 0) 1027 { 1028 if (log) 1029 log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()"); 1030 return false; 1031 } 1032 else if (chars_written >= max_expr_size) 1033 { 1034 if (log) 1035 log->Printf("RenderScriptRuntime::JITDataPointer - Expression too long"); 1036 return false; 1037 } 1038 1039 uint64_t result = 0; 1040 if (!EvalRSExpression(buffer, frame_ptr, &result)) 1041 return false; 1042 1043 addr_t mem_ptr = static_cast<lldb::addr_t>(result); 1044 allocation->data_ptr = mem_ptr; 1045 1046 return true; 1047 } 1048 1049 // JITs the RS runtime for the internal pointer to the RS Type of an allocation 1050 // Then sets the type_ptr member in Allocation with the result. 1051 // Returns true on success, false otherwise 1052 bool 1053 RenderScriptRuntime::JITTypePointer(AllocationDetails* allocation, StackFrame* frame_ptr) 1054 { 1055 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 1056 1057 if (!allocation->address.isValid() || !allocation->context.isValid()) 1058 { 1059 if (log) 1060 log->Printf("RenderScriptRuntime::JITTypePointer - Failed to find allocation details"); 1061 return false; 1062 } 1063 1064 const char* expr_cstr = runtimeExpressions[eExprAllocGetType]; 1065 const int max_expr_size = 512; // Max expression size 1066 char buffer[max_expr_size]; 1067 1068 int chars_written = snprintf(buffer, max_expr_size, expr_cstr, *allocation->context.get(), *allocation->address.get()); 1069 if (chars_written < 0) 1070 { 1071 if (log) 1072 log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()"); 1073 return false; 1074 } 1075 else if (chars_written >= max_expr_size) 1076 { 1077 if (log) 1078 log->Printf("RenderScriptRuntime::JITTypePointer - Expression too long"); 1079 return false; 1080 } 1081 1082 uint64_t result = 0; 1083 if (!EvalRSExpression(buffer, frame_ptr, &result)) 1084 return false; 1085 1086 addr_t type_ptr = static_cast<lldb::addr_t>(result); 1087 allocation->type_ptr = type_ptr; 1088 1089 return true; 1090 } 1091 1092 // JITs the RS runtime for information about the dimensions and type of an allocation 1093 // Then sets dimension and element_ptr members in Allocation with the result. 1094 // Returns true on success, false otherwise 1095 bool 1096 RenderScriptRuntime::JITTypePacked(AllocationDetails* allocation, StackFrame* frame_ptr) 1097 { 1098 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 1099 1100 if (!allocation->type_ptr.isValid() || !allocation->context.isValid()) 1101 { 1102 if (log) 1103 log->Printf("RenderScriptRuntime::JITTypePacked - Failed to find allocation details"); 1104 return false; 1105 } 1106 1107 // Expression is different depending on if device is 32 or 64 bit 1108 uint32_t archByteSize = GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize(); 1109 const unsigned int bits = archByteSize == 4 ? 32 : 64; 1110 1111 // We want 4 elements from packed data 1112 const unsigned int num_exprs = 4; 1113 assert(num_exprs == (eExprTypeElemPtr - eExprTypeDimX + 1) && "Invalid number of expressions"); 1114 1115 const int max_expr_size = 512; // Max expression size 1116 char buffer[num_exprs][max_expr_size]; 1117 uint64_t results[num_exprs]; 1118 1119 for (unsigned int i = 0; i < num_exprs; ++i) 1120 { 1121 int chars_written = snprintf(buffer[i], max_expr_size, runtimeExpressions[eExprTypeDimX + i], bits, 1122 *allocation->context.get(), *allocation->type_ptr.get()); 1123 if (chars_written < 0) 1124 { 1125 if (log) 1126 log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()"); 1127 return false; 1128 } 1129 else if (chars_written >= max_expr_size) 1130 { 1131 if (log) 1132 log->Printf("RenderScriptRuntime::JITTypePacked - Expression too long"); 1133 return false; 1134 } 1135 1136 // Perform expression evaluation 1137 if (!EvalRSExpression(buffer[i], frame_ptr, &results[i])) 1138 return false; 1139 } 1140 1141 // Assign results to allocation members 1142 AllocationDetails::Dimension dims; 1143 dims.dim_1 = static_cast<uint32_t>(results[0]); 1144 dims.dim_2 = static_cast<uint32_t>(results[1]); 1145 dims.dim_3 = static_cast<uint32_t>(results[2]); 1146 allocation->dimension = dims; 1147 1148 addr_t elem_ptr = static_cast<lldb::addr_t>(results[3]); 1149 allocation->element_ptr = elem_ptr; 1150 1151 if (log) 1152 log->Printf("RenderScriptRuntime::JITTypePacked - dims (%u, %u, %u) Element*: 0x%" PRIx64, 1153 dims.dim_1, dims.dim_2, dims.dim_3, elem_ptr); 1154 1155 return true; 1156 } 1157 1158 // JITs the RS runtime for information about the Element of an allocation 1159 // Then sets type, type_vec_size, and type_kind members in Allocation with the result. 1160 // Returns true on success, false otherwise 1161 bool 1162 RenderScriptRuntime::JITElementPacked(AllocationDetails* allocation, StackFrame* frame_ptr) 1163 { 1164 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 1165 1166 if (!allocation->element_ptr.isValid() || !allocation->context.isValid()) 1167 { 1168 if (log) 1169 log->Printf("RenderScriptRuntime::JITElementPacked - Failed to find allocation details"); 1170 return false; 1171 } 1172 1173 // We want 3 elements from packed data 1174 const unsigned int num_exprs = 3; 1175 assert(num_exprs == (eExprElementVec - eExprElementType + 1) && "Invalid number of expressions"); 1176 1177 const int max_expr_size = 512; // Max expression size 1178 char buffer[num_exprs][max_expr_size]; 1179 uint64_t results[num_exprs]; 1180 1181 for (unsigned int i = 0; i < num_exprs; i++) 1182 { 1183 int chars_written = snprintf(buffer[i], max_expr_size, runtimeExpressions[eExprElementType + i], *allocation->context.get(), *allocation->element_ptr.get()); 1184 if (chars_written < 0) 1185 { 1186 if (log) 1187 log->Printf("RenderScriptRuntime::JITDataPointer - Encoding error in snprintf()"); 1188 return false; 1189 } 1190 else if (chars_written >= max_expr_size) 1191 { 1192 if (log) 1193 log->Printf("RenderScriptRuntime::JITElementPacked - Expression too long"); 1194 return false; 1195 } 1196 1197 // Perform expression evaluation 1198 if (!EvalRSExpression(buffer[i], frame_ptr, &results[i])) 1199 return false; 1200 } 1201 1202 // Assign results to allocation members 1203 allocation->type = static_cast<RenderScriptRuntime::AllocationDetails::DataType>(results[0]); 1204 allocation->type_kind = static_cast<RenderScriptRuntime::AllocationDetails::DataKind>(results[1]); 1205 allocation->type_vec_size = static_cast<uint32_t>(results[2]); 1206 1207 if (log) 1208 log->Printf("RenderScriptRuntime::JITElementPacked - data type %u, pixel type %u, vector size %u", 1209 *allocation->type.get(), *allocation->type_kind.get(), *allocation->type_vec_size.get()); 1210 1211 return true; 1212 } 1213 1214 // JIT all the current runtime info regarding an allocation 1215 bool 1216 RenderScriptRuntime::RefreshAllocation(AllocationDetails* allocation, StackFrame* frame_ptr) 1217 { 1218 // GetOffsetPointer() 1219 if (!JITDataPointer(allocation, frame_ptr)) 1220 return false; 1221 1222 // rsaAllocationGetType() 1223 if (!JITTypePointer(allocation, frame_ptr)) 1224 return false; 1225 1226 // rsaTypeGetNativeData() 1227 if (!JITTypePacked(allocation, frame_ptr)) 1228 return false; 1229 1230 // rsaElementGetNativeData() 1231 if (!JITElementPacked(allocation, frame_ptr)) 1232 return false; 1233 1234 return true; 1235 } 1236 1237 bool 1238 RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp) 1239 { 1240 Log* log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE)); 1241 1242 if (module_sp) 1243 { 1244 for (const auto &rs_module : m_rsmodules) 1245 { 1246 if (rs_module->m_module == module_sp) 1247 { 1248 // Check if the user has enabled automatically breaking on 1249 // all RS kernels. 1250 if (m_breakAllKernels) 1251 BreakOnModuleKernels(rs_module); 1252 1253 return false; 1254 } 1255 } 1256 bool module_loaded = false; 1257 switch (GetModuleKind(module_sp)) 1258 { 1259 case eModuleKindKernelObj: 1260 { 1261 RSModuleDescriptorSP module_desc; 1262 module_desc.reset(new RSModuleDescriptor(module_sp)); 1263 if (module_desc->ParseRSInfo()) 1264 { 1265 m_rsmodules.push_back(module_desc); 1266 module_loaded = true; 1267 } 1268 if (module_loaded) 1269 { 1270 FixupScriptDetails(module_desc); 1271 } 1272 break; 1273 } 1274 case eModuleKindDriver: 1275 { 1276 if (!m_libRSDriver) 1277 { 1278 m_libRSDriver = module_sp; 1279 LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver); 1280 } 1281 break; 1282 } 1283 case eModuleKindImpl: 1284 { 1285 m_libRSCpuRef = module_sp; 1286 break; 1287 } 1288 case eModuleKindLibRS: 1289 { 1290 if (!m_libRS) 1291 { 1292 m_libRS = module_sp; 1293 static ConstString gDbgPresentStr("gDebuggerPresent"); 1294 const Symbol* debug_present = m_libRS->FindFirstSymbolWithNameAndType(gDbgPresentStr, eSymbolTypeData); 1295 if (debug_present) 1296 { 1297 Error error; 1298 uint32_t flag = 0x00000001U; 1299 Target &target = GetProcess()->GetTarget(); 1300 addr_t addr = debug_present->GetLoadAddress(&target); 1301 GetProcess()->WriteMemory(addr, &flag, sizeof(flag), error); 1302 if(error.Success()) 1303 { 1304 if (log) 1305 log->Printf ("RenderScriptRuntime::LoadModule - Debugger present flag set on debugee"); 1306 1307 m_debuggerPresentFlagged = true; 1308 } 1309 else if (log) 1310 { 1311 log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags '%s' ", error.AsCString()); 1312 } 1313 } 1314 else if (log) 1315 { 1316 log->Printf ("RenderScriptRuntime::LoadModule - Error writing debugger present flags - symbol not found"); 1317 } 1318 } 1319 break; 1320 } 1321 default: 1322 break; 1323 } 1324 if (module_loaded) 1325 Update(); 1326 return module_loaded; 1327 } 1328 return false; 1329 } 1330 1331 void 1332 RenderScriptRuntime::Update() 1333 { 1334 if (m_rsmodules.size() > 0) 1335 { 1336 if (!m_initiated) 1337 { 1338 Initiate(); 1339 } 1340 } 1341 } 1342 1343 1344 // The maximum line length of an .rs.info packet 1345 #define MAXLINE 500 1346 1347 // The .rs.info symbol in renderscript modules contains a string which needs to be parsed. 1348 // The string is basic and is parsed on a line by line basis. 1349 bool 1350 RSModuleDescriptor::ParseRSInfo() 1351 { 1352 const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData); 1353 if (info_sym) 1354 { 1355 const addr_t addr = info_sym->GetAddressRef().GetFileAddress(); 1356 const addr_t size = info_sym->GetByteSize(); 1357 const FileSpec fs = m_module->GetFileSpec(); 1358 1359 DataBufferSP buffer = fs.ReadFileContents(addr, size); 1360 1361 if (!buffer) 1362 return false; 1363 1364 std::string info((const char *)buffer->GetBytes()); 1365 1366 std::vector<std::string> info_lines; 1367 size_t lpos = info.find('\n'); 1368 while (lpos != std::string::npos) 1369 { 1370 info_lines.push_back(info.substr(0, lpos)); 1371 info = info.substr(lpos + 1); 1372 lpos = info.find('\n'); 1373 } 1374 size_t offset = 0; 1375 while (offset < info_lines.size()) 1376 { 1377 std::string line = info_lines[offset]; 1378 // Parse directives 1379 uint32_t numDefns = 0; 1380 if (sscanf(line.c_str(), "exportVarCount: %u", &numDefns) == 1) 1381 { 1382 while (numDefns--) 1383 m_globals.push_back(RSGlobalDescriptor(this, info_lines[++offset].c_str())); 1384 } 1385 else if (sscanf(line.c_str(), "exportFuncCount: %u", &numDefns) == 1) 1386 { 1387 } 1388 else if (sscanf(line.c_str(), "exportForEachCount: %u", &numDefns) == 1) 1389 { 1390 char name[MAXLINE]; 1391 while (numDefns--) 1392 { 1393 uint32_t slot = 0; 1394 name[0] = '\0'; 1395 if (sscanf(info_lines[++offset].c_str(), "%u - %s", &slot, &name[0]) == 2) 1396 { 1397 m_kernels.push_back(RSKernelDescriptor(this, name, slot)); 1398 } 1399 } 1400 } 1401 else if (sscanf(line.c_str(), "pragmaCount: %u", &numDefns) == 1) 1402 { 1403 char name[MAXLINE]; 1404 char value[MAXLINE]; 1405 while (numDefns--) 1406 { 1407 name[0] = '\0'; 1408 value[0] = '\0'; 1409 if (sscanf(info_lines[++offset].c_str(), "%s - %s", &name[0], &value[0]) != 0 1410 && (name[0] != '\0')) 1411 { 1412 m_pragmas[std::string(name)] = value; 1413 } 1414 } 1415 } 1416 else if (sscanf(line.c_str(), "objectSlotCount: %u", &numDefns) == 1) 1417 { 1418 } 1419 1420 offset++; 1421 } 1422 return m_kernels.size() > 0; 1423 } 1424 return false; 1425 } 1426 1427 bool 1428 RenderScriptRuntime::ProbeModules(const ModuleList module_list) 1429 { 1430 bool rs_found = false; 1431 size_t num_modules = module_list.GetSize(); 1432 for (size_t i = 0; i < num_modules; i++) 1433 { 1434 auto module = module_list.GetModuleAtIndex(i); 1435 rs_found |= LoadModule(module); 1436 } 1437 return rs_found; 1438 } 1439 1440 void 1441 RenderScriptRuntime::Status(Stream &strm) const 1442 { 1443 if (m_libRS) 1444 { 1445 strm.Printf("Runtime Library discovered."); 1446 strm.EOL(); 1447 } 1448 if (m_libRSDriver) 1449 { 1450 strm.Printf("Runtime Driver discovered."); 1451 strm.EOL(); 1452 } 1453 if (m_libRSCpuRef) 1454 { 1455 strm.Printf("CPU Reference Implementation discovered."); 1456 strm.EOL(); 1457 } 1458 1459 if (m_runtimeHooks.size()) 1460 { 1461 strm.Printf("Runtime functions hooked:"); 1462 strm.EOL(); 1463 for (auto b : m_runtimeHooks) 1464 { 1465 strm.Indent(b.second->defn->name); 1466 strm.EOL(); 1467 } 1468 strm.EOL(); 1469 } 1470 else 1471 { 1472 strm.Printf("Runtime is not hooked."); 1473 strm.EOL(); 1474 } 1475 } 1476 1477 void 1478 RenderScriptRuntime::DumpContexts(Stream &strm) const 1479 { 1480 strm.Printf("Inferred RenderScript Contexts:"); 1481 strm.EOL(); 1482 strm.IndentMore(); 1483 1484 std::map<addr_t, uint64_t> contextReferences; 1485 1486 // Iterate over all of the currently discovered scripts. 1487 // Note: We cant push or pop from m_scripts inside this loop or it may invalidate script. 1488 for (const auto & script : m_scripts) 1489 { 1490 if (!script->context.isValid()) 1491 continue; 1492 lldb::addr_t context = *script->context; 1493 1494 if (contextReferences.find(context) != contextReferences.end()) 1495 { 1496 contextReferences[context]++; 1497 } 1498 else 1499 { 1500 contextReferences[context] = 1; 1501 } 1502 } 1503 1504 for (const auto& cRef : contextReferences) 1505 { 1506 strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances", cRef.first, cRef.second); 1507 strm.EOL(); 1508 } 1509 strm.IndentLess(); 1510 } 1511 1512 void 1513 RenderScriptRuntime::DumpKernels(Stream &strm) const 1514 { 1515 strm.Printf("RenderScript Kernels:"); 1516 strm.EOL(); 1517 strm.IndentMore(); 1518 for (const auto &module : m_rsmodules) 1519 { 1520 strm.Printf("Resource '%s':",module->m_resname.c_str()); 1521 strm.EOL(); 1522 for (const auto &kernel : module->m_kernels) 1523 { 1524 strm.Indent(kernel.m_name.AsCString()); 1525 strm.EOL(); 1526 } 1527 } 1528 strm.IndentLess(); 1529 } 1530 1531 // Prints infomation regarding all the currently loaded allocations. 1532 // These details are gathered by jitting the runtime, which has as latency. 1533 void 1534 RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame* frame_ptr, bool recompute) 1535 { 1536 strm.Printf("RenderScript Allocations:"); 1537 strm.EOL(); 1538 strm.IndentMore(); 1539 1540 for (auto &alloc : m_allocations) 1541 { 1542 // JIT the allocation info if we haven't done it, or the user forces us to. 1543 bool do_refresh = !alloc->data_ptr.isValid() || recompute; 1544 1545 // JIT current allocation information 1546 if (do_refresh && !RefreshAllocation(alloc.get(), frame_ptr)) 1547 { 1548 strm.Printf("Error: Couldn't evaluate details for allocation %u\n", alloc->id); 1549 continue; 1550 } 1551 1552 strm.Printf("%u:\n",alloc->id); 1553 strm.IndentMore(); 1554 1555 strm.Indent("Context: "); 1556 if (!alloc->context.isValid()) 1557 strm.Printf("unknown\n"); 1558 else 1559 strm.Printf("0x%" PRIx64 "\n", *alloc->context.get()); 1560 1561 strm.Indent("Address: "); 1562 if (!alloc->address.isValid()) 1563 strm.Printf("unknown\n"); 1564 else 1565 strm.Printf("0x%" PRIx64 "\n", *alloc->address.get()); 1566 1567 strm.Indent("Data pointer: "); 1568 if (!alloc->data_ptr.isValid()) 1569 strm.Printf("unknown\n"); 1570 else 1571 strm.Printf("0x%" PRIx64 "\n", *alloc->data_ptr.get()); 1572 1573 strm.Indent("Dimensions: "); 1574 if (!alloc->dimension.isValid()) 1575 strm.Printf("unknown\n"); 1576 else 1577 strm.Printf("(%d, %d, %d)\n", alloc->dimension.get()->dim_1, 1578 alloc->dimension.get()->dim_2, 1579 alloc->dimension.get()->dim_3); 1580 1581 strm.Indent("Data Type: "); 1582 if (!alloc->type.isValid() || !alloc->type_vec_size.isValid()) 1583 strm.Printf("unknown\n"); 1584 else 1585 { 1586 const int vector_size = *alloc->type_vec_size.get(); 1587 const AllocationDetails::DataType type = *alloc->type.get(); 1588 1589 if (vector_size > 4 || vector_size < 1 || 1590 type < AllocationDetails::RS_TYPE_NONE || type > AllocationDetails::RS_TYPE_BOOLEAN) 1591 strm.Printf("invalid type\n"); 1592 else 1593 strm.Printf("%s\n", AllocationDetails::RsDataTypeToString[static_cast<unsigned int>(type)][vector_size-1]); 1594 } 1595 1596 strm.Indent("Data Kind: "); 1597 if (!alloc->type_kind.isValid()) 1598 strm.Printf("unknown\n"); 1599 else 1600 { 1601 const AllocationDetails::DataKind kind = *alloc->type_kind.get(); 1602 if (kind < AllocationDetails::RS_KIND_USER || kind > AllocationDetails::RS_KIND_PIXEL_YUV) 1603 strm.Printf("invalid kind\n"); 1604 else 1605 strm.Printf("%s\n", AllocationDetails::RsDataKindToString[static_cast<unsigned int>(kind)]); 1606 } 1607 1608 strm.EOL(); 1609 strm.IndentLess(); 1610 } 1611 strm.IndentLess(); 1612 } 1613 1614 // Set breakpoints on every kernel found in RS module 1615 void 1616 RenderScriptRuntime::BreakOnModuleKernels(const RSModuleDescriptorSP rsmodule_sp) 1617 { 1618 for (const auto &kernel : rsmodule_sp->m_kernels) 1619 { 1620 // Don't set breakpoint on 'root' kernel 1621 if (strcmp(kernel.m_name.AsCString(), "root") == 0) 1622 continue; 1623 1624 CreateKernelBreakpoint(kernel.m_name); 1625 } 1626 } 1627 1628 // Method is internally called by the 'kernel breakpoint all' command to 1629 // enable or disable breaking on all kernels. 1630 // 1631 // When do_break is true we want to enable this functionality. 1632 // When do_break is false we want to disable it. 1633 void 1634 RenderScriptRuntime::SetBreakAllKernels(bool do_break, TargetSP target) 1635 { 1636 Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS)); 1637 1638 InitSearchFilter(target); 1639 1640 // Set breakpoints on all the kernels 1641 if (do_break && !m_breakAllKernels) 1642 { 1643 m_breakAllKernels = true; 1644 1645 for (const auto &module : m_rsmodules) 1646 BreakOnModuleKernels(module); 1647 1648 if (log) 1649 log->Printf("RenderScriptRuntime::SetBreakAllKernels(True)" 1650 "- breakpoints set on all currently loaded kernels"); 1651 } 1652 else if (!do_break && m_breakAllKernels) // Breakpoints won't be set on any new kernels. 1653 { 1654 m_breakAllKernels = false; 1655 1656 if (log) 1657 log->Printf("RenderScriptRuntime::SetBreakAllKernels(False) - breakpoints no longer automatically set"); 1658 } 1659 } 1660 1661 // Given the name of a kernel this function creates a breakpoint using our 1662 // own breakpoint resolver, and returns the Breakpoint shared pointer. 1663 BreakpointSP 1664 RenderScriptRuntime::CreateKernelBreakpoint(const ConstString& name) 1665 { 1666 Log* log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_BREAKPOINTS)); 1667 1668 if (!m_filtersp) 1669 { 1670 if (log) 1671 log->Printf("RenderScriptRuntime::CreateKernelBreakpoint - Error: No breakpoint search filter set"); 1672 return nullptr; 1673 } 1674 1675 BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name)); 1676 BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(m_filtersp, resolver_sp, false, false, false); 1677 1678 // Give RS breakpoints a specific name, so the user can manipulate them as a group. 1679 Error err; 1680 if (!bp->AddName("RenderScriptKernel", err) && log) 1681 log->Printf("RenderScriptRuntime::CreateKernelBreakpoint: Error setting break name, %s", err.AsCString()); 1682 1683 return bp; 1684 } 1685 1686 void 1687 RenderScriptRuntime::AttemptBreakpointAtKernelName(Stream &strm, const char* name, Error& error, TargetSP target) 1688 { 1689 if (!name) 1690 { 1691 error.SetErrorString("invalid kernel name"); 1692 return; 1693 } 1694 1695 InitSearchFilter(target); 1696 1697 ConstString kernel_name(name); 1698 BreakpointSP bp = CreateKernelBreakpoint(kernel_name); 1699 if (bp) 1700 bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false); 1701 1702 return; 1703 } 1704 1705 void 1706 RenderScriptRuntime::DumpModules(Stream &strm) const 1707 { 1708 strm.Printf("RenderScript Modules:"); 1709 strm.EOL(); 1710 strm.IndentMore(); 1711 for (const auto &module : m_rsmodules) 1712 { 1713 module->Dump(strm); 1714 } 1715 strm.IndentLess(); 1716 } 1717 1718 RenderScriptRuntime::ScriptDetails* 1719 RenderScriptRuntime::LookUpScript(addr_t address, bool create) 1720 { 1721 for (const auto & s : m_scripts) 1722 { 1723 if (s->script.isValid()) 1724 if (*s->script == address) 1725 return s.get(); 1726 } 1727 if (create) 1728 { 1729 std::unique_ptr<ScriptDetails> s(new ScriptDetails); 1730 s->script = address; 1731 m_scripts.push_back(std::move(s)); 1732 return m_scripts.back().get(); 1733 } 1734 return nullptr; 1735 } 1736 1737 RenderScriptRuntime::AllocationDetails* 1738 RenderScriptRuntime::LookUpAllocation(addr_t address, bool create) 1739 { 1740 for (const auto & a : m_allocations) 1741 { 1742 if (a->address.isValid()) 1743 if (*a->address == address) 1744 return a.get(); 1745 } 1746 if (create) 1747 { 1748 std::unique_ptr<AllocationDetails> a(new AllocationDetails); 1749 a->address = address; 1750 m_allocations.push_back(std::move(a)); 1751 return m_allocations.back().get(); 1752 } 1753 return nullptr; 1754 } 1755 1756 void 1757 RSModuleDescriptor::Dump(Stream &strm) const 1758 { 1759 strm.Indent(); 1760 m_module->GetFileSpec().Dump(&strm); 1761 if(m_module->GetNumCompileUnits()) 1762 { 1763 strm.Indent("Debug info loaded."); 1764 } 1765 else 1766 { 1767 strm.Indent("Debug info does not exist."); 1768 } 1769 strm.EOL(); 1770 strm.IndentMore(); 1771 strm.Indent(); 1772 strm.Printf("Globals: %" PRIu64, static_cast<uint64_t>(m_globals.size())); 1773 strm.EOL(); 1774 strm.IndentMore(); 1775 for (const auto &global : m_globals) 1776 { 1777 global.Dump(strm); 1778 } 1779 strm.IndentLess(); 1780 strm.Indent(); 1781 strm.Printf("Kernels: %" PRIu64, static_cast<uint64_t>(m_kernels.size())); 1782 strm.EOL(); 1783 strm.IndentMore(); 1784 for (const auto &kernel : m_kernels) 1785 { 1786 kernel.Dump(strm); 1787 } 1788 strm.Printf("Pragmas: %" PRIu64 , static_cast<uint64_t>(m_pragmas.size())); 1789 strm.EOL(); 1790 strm.IndentMore(); 1791 for (const auto &key_val : m_pragmas) 1792 { 1793 strm.Printf("%s: %s", key_val.first.c_str(), key_val.second.c_str()); 1794 strm.EOL(); 1795 } 1796 strm.IndentLess(4); 1797 } 1798 1799 void 1800 RSGlobalDescriptor::Dump(Stream &strm) const 1801 { 1802 strm.Indent(m_name.AsCString()); 1803 VariableList var_list; 1804 m_module->m_module->FindGlobalVariables(m_name, nullptr, true, 1U, var_list); 1805 if (var_list.GetSize() == 1) 1806 { 1807 auto var = var_list.GetVariableAtIndex(0); 1808 auto type = var->GetType(); 1809 if(type) 1810 { 1811 strm.Printf(" - "); 1812 type->DumpTypeName(&strm); 1813 } 1814 else 1815 { 1816 strm.Printf(" - Unknown Type"); 1817 } 1818 } 1819 else 1820 { 1821 strm.Printf(" - variable identified, but not found in binary"); 1822 const Symbol* s = m_module->m_module->FindFirstSymbolWithNameAndType(m_name, eSymbolTypeData); 1823 if (s) 1824 { 1825 strm.Printf(" (symbol exists) "); 1826 } 1827 } 1828 1829 strm.EOL(); 1830 } 1831 1832 void 1833 RSKernelDescriptor::Dump(Stream &strm) const 1834 { 1835 strm.Indent(m_name.AsCString()); 1836 strm.EOL(); 1837 } 1838 1839 class CommandObjectRenderScriptRuntimeModuleProbe : public CommandObjectParsed 1840 { 1841 private: 1842 public: 1843 CommandObjectRenderScriptRuntimeModuleProbe(CommandInterpreter &interpreter) 1844 : CommandObjectParsed(interpreter, "renderscript module probe", 1845 "Initiates a Probe of all loaded modules for kernels and other renderscript objects.", 1846 "renderscript module probe", 1847 eCommandRequiresTarget | eCommandRequiresProcess | eCommandProcessMustBeLaunched) 1848 { 1849 } 1850 1851 ~CommandObjectRenderScriptRuntimeModuleProbe() {} 1852 1853 bool 1854 DoExecute(Args &command, CommandReturnObject &result) 1855 { 1856 const size_t argc = command.GetArgumentCount(); 1857 if (argc == 0) 1858 { 1859 Target *target = m_exe_ctx.GetTargetPtr(); 1860 RenderScriptRuntime *runtime = 1861 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 1862 auto module_list = target->GetImages(); 1863 bool new_rs_details = runtime->ProbeModules(module_list); 1864 if (new_rs_details) 1865 { 1866 result.AppendMessage("New renderscript modules added to runtime model."); 1867 } 1868 result.SetStatus(eReturnStatusSuccessFinishResult); 1869 return true; 1870 } 1871 1872 result.AppendErrorWithFormat("'%s' takes no arguments", m_cmd_name.c_str()); 1873 result.SetStatus(eReturnStatusFailed); 1874 return false; 1875 } 1876 }; 1877 1878 class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed 1879 { 1880 private: 1881 public: 1882 CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter) 1883 : CommandObjectParsed(interpreter, "renderscript module dump", 1884 "Dumps renderscript specific information for all modules.", "renderscript module dump", 1885 eCommandRequiresProcess | eCommandProcessMustBeLaunched) 1886 { 1887 } 1888 1889 ~CommandObjectRenderScriptRuntimeModuleDump() {} 1890 1891 bool 1892 DoExecute(Args &command, CommandReturnObject &result) 1893 { 1894 RenderScriptRuntime *runtime = 1895 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 1896 runtime->DumpModules(result.GetOutputStream()); 1897 result.SetStatus(eReturnStatusSuccessFinishResult); 1898 return true; 1899 } 1900 }; 1901 1902 class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword 1903 { 1904 private: 1905 public: 1906 CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter) 1907 : CommandObjectMultiword(interpreter, "renderscript module", "Commands that deal with renderscript modules.", 1908 NULL) 1909 { 1910 LoadSubCommand("probe", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleProbe(interpreter))); 1911 LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump(interpreter))); 1912 } 1913 1914 ~CommandObjectRenderScriptRuntimeModule() {} 1915 }; 1916 1917 class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed 1918 { 1919 private: 1920 public: 1921 CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter) 1922 : CommandObjectParsed(interpreter, "renderscript kernel list", 1923 "Lists renderscript kernel names and associated script resources.", "renderscript kernel list", 1924 eCommandRequiresProcess | eCommandProcessMustBeLaunched) 1925 { 1926 } 1927 1928 ~CommandObjectRenderScriptRuntimeKernelList() {} 1929 1930 bool 1931 DoExecute(Args &command, CommandReturnObject &result) 1932 { 1933 RenderScriptRuntime *runtime = 1934 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 1935 runtime->DumpKernels(result.GetOutputStream()); 1936 result.SetStatus(eReturnStatusSuccessFinishResult); 1937 return true; 1938 } 1939 }; 1940 1941 class CommandObjectRenderScriptRuntimeKernelBreakpointSet : public CommandObjectParsed 1942 { 1943 private: 1944 public: 1945 CommandObjectRenderScriptRuntimeKernelBreakpointSet(CommandInterpreter &interpreter) 1946 : CommandObjectParsed(interpreter, "renderscript kernel breakpoint set", 1947 "Sets a breakpoint on a renderscript kernel.", "renderscript kernel breakpoint set <kernel_name>", 1948 eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) 1949 { 1950 } 1951 1952 ~CommandObjectRenderScriptRuntimeKernelBreakpointSet() {} 1953 1954 bool 1955 DoExecute(Args &command, CommandReturnObject &result) 1956 { 1957 const size_t argc = command.GetArgumentCount(); 1958 if (argc == 1) 1959 { 1960 RenderScriptRuntime *runtime = 1961 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 1962 1963 Error error; 1964 runtime->AttemptBreakpointAtKernelName(result.GetOutputStream(), command.GetArgumentAtIndex(0), 1965 error, m_exe_ctx.GetTargetSP()); 1966 1967 if (error.Success()) 1968 { 1969 result.AppendMessage("Breakpoint(s) created"); 1970 result.SetStatus(eReturnStatusSuccessFinishResult); 1971 return true; 1972 } 1973 result.SetStatus(eReturnStatusFailed); 1974 result.AppendErrorWithFormat("Error: %s", error.AsCString()); 1975 return false; 1976 } 1977 1978 result.AppendErrorWithFormat("'%s' takes 1 argument of kernel name", m_cmd_name.c_str()); 1979 result.SetStatus(eReturnStatusFailed); 1980 return false; 1981 } 1982 }; 1983 1984 class CommandObjectRenderScriptRuntimeKernelBreakpointAll : public CommandObjectParsed 1985 { 1986 private: 1987 public: 1988 CommandObjectRenderScriptRuntimeKernelBreakpointAll(CommandInterpreter &interpreter) 1989 : CommandObjectParsed(interpreter, "renderscript kernel breakpoint all", 1990 "Automatically sets a breakpoint on all renderscript kernels that are or will be loaded.\n" 1991 "Disabling option means breakpoints will no longer be set on any kernels loaded in the future, " 1992 "but does not remove currently set breakpoints.", 1993 "renderscript kernel breakpoint all <enable/disable>", 1994 eCommandRequiresProcess | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) 1995 { 1996 } 1997 1998 ~CommandObjectRenderScriptRuntimeKernelBreakpointAll() {} 1999 2000 bool 2001 DoExecute(Args &command, CommandReturnObject &result) 2002 { 2003 const size_t argc = command.GetArgumentCount(); 2004 if (argc != 1) 2005 { 2006 result.AppendErrorWithFormat("'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str()); 2007 result.SetStatus(eReturnStatusFailed); 2008 return false; 2009 } 2010 2011 RenderScriptRuntime *runtime = 2012 static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript)); 2013 2014 bool do_break = false; 2015 const char* argument = command.GetArgumentAtIndex(0); 2016 if (strcmp(argument, "enable") == 0) 2017 { 2018 do_break = true; 2019 result.AppendMessage("Breakpoints will be set on all kernels."); 2020 } 2021 else if (strcmp(argument, "disable") == 0) 2022 { 2023 do_break = false; 2024 result.AppendMessage("Breakpoints will not be set on any new kernels."); 2025 } 2026 else 2027 { 2028 result.AppendErrorWithFormat("Argument must be either 'enable' or 'disable'"); 2029 result.SetStatus(eReturnStatusFailed); 2030 return false; 2031 } 2032 2033 runtime->SetBreakAllKernels(do_break, m_exe_ctx.GetTargetSP()); 2034 2035 result.SetStatus(eReturnStatusSuccessFinishResult); 2036 return true; 2037 } 2038 }; 2039 2040 class CommandObjectRenderScriptRuntimeKernelBreakpoint : public CommandObjectMultiword 2041 { 2042 private: 2043 public: 2044 CommandObjectRenderScriptRuntimeKernelBreakpoint(CommandInterpreter &interpreter) 2045 : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that generate breakpoints on renderscript kernels.", 2046 nullptr) 2047 { 2048 LoadSubCommand("set", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointSet(interpreter))); 2049 LoadSubCommand("all", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointAll(interpreter))); 2050 } 2051 2052 ~CommandObjectRenderScriptRuntimeKernelBreakpoint() {} 2053 }; 2054 2055 class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword 2056 { 2057 private: 2058 public: 2059 CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter) 2060 : CommandObjectMultiword(interpreter, "renderscript kernel", "Commands that deal with renderscript kernels.", 2061 NULL) 2062 { 2063 LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList(interpreter))); 2064 LoadSubCommand("breakpoint", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter))); 2065 } 2066 2067 ~CommandObjectRenderScriptRuntimeKernel() {} 2068 }; 2069 2070 class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed 2071 { 2072 private: 2073 public: 2074 CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter) 2075 : CommandObjectParsed(interpreter, "renderscript context dump", 2076 "Dumps renderscript context information.", "renderscript context dump", 2077 eCommandRequiresProcess | eCommandProcessMustBeLaunched) 2078 { 2079 } 2080 2081 ~CommandObjectRenderScriptRuntimeContextDump() {} 2082 2083 bool 2084 DoExecute(Args &command, CommandReturnObject &result) 2085 { 2086 RenderScriptRuntime *runtime = 2087 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 2088 runtime->DumpContexts(result.GetOutputStream()); 2089 result.SetStatus(eReturnStatusSuccessFinishResult); 2090 return true; 2091 } 2092 }; 2093 2094 class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword 2095 { 2096 private: 2097 public: 2098 CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter) 2099 : CommandObjectMultiword(interpreter, "renderscript context", "Commands that deal with renderscript contexts.", 2100 NULL) 2101 { 2102 LoadSubCommand("dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump(interpreter))); 2103 } 2104 2105 ~CommandObjectRenderScriptRuntimeContext() {} 2106 }; 2107 2108 class CommandObjectRenderScriptRuntimeAllocationList : public CommandObjectParsed 2109 { 2110 public: 2111 CommandObjectRenderScriptRuntimeAllocationList(CommandInterpreter &interpreter) 2112 : CommandObjectParsed(interpreter, "renderscript allocation list", 2113 "List renderscript allocations and their information.", "renderscript allocation list", 2114 eCommandRequiresProcess | eCommandProcessMustBeLaunched), m_options(interpreter) 2115 { 2116 } 2117 2118 virtual Options* 2119 GetOptions() 2120 { 2121 return &m_options; 2122 } 2123 2124 class CommandOptions : public Options 2125 { 2126 public: 2127 CommandOptions(CommandInterpreter &interpreter) : Options(interpreter), m_refresh(false) 2128 { 2129 } 2130 2131 virtual 2132 ~CommandOptions() 2133 { 2134 } 2135 2136 virtual Error 2137 SetOptionValue(uint32_t option_idx, const char *option_arg) 2138 { 2139 Error error; 2140 const int short_option = m_getopt_table[option_idx].val; 2141 2142 switch (short_option) 2143 { 2144 case 'r': 2145 m_refresh = true; 2146 break; 2147 default: 2148 error.SetErrorStringWithFormat("unrecognized option '%c'", short_option); 2149 break; 2150 } 2151 return error; 2152 } 2153 2154 void 2155 OptionParsingStarting() 2156 { 2157 m_refresh = false; 2158 } 2159 2160 const OptionDefinition* 2161 GetDefinitions() 2162 { 2163 return g_option_table; 2164 } 2165 2166 static OptionDefinition g_option_table[]; 2167 bool m_refresh; 2168 }; 2169 2170 ~CommandObjectRenderScriptRuntimeAllocationList() {} 2171 2172 bool 2173 DoExecute(Args &command, CommandReturnObject &result) 2174 { 2175 RenderScriptRuntime *runtime = 2176 static_cast<RenderScriptRuntime *>(m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript)); 2177 runtime->ListAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr(), m_options.m_refresh); 2178 result.SetStatus(eReturnStatusSuccessFinishResult); 2179 return true; 2180 } 2181 2182 private: 2183 CommandOptions m_options; 2184 }; 2185 2186 OptionDefinition 2187 CommandObjectRenderScriptRuntimeAllocationList::CommandOptions::g_option_table[] = 2188 { 2189 { LLDB_OPT_SET_1, false, "refresh", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, 2190 "Recompute allocation details."}, 2191 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 2192 }; 2193 2194 2195 class CommandObjectRenderScriptRuntimeAllocation : public CommandObjectMultiword 2196 { 2197 private: 2198 public: 2199 CommandObjectRenderScriptRuntimeAllocation(CommandInterpreter &interpreter) 2200 : CommandObjectMultiword(interpreter, "renderscript allocation", "Commands that deal with renderscript allocations.", 2201 NULL) 2202 { 2203 LoadSubCommand("list", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationList(interpreter))); 2204 } 2205 2206 ~CommandObjectRenderScriptRuntimeAllocation() {} 2207 }; 2208 2209 2210 class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed 2211 { 2212 private: 2213 public: 2214 CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter) 2215 : CommandObjectParsed(interpreter, "renderscript status", 2216 "Displays current renderscript runtime status.", "renderscript status", 2217 eCommandRequiresProcess | eCommandProcessMustBeLaunched) 2218 { 2219 } 2220 2221 ~CommandObjectRenderScriptRuntimeStatus() {} 2222 2223 bool 2224 DoExecute(Args &command, CommandReturnObject &result) 2225 { 2226 RenderScriptRuntime *runtime = 2227 (RenderScriptRuntime *)m_exe_ctx.GetProcessPtr()->GetLanguageRuntime(eLanguageTypeExtRenderScript); 2228 runtime->Status(result.GetOutputStream()); 2229 result.SetStatus(eReturnStatusSuccessFinishResult); 2230 return true; 2231 } 2232 }; 2233 2234 class CommandObjectRenderScriptRuntime : public CommandObjectMultiword 2235 { 2236 public: 2237 CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter) 2238 : CommandObjectMultiword(interpreter, "renderscript", "A set of commands for operating on renderscript.", 2239 "renderscript <subcommand> [<subcommand-options>]") 2240 { 2241 LoadSubCommand("module", CommandObjectSP(new CommandObjectRenderScriptRuntimeModule(interpreter))); 2242 LoadSubCommand("status", CommandObjectSP(new CommandObjectRenderScriptRuntimeStatus(interpreter))); 2243 LoadSubCommand("kernel", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernel(interpreter))); 2244 LoadSubCommand("context", CommandObjectSP(new CommandObjectRenderScriptRuntimeContext(interpreter))); 2245 LoadSubCommand("allocation", CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocation(interpreter))); 2246 } 2247 2248 ~CommandObjectRenderScriptRuntime() {} 2249 }; 2250 2251 void 2252 RenderScriptRuntime::Initiate() 2253 { 2254 assert(!m_initiated); 2255 } 2256 2257 RenderScriptRuntime::RenderScriptRuntime(Process *process) 2258 : lldb_private::CPPLanguageRuntime(process), m_initiated(false), m_debuggerPresentFlagged(false), 2259 m_breakAllKernels(false) 2260 { 2261 ModulesDidLoad(process->GetTarget().GetImages()); 2262 } 2263 2264 lldb::CommandObjectSP 2265 RenderScriptRuntime::GetCommandObject(lldb_private::CommandInterpreter& interpreter) 2266 { 2267 static CommandObjectSP command_object; 2268 if(!command_object) 2269 { 2270 command_object.reset(new CommandObjectRenderScriptRuntime(interpreter)); 2271 } 2272 return command_object; 2273 } 2274 2275 RenderScriptRuntime::~RenderScriptRuntime() = default; 2276