682 lines · cpp
1//===-- SBModule.cpp ------------------------------------------------------===//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-exception6//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/Symbol/ObjectFile.h"19#include "lldb/Symbol/SymbolFile.h"20#include "lldb/Symbol/Symtab.h"21#include "lldb/Symbol/TypeSystem.h"22#include "lldb/Symbol/VariableList.h"23#include "lldb/Target/Target.h"24#include "lldb/Utility/Instrumentation.h"25#include "lldb/Utility/StreamString.h"26#include "lldb/ValueObject/ValueObjectList.h"27#include "lldb/ValueObject/ValueObjectVariable.h"28 29using namespace lldb;30using namespace lldb_private;31 32SBModule::SBModule() { LLDB_INSTRUMENT_VA(this); }33 34SBModule::SBModule(const lldb::ModuleSP &module_sp) : m_opaque_sp(module_sp) {}35 36SBModule::SBModule(const SBModuleSpec &module_spec) {37 LLDB_INSTRUMENT_VA(this, module_spec);38 39 ModuleSP module_sp;40 Status error = ModuleList::GetSharedModule(*module_spec.m_opaque_up,41 module_sp, nullptr, nullptr);42 if (module_sp)43 SetSP(module_sp);44}45 46SBModule::SBModule(const SBModule &rhs) : m_opaque_sp(rhs.m_opaque_sp) {47 LLDB_INSTRUMENT_VA(this, rhs);48}49 50SBModule::SBModule(lldb::SBProcess &process, lldb::addr_t header_addr) {51 LLDB_INSTRUMENT_VA(this, process, header_addr);52 53 ProcessSP process_sp(process.GetSP());54 if (process_sp) {55 m_opaque_sp = process_sp->ReadModuleFromMemory(FileSpec(), header_addr);56 if (m_opaque_sp) {57 Target &target = process_sp->GetTarget();58 bool changed = false;59 m_opaque_sp->SetLoadAddress(target, 0, true, changed);60 target.GetImages().Append(m_opaque_sp);61 }62 }63}64 65const SBModule &SBModule::operator=(const SBModule &rhs) {66 LLDB_INSTRUMENT_VA(this, rhs);67 68 if (this != &rhs)69 m_opaque_sp = rhs.m_opaque_sp;70 return *this;71}72 73SBModule::~SBModule() = default;74 75bool SBModule::IsValid() const {76 LLDB_INSTRUMENT_VA(this);77 return this->operator bool();78}79SBModule::operator bool() const {80 LLDB_INSTRUMENT_VA(this);81 82 return m_opaque_sp.get() != nullptr;83}84 85void SBModule::Clear() {86 LLDB_INSTRUMENT_VA(this);87 88 m_opaque_sp.reset();89}90 91bool SBModule::IsFileBacked() const {92 LLDB_INSTRUMENT_VA(this);93 94 ModuleSP module_sp(GetSP());95 if (!module_sp)96 return false;97 98 ObjectFile *obj_file = module_sp->GetObjectFile();99 if (!obj_file)100 return false;101 102 return !obj_file->IsInMemory();103}104 105SBFileSpec SBModule::GetFileSpec() const {106 LLDB_INSTRUMENT_VA(this);107 108 SBFileSpec file_spec;109 ModuleSP module_sp(GetSP());110 if (module_sp)111 file_spec.SetFileSpec(module_sp->GetFileSpec());112 113 return file_spec;114}115 116lldb::SBFileSpec SBModule::GetPlatformFileSpec() const {117 LLDB_INSTRUMENT_VA(this);118 119 SBFileSpec file_spec;120 ModuleSP module_sp(GetSP());121 if (module_sp)122 file_spec.SetFileSpec(module_sp->GetPlatformFileSpec());123 124 return file_spec;125}126 127bool SBModule::SetPlatformFileSpec(const lldb::SBFileSpec &platform_file) {128 LLDB_INSTRUMENT_VA(this, platform_file);129 130 bool result = false;131 132 ModuleSP module_sp(GetSP());133 if (module_sp) {134 module_sp->SetPlatformFileSpec(*platform_file);135 result = true;136 }137 138 return result;139}140 141lldb::SBFileSpec SBModule::GetRemoteInstallFileSpec() {142 LLDB_INSTRUMENT_VA(this);143 144 SBFileSpec sb_file_spec;145 ModuleSP module_sp(GetSP());146 if (module_sp)147 sb_file_spec.SetFileSpec(module_sp->GetRemoteInstallFileSpec());148 return sb_file_spec;149}150 151bool SBModule::SetRemoteInstallFileSpec(lldb::SBFileSpec &file) {152 LLDB_INSTRUMENT_VA(this, file);153 154 ModuleSP module_sp(GetSP());155 if (module_sp) {156 module_sp->SetRemoteInstallFileSpec(file.ref());157 return true;158 }159 return false;160}161 162const uint8_t *SBModule::GetUUIDBytes() const {163 LLDB_INSTRUMENT_VA(this);164 165 const uint8_t *uuid_bytes = nullptr;166 ModuleSP module_sp(GetSP());167 if (module_sp)168 uuid_bytes = module_sp->GetUUID().GetBytes().data();169 170 return uuid_bytes;171}172 173const char *SBModule::GetUUIDString() const {174 LLDB_INSTRUMENT_VA(this);175 176 ModuleSP module_sp(GetSP());177 if (!module_sp)178 return nullptr;179 180 // We are going to return a "const char *" value through the public API, so181 // we need to constify it so it gets added permanently the string pool and182 // then we don't need to worry about the lifetime of the string as it will183 // never go away once it has been put into the ConstString string pool184 const char *uuid_cstr =185 ConstString(module_sp->GetUUID().GetAsString()).GetCString();186 // Note: SBModule::GetUUIDString's expected behavior is to return nullptr if187 // the string we get is empty, so we must perform this check before returning.188 if (uuid_cstr && uuid_cstr[0])189 return uuid_cstr;190 return nullptr;191}192 193bool SBModule::operator==(const SBModule &rhs) const {194 LLDB_INSTRUMENT_VA(this, rhs);195 196 if (m_opaque_sp)197 return m_opaque_sp.get() == rhs.m_opaque_sp.get();198 return false;199}200 201bool SBModule::operator!=(const SBModule &rhs) const {202 LLDB_INSTRUMENT_VA(this, rhs);203 204 if (m_opaque_sp)205 return m_opaque_sp.get() != rhs.m_opaque_sp.get();206 return false;207}208 209ModuleSP SBModule::GetSP() const { return m_opaque_sp; }210 211void SBModule::SetSP(const ModuleSP &module_sp) { m_opaque_sp = module_sp; }212 213SBAddress SBModule::ResolveFileAddress(lldb::addr_t vm_addr) {214 LLDB_INSTRUMENT_VA(this, vm_addr);215 216 lldb::SBAddress sb_addr;217 ModuleSP module_sp(GetSP());218 if (module_sp) {219 Address addr;220 if (module_sp->ResolveFileAddress(vm_addr, addr))221 sb_addr.ref() = addr;222 }223 return sb_addr;224}225 226SBSymbolContext227SBModule::ResolveSymbolContextForAddress(const SBAddress &addr,228 uint32_t resolve_scope) {229 LLDB_INSTRUMENT_VA(this, addr, resolve_scope);230 231 SBSymbolContext sb_sc;232 ModuleSP module_sp(GetSP());233 SymbolContextItem scope = static_cast<SymbolContextItem>(resolve_scope);234 if (module_sp && addr.IsValid())235 module_sp->ResolveSymbolContextForAddress(addr.ref(), scope, *sb_sc);236 return sb_sc;237}238 239bool SBModule::GetDescription(SBStream &description) {240 LLDB_INSTRUMENT_VA(this, description);241 242 Stream &strm = description.ref();243 244 ModuleSP module_sp(GetSP());245 if (module_sp) {246 module_sp->GetDescription(strm.AsRawOstream());247 } else248 strm.PutCString("No value");249 250 return true;251}252 253uint32_t SBModule::GetNumCompileUnits() {254 LLDB_INSTRUMENT_VA(this);255 256 ModuleSP module_sp(GetSP());257 if (module_sp) {258 return module_sp->GetNumCompileUnits();259 }260 return 0;261}262 263SBCompileUnit SBModule::GetCompileUnitAtIndex(uint32_t index) {264 LLDB_INSTRUMENT_VA(this, index);265 266 SBCompileUnit sb_cu;267 ModuleSP module_sp(GetSP());268 if (module_sp) {269 CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(index);270 sb_cu.reset(cu_sp.get());271 }272 return sb_cu;273}274 275SBSymbolContextList SBModule::FindCompileUnits(const SBFileSpec &sb_file_spec) {276 LLDB_INSTRUMENT_VA(this, sb_file_spec);277 278 SBSymbolContextList sb_sc_list;279 const ModuleSP module_sp(GetSP());280 if (sb_file_spec.IsValid() && module_sp) {281 module_sp->FindCompileUnits(*sb_file_spec, *sb_sc_list);282 }283 return sb_sc_list;284}285 286static Symtab *GetUnifiedSymbolTable(const lldb::ModuleSP &module_sp) {287 if (module_sp)288 return module_sp->GetSymtab();289 return nullptr;290}291 292size_t SBModule::GetNumSymbols() {293 LLDB_INSTRUMENT_VA(this);294 295 ModuleSP module_sp(GetSP());296 if (Symtab *symtab = GetUnifiedSymbolTable(module_sp))297 return symtab->GetNumSymbols();298 return 0;299}300 301SBSymbol SBModule::GetSymbolAtIndex(size_t idx) {302 LLDB_INSTRUMENT_VA(this, idx);303 304 SBSymbol sb_symbol;305 ModuleSP module_sp(GetSP());306 Symtab *symtab = GetUnifiedSymbolTable(module_sp);307 if (symtab)308 sb_symbol.SetSymbol(symtab->SymbolAtIndex(idx));309 return sb_symbol;310}311 312lldb::SBSymbol SBModule::FindSymbol(const char *name,313 lldb::SymbolType symbol_type) {314 LLDB_INSTRUMENT_VA(this, name, symbol_type);315 316 SBSymbol sb_symbol;317 if (name && name[0]) {318 ModuleSP module_sp(GetSP());319 Symtab *symtab = GetUnifiedSymbolTable(module_sp);320 if (symtab)321 sb_symbol.SetSymbol(symtab->FindFirstSymbolWithNameAndType(322 ConstString(name), symbol_type, Symtab::eDebugAny,323 Symtab::eVisibilityAny));324 }325 return sb_symbol;326}327 328lldb::SBSymbolContextList SBModule::FindSymbols(const char *name,329 lldb::SymbolType symbol_type) {330 LLDB_INSTRUMENT_VA(this, name, symbol_type);331 332 SBSymbolContextList sb_sc_list;333 if (name && name[0]) {334 ModuleSP module_sp(GetSP());335 Symtab *symtab = GetUnifiedSymbolTable(module_sp);336 if (symtab) {337 std::vector<uint32_t> matching_symbol_indexes;338 symtab->FindAllSymbolsWithNameAndType(ConstString(name), symbol_type,339 matching_symbol_indexes);340 const size_t num_matches = matching_symbol_indexes.size();341 if (num_matches) {342 SymbolContext sc;343 sc.module_sp = module_sp;344 SymbolContextList &sc_list = *sb_sc_list;345 for (size_t i = 0; i < num_matches; ++i) {346 sc.symbol = symtab->SymbolAtIndex(matching_symbol_indexes[i]);347 if (sc.symbol)348 sc_list.Append(sc);349 }350 }351 }352 }353 return sb_sc_list;354}355 356size_t SBModule::GetNumSections() {357 LLDB_INSTRUMENT_VA(this);358 359 ModuleSP module_sp(GetSP());360 if (module_sp) {361 // Give the symbol vendor a chance to add to the unified section list.362 module_sp->GetSymbolFile();363 SectionList *section_list = module_sp->GetSectionList();364 if (section_list)365 return section_list->GetSize();366 }367 return 0;368}369 370SBSection SBModule::GetSectionAtIndex(size_t idx) {371 LLDB_INSTRUMENT_VA(this, idx);372 373 SBSection sb_section;374 ModuleSP module_sp(GetSP());375 if (module_sp) {376 // Give the symbol vendor a chance to add to the unified section list.377 module_sp->GetSymbolFile();378 SectionList *section_list = module_sp->GetSectionList();379 380 if (section_list)381 sb_section.SetSP(section_list->GetSectionAtIndex(idx));382 }383 return sb_section;384}385 386lldb::SBSymbolContextList SBModule::FindFunctions(const char *name,387 uint32_t name_type_mask) {388 LLDB_INSTRUMENT_VA(this, name, name_type_mask);389 390 lldb::SBSymbolContextList sb_sc_list;391 ModuleSP module_sp(GetSP());392 if (name && module_sp) {393 394 ModuleFunctionSearchOptions function_options;395 function_options.include_symbols = true;396 function_options.include_inlines = true;397 FunctionNameType type = static_cast<FunctionNameType>(name_type_mask);398 module_sp->FindFunctions(ConstString(name), CompilerDeclContext(), type,399 function_options, *sb_sc_list);400 }401 return sb_sc_list;402}403 404SBValueList SBModule::FindGlobalVariables(SBTarget &target, const char *name,405 uint32_t max_matches) {406 LLDB_INSTRUMENT_VA(this, target, name, max_matches);407 408 SBValueList sb_value_list;409 ModuleSP module_sp(GetSP());410 if (name && module_sp) {411 VariableList variable_list;412 module_sp->FindGlobalVariables(ConstString(name), CompilerDeclContext(),413 max_matches, variable_list);414 for (const VariableSP &var_sp : variable_list) {415 lldb::ValueObjectSP valobj_sp;416 TargetSP target_sp(target.GetSP());417 valobj_sp = ValueObjectVariable::Create(target_sp.get(), var_sp);418 if (valobj_sp)419 sb_value_list.Append(SBValue(valobj_sp));420 }421 }422 423 return sb_value_list;424}425 426lldb::SBValue SBModule::FindFirstGlobalVariable(lldb::SBTarget &target,427 const char *name) {428 LLDB_INSTRUMENT_VA(this, target, name);429 430 SBValueList sb_value_list(FindGlobalVariables(target, name, 1));431 if (sb_value_list.IsValid() && sb_value_list.GetSize() > 0)432 return sb_value_list.GetValueAtIndex(0);433 return SBValue();434}435 436lldb::SBType SBModule::FindFirstType(const char *name_cstr) {437 LLDB_INSTRUMENT_VA(this, name_cstr);438 439 ModuleSP module_sp(GetSP());440 if (name_cstr && module_sp) {441 ConstString name(name_cstr);442 TypeQuery query(name.GetStringRef(), TypeQueryOptions::e_find_one);443 TypeResults results;444 module_sp->FindTypes(query, results);445 TypeSP type_sp = results.GetFirstType();446 if (type_sp)447 return SBType(type_sp);448 449 auto type_system_or_err =450 module_sp->GetTypeSystemForLanguage(eLanguageTypeC);451 if (auto err = type_system_or_err.takeError()) {452 llvm::consumeError(std::move(err));453 return {};454 }455 456 if (auto ts = *type_system_or_err)457 return SBType(ts->GetBuiltinTypeByName(name));458 }459 return {};460}461 462lldb::SBType SBModule::GetBasicType(lldb::BasicType type) {463 LLDB_INSTRUMENT_VA(this, type);464 465 ModuleSP module_sp(GetSP());466 if (module_sp) {467 auto type_system_or_err =468 module_sp->GetTypeSystemForLanguage(eLanguageTypeC);469 if (auto err = type_system_or_err.takeError()) {470 llvm::consumeError(std::move(err));471 } else {472 if (auto ts = *type_system_or_err)473 return SBType(ts->GetBasicTypeFromAST(type));474 }475 }476 return SBType();477}478 479lldb::SBTypeList SBModule::FindTypes(const char *type) {480 LLDB_INSTRUMENT_VA(this, type);481 482 SBTypeList retval;483 484 ModuleSP module_sp(GetSP());485 if (type && module_sp) {486 TypeList type_list;487 TypeQuery query(type);488 TypeResults results;489 module_sp->FindTypes(query, results);490 if (results.GetTypeMap().Empty()) {491 ConstString name(type);492 auto type_system_or_err =493 module_sp->GetTypeSystemForLanguage(eLanguageTypeC);494 if (auto err = type_system_or_err.takeError()) {495 llvm::consumeError(std::move(err));496 } else {497 if (auto ts = *type_system_or_err)498 if (CompilerType compiler_type = ts->GetBuiltinTypeByName(name))499 retval.Append(SBType(compiler_type));500 }501 } else {502 for (const TypeSP &type_sp : results.GetTypeMap().Types())503 retval.Append(SBType(type_sp));504 }505 }506 return retval;507}508 509lldb::SBType SBModule::GetTypeByID(lldb::user_id_t uid) {510 LLDB_INSTRUMENT_VA(this, uid);511 512 ModuleSP module_sp(GetSP());513 if (module_sp) {514 if (SymbolFile *symfile = module_sp->GetSymbolFile()) {515 Type *type_ptr = symfile->ResolveTypeUID(uid);516 if (type_ptr)517 return SBType(type_ptr->shared_from_this());518 }519 }520 return SBType();521}522 523lldb::SBTypeList SBModule::GetTypes(uint32_t type_mask) {524 LLDB_INSTRUMENT_VA(this, type_mask);525 526 SBTypeList sb_type_list;527 528 ModuleSP module_sp(GetSP());529 if (!module_sp)530 return sb_type_list;531 SymbolFile *symfile = module_sp->GetSymbolFile();532 if (!symfile)533 return sb_type_list;534 535 TypeClass type_class = static_cast<TypeClass>(type_mask);536 TypeList type_list;537 symfile->GetTypes(nullptr, type_class, type_list);538 sb_type_list.m_opaque_up->Append(type_list);539 return sb_type_list;540}541 542SBSection SBModule::FindSection(const char *sect_name) {543 LLDB_INSTRUMENT_VA(this, sect_name);544 545 SBSection sb_section;546 547 ModuleSP module_sp(GetSP());548 if (sect_name && module_sp) {549 // Give the symbol vendor a chance to add to the unified section list.550 module_sp->GetSymbolFile();551 SectionList *section_list = module_sp->GetSectionList();552 if (section_list) {553 ConstString const_sect_name(sect_name);554 SectionSP section_sp(section_list->FindSectionByName(const_sect_name));555 if (section_sp) {556 sb_section.SetSP(section_sp);557 }558 }559 }560 return sb_section;561}562 563lldb::ByteOrder SBModule::GetByteOrder() {564 LLDB_INSTRUMENT_VA(this);565 566 ModuleSP module_sp(GetSP());567 if (module_sp)568 return module_sp->GetArchitecture().GetByteOrder();569 return eByteOrderInvalid;570}571 572const char *SBModule::GetTriple() {573 LLDB_INSTRUMENT_VA(this);574 575 ModuleSP module_sp(GetSP());576 if (!module_sp)577 return nullptr;578 579 std::string triple(module_sp->GetArchitecture().GetTriple().str());580 // Unique the string so we don't run into ownership issues since the const581 // strings put the string into the string pool once and the strings never582 // comes out583 ConstString const_triple(triple.c_str());584 return const_triple.GetCString();585}586 587uint32_t SBModule::GetAddressByteSize() {588 LLDB_INSTRUMENT_VA(this);589 590 ModuleSP module_sp(GetSP());591 if (module_sp)592 return module_sp->GetArchitecture().GetAddressByteSize();593 return sizeof(void *);594}595 596uint32_t SBModule::GetVersion(uint32_t *versions, uint32_t num_versions) {597 LLDB_INSTRUMENT_VA(this, versions, num_versions);598 599 llvm::VersionTuple version;600 if (ModuleSP module_sp = GetSP())601 version = module_sp->GetVersion();602 uint32_t result = 0;603 if (!version.empty())604 ++result;605 if (version.getMinor())606 ++result;607 if (version.getSubminor())608 ++result;609 610 if (!versions)611 return result;612 613 if (num_versions > 0)614 versions[0] = version.empty() ? UINT32_MAX : version.getMajor();615 if (num_versions > 1)616 versions[1] = version.getMinor().value_or(UINT32_MAX);617 if (num_versions > 2)618 versions[2] = version.getSubminor().value_or(UINT32_MAX);619 for (uint32_t i = 3; i < num_versions; ++i)620 versions[i] = UINT32_MAX;621 return result;622}623 624lldb::SBFileSpec SBModule::GetSymbolFileSpec() const {625 LLDB_INSTRUMENT_VA(this);626 627 lldb::SBFileSpec sb_file_spec;628 ModuleSP module_sp(GetSP());629 if (module_sp) {630 if (SymbolFile *symfile = module_sp->GetSymbolFile())631 sb_file_spec.SetFileSpec(symfile->GetObjectFile()->GetFileSpec());632 }633 return sb_file_spec;634}635 636lldb::SBAddress SBModule::GetObjectFileHeaderAddress() const {637 LLDB_INSTRUMENT_VA(this);638 639 lldb::SBAddress sb_addr;640 ModuleSP module_sp(GetSP());641 if (module_sp) {642 ObjectFile *objfile_ptr = module_sp->GetObjectFile();643 if (objfile_ptr)644 sb_addr.ref() = objfile_ptr->GetBaseAddress();645 }646 return sb_addr;647}648 649lldb::SBAddress SBModule::GetObjectFileEntryPointAddress() const {650 LLDB_INSTRUMENT_VA(this);651 652 lldb::SBAddress sb_addr;653 ModuleSP module_sp(GetSP());654 if (module_sp) {655 ObjectFile *objfile_ptr = module_sp->GetObjectFile();656 if (objfile_ptr)657 sb_addr.ref() = objfile_ptr->GetEntryPointAddress();658 }659 return sb_addr;660}661 662uint32_t SBModule::GetNumberAllocatedModules() {663 LLDB_INSTRUMENT();664 665 return Module::GetNumberAllocatedModules();666}667 668void SBModule::GarbageCollectAllocatedModules() {669 LLDB_INSTRUMENT();670 671 const bool mandatory = false;672 ModuleList::RemoveOrphanSharedModules(mandatory);673}674 675const char *SBModule::GetObjectName() const {676 LLDB_INSTRUMENT_VA(this);677 678 if (!m_opaque_sp)679 return nullptr;680 return m_opaque_sp->GetObjectName().AsCString();681}682