1 //===-- SBModule.cpp --------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/API/SBModule.h" 10 #include "lldb/API/SBAddress.h" 11 #include "lldb/API/SBFileSpec.h" 12 #include "lldb/API/SBModuleSpec.h" 13 #include "lldb/API/SBProcess.h" 14 #include "lldb/API/SBStream.h" 15 #include "lldb/API/SBSymbolContextList.h" 16 #include "lldb/Core/Module.h" 17 #include "lldb/Core/Section.h" 18 #include "lldb/Core/ValueObjectList.h" 19 #include "lldb/Core/ValueObjectVariable.h" 20 #include "lldb/Symbol/ObjectFile.h" 21 #include "lldb/Symbol/SymbolFile.h" 22 #include "lldb/Symbol/SymbolVendor.h" 23 #include "lldb/Symbol/Symtab.h" 24 #include "lldb/Symbol/TypeSystem.h" 25 #include "lldb/Symbol/VariableList.h" 26 #include "lldb/Target/Target.h" 27 #include "lldb/Utility/Log.h" 28 #include "lldb/Utility/StreamString.h" 29 30 using namespace lldb; 31 using namespace lldb_private; 32 33 SBModule::SBModule() : m_opaque_sp() {} 34 35 SBModule::SBModule(const lldb::ModuleSP &module_sp) : m_opaque_sp(module_sp) {} 36 37 SBModule::SBModule(const SBModuleSpec &module_spec) : m_opaque_sp() { 38 ModuleSP module_sp; 39 Status error = ModuleList::GetSharedModule(*module_spec.m_opaque_ap, 40 module_sp, NULL, NULL, NULL); 41 if (module_sp) 42 SetSP(module_sp); 43 } 44 45 SBModule::SBModule(const SBModule &rhs) : m_opaque_sp(rhs.m_opaque_sp) {} 46 47 SBModule::SBModule(lldb::SBProcess &process, lldb::addr_t header_addr) 48 : m_opaque_sp() { 49 ProcessSP process_sp(process.GetSP()); 50 if (process_sp) { 51 m_opaque_sp = process_sp->ReadModuleFromMemory(FileSpec(), header_addr); 52 if (m_opaque_sp) { 53 Target &target = process_sp->GetTarget(); 54 bool changed = false; 55 m_opaque_sp->SetLoadAddress(target, 0, true, changed); 56 target.GetImages().Append(m_opaque_sp); 57 } 58 } 59 } 60 61 const SBModule &SBModule::operator=(const SBModule &rhs) { 62 if (this != &rhs) 63 m_opaque_sp = rhs.m_opaque_sp; 64 return *this; 65 } 66 67 SBModule::~SBModule() {} 68 69 bool SBModule::IsValid() const { return m_opaque_sp.get() != NULL; } 70 71 void SBModule::Clear() { m_opaque_sp.reset(); } 72 73 SBFileSpec SBModule::GetFileSpec() const { 74 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 75 76 SBFileSpec file_spec; 77 ModuleSP module_sp(GetSP()); 78 if (module_sp) 79 file_spec.SetFileSpec(module_sp->GetFileSpec()); 80 81 if (log) 82 log->Printf("SBModule(%p)::GetFileSpec () => SBFileSpec(%p)", 83 static_cast<void *>(module_sp.get()), 84 static_cast<const void *>(file_spec.get())); 85 86 return file_spec; 87 } 88 89 lldb::SBFileSpec SBModule::GetPlatformFileSpec() const { 90 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 91 92 SBFileSpec file_spec; 93 ModuleSP module_sp(GetSP()); 94 if (module_sp) 95 file_spec.SetFileSpec(module_sp->GetPlatformFileSpec()); 96 97 if (log) 98 log->Printf("SBModule(%p)::GetPlatformFileSpec () => SBFileSpec(%p)", 99 static_cast<void *>(module_sp.get()), 100 static_cast<const void *>(file_spec.get())); 101 102 return file_spec; 103 } 104 105 bool SBModule::SetPlatformFileSpec(const lldb::SBFileSpec &platform_file) { 106 bool result = false; 107 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 108 109 ModuleSP module_sp(GetSP()); 110 if (module_sp) { 111 module_sp->SetPlatformFileSpec(*platform_file); 112 result = true; 113 } 114 115 if (log) 116 log->Printf("SBModule(%p)::SetPlatformFileSpec (SBFileSpec(%p (%s)) => %i", 117 static_cast<void *>(module_sp.get()), 118 static_cast<const void *>(platform_file.get()), 119 platform_file->GetPath().c_str(), result); 120 return result; 121 } 122 123 lldb::SBFileSpec SBModule::GetRemoteInstallFileSpec() { 124 SBFileSpec sb_file_spec; 125 ModuleSP module_sp(GetSP()); 126 if (module_sp) 127 sb_file_spec.SetFileSpec(module_sp->GetRemoteInstallFileSpec()); 128 return sb_file_spec; 129 } 130 131 bool SBModule::SetRemoteInstallFileSpec(lldb::SBFileSpec &file) { 132 ModuleSP module_sp(GetSP()); 133 if (module_sp) { 134 module_sp->SetRemoteInstallFileSpec(file.ref()); 135 return true; 136 } 137 return false; 138 } 139 140 const uint8_t *SBModule::GetUUIDBytes() const { 141 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 142 143 const uint8_t *uuid_bytes = NULL; 144 ModuleSP module_sp(GetSP()); 145 if (module_sp) 146 uuid_bytes = module_sp->GetUUID().GetBytes().data(); 147 148 if (log) { 149 if (uuid_bytes) { 150 StreamString s; 151 module_sp->GetUUID().Dump(&s); 152 log->Printf("SBModule(%p)::GetUUIDBytes () => %s", 153 static_cast<void *>(module_sp.get()), s.GetData()); 154 } else 155 log->Printf("SBModule(%p)::GetUUIDBytes () => NULL", 156 static_cast<void *>(module_sp.get())); 157 } 158 return uuid_bytes; 159 } 160 161 const char *SBModule::GetUUIDString() const { 162 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 163 164 const char *uuid_cstr = NULL; 165 ModuleSP module_sp(GetSP()); 166 if (module_sp) { 167 // We are going to return a "const char *" value through the public API, so 168 // we need to constify it so it gets added permanently the string pool and 169 // then we don't need to worry about the lifetime of the string as it will 170 // never go away once it has been put into the ConstString string pool 171 uuid_cstr = ConstString(module_sp->GetUUID().GetAsString()).GetCString(); 172 } 173 174 if (uuid_cstr && uuid_cstr[0]) { 175 if (log) 176 log->Printf("SBModule(%p)::GetUUIDString () => %s", 177 static_cast<void *>(module_sp.get()), uuid_cstr); 178 return uuid_cstr; 179 } 180 181 if (log) 182 log->Printf("SBModule(%p)::GetUUIDString () => NULL", 183 static_cast<void *>(module_sp.get())); 184 return NULL; 185 } 186 187 bool SBModule::operator==(const SBModule &rhs) const { 188 if (m_opaque_sp) 189 return m_opaque_sp.get() == rhs.m_opaque_sp.get(); 190 return false; 191 } 192 193 bool SBModule::operator!=(const SBModule &rhs) const { 194 if (m_opaque_sp) 195 return m_opaque_sp.get() != rhs.m_opaque_sp.get(); 196 return false; 197 } 198 199 ModuleSP SBModule::GetSP() const { return m_opaque_sp; } 200 201 void SBModule::SetSP(const ModuleSP &module_sp) { m_opaque_sp = module_sp; } 202 203 SBAddress SBModule::ResolveFileAddress(lldb::addr_t vm_addr) { 204 lldb::SBAddress sb_addr; 205 ModuleSP module_sp(GetSP()); 206 if (module_sp) { 207 Address addr; 208 if (module_sp->ResolveFileAddress(vm_addr, addr)) 209 sb_addr.ref() = addr; 210 } 211 return sb_addr; 212 } 213 214 SBSymbolContext 215 SBModule::ResolveSymbolContextForAddress(const SBAddress &addr, 216 uint32_t resolve_scope) { 217 SBSymbolContext sb_sc; 218 ModuleSP module_sp(GetSP()); 219 SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope); 220 if (module_sp && addr.IsValid()) 221 module_sp->ResolveSymbolContextForAddress(addr.ref(), scope, *sb_sc); 222 return sb_sc; 223 } 224 225 bool SBModule::GetDescription(SBStream &description) { 226 Stream &strm = description.ref(); 227 228 ModuleSP module_sp(GetSP()); 229 if (module_sp) { 230 module_sp->GetDescription(&strm); 231 } else 232 strm.PutCString("No value"); 233 234 return true; 235 } 236 237 uint32_t SBModule::GetNumCompileUnits() { 238 ModuleSP module_sp(GetSP()); 239 if (module_sp) { 240 return module_sp->GetNumCompileUnits(); 241 } 242 return 0; 243 } 244 245 SBCompileUnit SBModule::GetCompileUnitAtIndex(uint32_t index) { 246 SBCompileUnit sb_cu; 247 ModuleSP module_sp(GetSP()); 248 if (module_sp) { 249 CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(index); 250 sb_cu.reset(cu_sp.get()); 251 } 252 return sb_cu; 253 } 254 255 SBSymbolContextList 256 SBModule::FindCompileUnits(const SBFileSpec &sb_file_spec) { 257 SBSymbolContextList sb_sc_list; 258 const ModuleSP module_sp(GetSP()); 259 if (sb_file_spec.IsValid() && module_sp) { 260 const bool append = true; 261 module_sp->FindCompileUnits(*sb_file_spec, append, *sb_sc_list); 262 } 263 return sb_sc_list; 264 } 265 266 static Symtab *GetUnifiedSymbolTable(const lldb::ModuleSP &module_sp) { 267 if (module_sp) { 268 SymbolVendor *symbols = module_sp->GetSymbolVendor(); 269 if (symbols) 270 return symbols->GetSymtab(); 271 } 272 return NULL; 273 } 274 275 size_t SBModule::GetNumSymbols() { 276 ModuleSP module_sp(GetSP()); 277 if (module_sp) { 278 Symtab *symtab = GetUnifiedSymbolTable(module_sp); 279 if (symtab) 280 return symtab->GetNumSymbols(); 281 } 282 return 0; 283 } 284 285 SBSymbol SBModule::GetSymbolAtIndex(size_t idx) { 286 SBSymbol sb_symbol; 287 ModuleSP module_sp(GetSP()); 288 Symtab *symtab = GetUnifiedSymbolTable(module_sp); 289 if (symtab) 290 sb_symbol.SetSymbol(symtab->SymbolAtIndex(idx)); 291 return sb_symbol; 292 } 293 294 lldb::SBSymbol SBModule::FindSymbol(const char *name, 295 lldb::SymbolType symbol_type) { 296 SBSymbol sb_symbol; 297 if (name && name[0]) { 298 ModuleSP module_sp(GetSP()); 299 Symtab *symtab = GetUnifiedSymbolTable(module_sp); 300 if (symtab) 301 sb_symbol.SetSymbol(symtab->FindFirstSymbolWithNameAndType( 302 ConstString(name), symbol_type, Symtab::eDebugAny, 303 Symtab::eVisibilityAny)); 304 } 305 return sb_symbol; 306 } 307 308 lldb::SBSymbolContextList SBModule::FindSymbols(const char *name, 309 lldb::SymbolType symbol_type) { 310 SBSymbolContextList sb_sc_list; 311 if (name && name[0]) { 312 ModuleSP module_sp(GetSP()); 313 Symtab *symtab = GetUnifiedSymbolTable(module_sp); 314 if (symtab) { 315 std::vector<uint32_t> matching_symbol_indexes; 316 const size_t num_matches = symtab->FindAllSymbolsWithNameAndType( 317 ConstString(name), symbol_type, matching_symbol_indexes); 318 if (num_matches) { 319 SymbolContext sc; 320 sc.module_sp = module_sp; 321 SymbolContextList &sc_list = *sb_sc_list; 322 for (size_t i = 0; i < num_matches; ++i) { 323 sc.symbol = symtab->SymbolAtIndex(matching_symbol_indexes[i]); 324 if (sc.symbol) 325 sc_list.Append(sc); 326 } 327 } 328 } 329 } 330 return sb_sc_list; 331 } 332 333 size_t SBModule::GetNumSections() { 334 ModuleSP module_sp(GetSP()); 335 if (module_sp) { 336 // Give the symbol vendor a chance to add to the unified section list. 337 module_sp->GetSymbolVendor(); 338 SectionList *section_list = module_sp->GetSectionList(); 339 if (section_list) 340 return section_list->GetSize(); 341 } 342 return 0; 343 } 344 345 SBSection SBModule::GetSectionAtIndex(size_t idx) { 346 SBSection sb_section; 347 ModuleSP module_sp(GetSP()); 348 if (module_sp) { 349 // Give the symbol vendor a chance to add to the unified section list. 350 module_sp->GetSymbolVendor(); 351 SectionList *section_list = module_sp->GetSectionList(); 352 353 if (section_list) 354 sb_section.SetSP(section_list->GetSectionAtIndex(idx)); 355 } 356 return sb_section; 357 } 358 359 lldb::SBSymbolContextList SBModule::FindFunctions(const char *name, 360 uint32_t name_type_mask) { 361 lldb::SBSymbolContextList sb_sc_list; 362 ModuleSP module_sp(GetSP()); 363 if (name && module_sp) { 364 const bool append = true; 365 const bool symbols_ok = true; 366 const bool inlines_ok = true; 367 FunctionNameType type = static_cast<FunctionNameType>(name_type_mask); 368 module_sp->FindFunctions(ConstString(name), NULL, type, symbols_ok, 369 inlines_ok, append, *sb_sc_list); 370 } 371 return sb_sc_list; 372 } 373 374 SBValueList SBModule::FindGlobalVariables(SBTarget &target, const char *name, 375 uint32_t max_matches) { 376 SBValueList sb_value_list; 377 ModuleSP module_sp(GetSP()); 378 if (name && module_sp) { 379 VariableList variable_list; 380 const uint32_t match_count = module_sp->FindGlobalVariables( 381 ConstString(name), NULL, max_matches, variable_list); 382 383 if (match_count > 0) { 384 for (uint32_t i = 0; i < match_count; ++i) { 385 lldb::ValueObjectSP valobj_sp; 386 TargetSP target_sp(target.GetSP()); 387 valobj_sp = ValueObjectVariable::Create( 388 target_sp.get(), variable_list.GetVariableAtIndex(i)); 389 if (valobj_sp) 390 sb_value_list.Append(SBValue(valobj_sp)); 391 } 392 } 393 } 394 395 return sb_value_list; 396 } 397 398 lldb::SBValue SBModule::FindFirstGlobalVariable(lldb::SBTarget &target, 399 const char *name) { 400 SBValueList sb_value_list(FindGlobalVariables(target, name, 1)); 401 if (sb_value_list.IsValid() && sb_value_list.GetSize() > 0) 402 return sb_value_list.GetValueAtIndex(0); 403 return SBValue(); 404 } 405 406 lldb::SBType SBModule::FindFirstType(const char *name_cstr) { 407 SBType sb_type; 408 ModuleSP module_sp(GetSP()); 409 if (name_cstr && module_sp) { 410 SymbolContext sc; 411 const bool exact_match = false; 412 ConstString name(name_cstr); 413 414 sb_type = SBType(module_sp->FindFirstType(sc, name, exact_match)); 415 416 if (!sb_type.IsValid()) { 417 TypeSystem *type_system = 418 module_sp->GetTypeSystemForLanguage(eLanguageTypeC); 419 if (type_system) 420 sb_type = SBType(type_system->GetBuiltinTypeByName(name)); 421 } 422 } 423 return sb_type; 424 } 425 426 lldb::SBType SBModule::GetBasicType(lldb::BasicType type) { 427 ModuleSP module_sp(GetSP()); 428 if (module_sp) { 429 TypeSystem *type_system = 430 module_sp->GetTypeSystemForLanguage(eLanguageTypeC); 431 if (type_system) 432 return SBType(type_system->GetBasicTypeFromAST(type)); 433 } 434 return SBType(); 435 } 436 437 lldb::SBTypeList SBModule::FindTypes(const char *type) { 438 SBTypeList retval; 439 440 ModuleSP module_sp(GetSP()); 441 if (type && module_sp) { 442 TypeList type_list; 443 const bool exact_match = false; 444 ConstString name(type); 445 llvm::DenseSet<SymbolFile *> searched_symbol_files; 446 const uint32_t num_matches = module_sp->FindTypes( 447 name, exact_match, UINT32_MAX, searched_symbol_files, type_list); 448 449 if (num_matches > 0) { 450 for (size_t idx = 0; idx < num_matches; idx++) { 451 TypeSP type_sp(type_list.GetTypeAtIndex(idx)); 452 if (type_sp) 453 retval.Append(SBType(type_sp)); 454 } 455 } else { 456 TypeSystem *type_system = 457 module_sp->GetTypeSystemForLanguage(eLanguageTypeC); 458 if (type_system) { 459 CompilerType compiler_type = type_system->GetBuiltinTypeByName(name); 460 if (compiler_type) 461 retval.Append(SBType(compiler_type)); 462 } 463 } 464 } 465 466 return retval; 467 } 468 469 lldb::SBType SBModule::GetTypeByID(lldb::user_id_t uid) { 470 ModuleSP module_sp(GetSP()); 471 if (module_sp) { 472 SymbolVendor *vendor = module_sp->GetSymbolVendor(); 473 if (vendor) { 474 Type *type_ptr = vendor->ResolveTypeUID(uid); 475 if (type_ptr) 476 return SBType(type_ptr->shared_from_this()); 477 } 478 } 479 return SBType(); 480 } 481 482 lldb::SBTypeList SBModule::GetTypes(uint32_t type_mask) { 483 SBTypeList sb_type_list; 484 485 ModuleSP module_sp(GetSP()); 486 if (!module_sp) 487 return sb_type_list; 488 SymbolVendor *vendor = module_sp->GetSymbolVendor(); 489 if (!vendor) 490 return sb_type_list; 491 492 TypeClass type_class = static_cast<TypeClass>(type_mask); 493 TypeList type_list; 494 vendor->GetTypes(NULL, type_class, type_list); 495 sb_type_list.m_opaque_ap->Append(type_list); 496 return sb_type_list; 497 } 498 499 SBSection SBModule::FindSection(const char *sect_name) { 500 SBSection sb_section; 501 502 ModuleSP module_sp(GetSP()); 503 if (sect_name && module_sp) { 504 // Give the symbol vendor a chance to add to the unified section list. 505 module_sp->GetSymbolVendor(); 506 SectionList *section_list = module_sp->GetSectionList(); 507 if (section_list) { 508 ConstString const_sect_name(sect_name); 509 SectionSP section_sp(section_list->FindSectionByName(const_sect_name)); 510 if (section_sp) { 511 sb_section.SetSP(section_sp); 512 } 513 } 514 } 515 return sb_section; 516 } 517 518 lldb::ByteOrder SBModule::GetByteOrder() { 519 ModuleSP module_sp(GetSP()); 520 if (module_sp) 521 return module_sp->GetArchitecture().GetByteOrder(); 522 return eByteOrderInvalid; 523 } 524 525 const char *SBModule::GetTriple() { 526 ModuleSP module_sp(GetSP()); 527 if (module_sp) { 528 std::string triple(module_sp->GetArchitecture().GetTriple().str()); 529 // Unique the string so we don't run into ownership issues since the const 530 // strings put the string into the string pool once and the strings never 531 // comes out 532 ConstString const_triple(triple.c_str()); 533 return const_triple.GetCString(); 534 } 535 return NULL; 536 } 537 538 uint32_t SBModule::GetAddressByteSize() { 539 ModuleSP module_sp(GetSP()); 540 if (module_sp) 541 return module_sp->GetArchitecture().GetAddressByteSize(); 542 return sizeof(void *); 543 } 544 545 uint32_t SBModule::GetVersion(uint32_t *versions, uint32_t num_versions) { 546 llvm::VersionTuple version; 547 if (ModuleSP module_sp = GetSP()) 548 version = module_sp->GetVersion(); 549 uint32_t result = 0; 550 if (!version.empty()) 551 ++result; 552 if (version.getMinor()) 553 ++result; 554 if(version.getSubminor()) 555 ++result; 556 557 if (!versions) 558 return result; 559 560 if (num_versions > 0) 561 versions[0] = version.empty() ? UINT32_MAX : version.getMajor(); 562 if (num_versions > 1) 563 versions[1] = version.getMinor().getValueOr(UINT32_MAX); 564 if (num_versions > 2) 565 versions[2] = version.getSubminor().getValueOr(UINT32_MAX); 566 for (uint32_t i = 3; i < num_versions; ++i) 567 versions[i] = UINT32_MAX; 568 return result; 569 } 570 571 lldb::SBFileSpec SBModule::GetSymbolFileSpec() const { 572 lldb::SBFileSpec sb_file_spec; 573 ModuleSP module_sp(GetSP()); 574 if (module_sp) { 575 SymbolVendor *symbol_vendor_ptr = module_sp->GetSymbolVendor(); 576 if (symbol_vendor_ptr) 577 sb_file_spec.SetFileSpec(symbol_vendor_ptr->GetMainFileSpec()); 578 } 579 return sb_file_spec; 580 } 581 582 lldb::SBAddress SBModule::GetObjectFileHeaderAddress() const { 583 lldb::SBAddress sb_addr; 584 ModuleSP module_sp(GetSP()); 585 if (module_sp) { 586 ObjectFile *objfile_ptr = module_sp->GetObjectFile(); 587 if (objfile_ptr) 588 sb_addr.ref() = objfile_ptr->GetBaseAddress(); 589 } 590 return sb_addr; 591 } 592 593 lldb::SBAddress SBModule::GetObjectFileEntryPointAddress() const { 594 lldb::SBAddress sb_addr; 595 ModuleSP module_sp(GetSP()); 596 if (module_sp) { 597 ObjectFile *objfile_ptr = module_sp->GetObjectFile(); 598 if (objfile_ptr) 599 sb_addr.ref() = objfile_ptr->GetEntryPointAddress(); 600 } 601 return sb_addr; 602 } 603