Path: blob/main/contrib/llvm-project/lldb/source/Core/Module.cpp
39587 views
//===-- Module.cpp --------------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Core/Module.h"910#include "lldb/Core/AddressRange.h"11#include "lldb/Core/AddressResolverFileLine.h"12#include "lldb/Core/DataFileCache.h"13#include "lldb/Core/Debugger.h"14#include "lldb/Core/Mangled.h"15#include "lldb/Core/ModuleSpec.h"16#include "lldb/Core/SearchFilter.h"17#include "lldb/Core/Section.h"18#include "lldb/Host/FileSystem.h"19#include "lldb/Host/Host.h"20#include "lldb/Host/HostInfo.h"21#include "lldb/Interpreter/CommandInterpreter.h"22#include "lldb/Interpreter/ScriptInterpreter.h"23#include "lldb/Symbol/CompileUnit.h"24#include "lldb/Symbol/Function.h"25#include "lldb/Symbol/ObjectFile.h"26#include "lldb/Symbol/Symbol.h"27#include "lldb/Symbol/SymbolContext.h"28#include "lldb/Symbol/SymbolFile.h"29#include "lldb/Symbol/SymbolLocator.h"30#include "lldb/Symbol/SymbolVendor.h"31#include "lldb/Symbol/Symtab.h"32#include "lldb/Symbol/Type.h"33#include "lldb/Symbol/TypeList.h"34#include "lldb/Symbol/TypeMap.h"35#include "lldb/Symbol/TypeSystem.h"36#include "lldb/Target/Language.h"37#include "lldb/Target/Process.h"38#include "lldb/Target/Target.h"39#include "lldb/Utility/DataBufferHeap.h"40#include "lldb/Utility/FileSpecList.h"41#include "lldb/Utility/LLDBAssert.h"42#include "lldb/Utility/LLDBLog.h"43#include "lldb/Utility/Log.h"44#include "lldb/Utility/RegularExpression.h"45#include "lldb/Utility/Status.h"46#include "lldb/Utility/Stream.h"47#include "lldb/Utility/StreamString.h"48#include "lldb/Utility/Timer.h"4950#if defined(_WIN32)51#include "lldb/Host/windows/PosixApi.h"52#endif5354#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"55#include "Plugins/Language/ObjC/ObjCLanguage.h"5657#include "llvm/ADT/STLExtras.h"58#include "llvm/Support/Compiler.h"59#include "llvm/Support/DJB.h"60#include "llvm/Support/FileSystem.h"61#include "llvm/Support/FormatVariadic.h"62#include "llvm/Support/JSON.h"63#include "llvm/Support/Signals.h"64#include "llvm/Support/raw_ostream.h"6566#include <cassert>67#include <cinttypes>68#include <cstdarg>69#include <cstdint>70#include <cstring>71#include <map>72#include <optional>73#include <type_traits>74#include <utility>7576namespace lldb_private {77class CompilerDeclContext;78}79namespace lldb_private {80class VariableList;81}8283using namespace lldb;84using namespace lldb_private;8586// Shared pointers to modules track module lifetimes in targets and in the87// global module, but this collection will track all module objects that are88// still alive89typedef std::vector<Module *> ModuleCollection;9091static ModuleCollection &GetModuleCollection() {92// This module collection needs to live past any module, so we could either93// make it a shared pointer in each module or just leak is. Since it is only94// an empty vector by the time all the modules have gone away, we just leak95// it for now. If we decide this is a big problem we can introduce a96// Finalize method that will tear everything down in a predictable order.9798static ModuleCollection *g_module_collection = nullptr;99if (g_module_collection == nullptr)100g_module_collection = new ModuleCollection();101102return *g_module_collection;103}104105std::recursive_mutex &Module::GetAllocationModuleCollectionMutex() {106// NOTE: The mutex below must be leaked since the global module list in107// the ModuleList class will get torn at some point, and we can't know if it108// will tear itself down before the "g_module_collection_mutex" below will.109// So we leak a Mutex object below to safeguard against that110111static std::recursive_mutex *g_module_collection_mutex = nullptr;112if (g_module_collection_mutex == nullptr)113g_module_collection_mutex = new std::recursive_mutex; // NOTE: known leak114return *g_module_collection_mutex;115}116117size_t Module::GetNumberAllocatedModules() {118std::lock_guard<std::recursive_mutex> guard(119GetAllocationModuleCollectionMutex());120return GetModuleCollection().size();121}122123Module *Module::GetAllocatedModuleAtIndex(size_t idx) {124std::lock_guard<std::recursive_mutex> guard(125GetAllocationModuleCollectionMutex());126ModuleCollection &modules = GetModuleCollection();127if (idx < modules.size())128return modules[idx];129return nullptr;130}131132Module::Module(const ModuleSpec &module_spec)133: m_file_has_changed(false), m_first_file_changed_log(false) {134// Scope for locker below...135{136std::lock_guard<std::recursive_mutex> guard(137GetAllocationModuleCollectionMutex());138GetModuleCollection().push_back(this);139}140141Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules));142if (log != nullptr)143LLDB_LOGF(log, "%p Module::Module((%s) '%s%s%s%s')",144static_cast<void *>(this),145module_spec.GetArchitecture().GetArchitectureName(),146module_spec.GetFileSpec().GetPath().c_str(),147module_spec.GetObjectName().IsEmpty() ? "" : "(",148module_spec.GetObjectName().AsCString(""),149module_spec.GetObjectName().IsEmpty() ? "" : ")");150151auto data_sp = module_spec.GetData();152lldb::offset_t file_size = 0;153if (data_sp)154file_size = data_sp->GetByteSize();155156// First extract all module specifications from the file using the local file157// path. If there are no specifications, then don't fill anything in158ModuleSpecList modules_specs;159if (ObjectFile::GetModuleSpecifications(160module_spec.GetFileSpec(), 0, file_size, modules_specs, data_sp) == 0)161return;162163// Now make sure that one of the module specifications matches what we just164// extract. We might have a module specification that specifies a file165// "/usr/lib/dyld" with UUID XXX, but we might have a local version of166// "/usr/lib/dyld" that has167// UUID YYY and we don't want those to match. If they don't match, just don't168// fill any ivars in so we don't accidentally grab the wrong file later since169// they don't match...170ModuleSpec matching_module_spec;171if (!modules_specs.FindMatchingModuleSpec(module_spec,172matching_module_spec)) {173if (log) {174LLDB_LOGF(log, "Found local object file but the specs didn't match");175}176return;177}178179// Set m_data_sp if it was initially provided in the ModuleSpec. Note that180// we cannot use the data_sp variable here, because it will have been181// modified by GetModuleSpecifications().182if (auto module_spec_data_sp = module_spec.GetData()) {183m_data_sp = module_spec_data_sp;184m_mod_time = {};185} else {186if (module_spec.GetFileSpec())187m_mod_time =188FileSystem::Instance().GetModificationTime(module_spec.GetFileSpec());189else if (matching_module_spec.GetFileSpec())190m_mod_time = FileSystem::Instance().GetModificationTime(191matching_module_spec.GetFileSpec());192}193194// Copy the architecture from the actual spec if we got one back, else use195// the one that was specified196if (matching_module_spec.GetArchitecture().IsValid())197m_arch = matching_module_spec.GetArchitecture();198else if (module_spec.GetArchitecture().IsValid())199m_arch = module_spec.GetArchitecture();200201// Copy the file spec over and use the specified one (if there was one) so we202// don't use a path that might have gotten resolved a path in203// 'matching_module_spec'204if (module_spec.GetFileSpec())205m_file = module_spec.GetFileSpec();206else if (matching_module_spec.GetFileSpec())207m_file = matching_module_spec.GetFileSpec();208209// Copy the platform file spec over210if (module_spec.GetPlatformFileSpec())211m_platform_file = module_spec.GetPlatformFileSpec();212else if (matching_module_spec.GetPlatformFileSpec())213m_platform_file = matching_module_spec.GetPlatformFileSpec();214215// Copy the symbol file spec over216if (module_spec.GetSymbolFileSpec())217m_symfile_spec = module_spec.GetSymbolFileSpec();218else if (matching_module_spec.GetSymbolFileSpec())219m_symfile_spec = matching_module_spec.GetSymbolFileSpec();220221// Copy the object name over222if (matching_module_spec.GetObjectName())223m_object_name = matching_module_spec.GetObjectName();224else225m_object_name = module_spec.GetObjectName();226227// Always trust the object offset (file offset) and object modification time228// (for mod time in a BSD static archive) of from the matching module229// specification230m_object_offset = matching_module_spec.GetObjectOffset();231m_object_mod_time = matching_module_spec.GetObjectModificationTime();232}233234Module::Module(const FileSpec &file_spec, const ArchSpec &arch,235ConstString object_name, lldb::offset_t object_offset,236const llvm::sys::TimePoint<> &object_mod_time)237: m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)),238m_arch(arch), m_file(file_spec), m_object_name(object_name),239m_object_offset(object_offset), m_object_mod_time(object_mod_time),240m_file_has_changed(false), m_first_file_changed_log(false) {241// Scope for locker below...242{243std::lock_guard<std::recursive_mutex> guard(244GetAllocationModuleCollectionMutex());245GetModuleCollection().push_back(this);246}247248Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules));249if (log != nullptr)250LLDB_LOGF(log, "%p Module::Module((%s) '%s%s%s%s')",251static_cast<void *>(this), m_arch.GetArchitectureName(),252m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",253m_object_name.AsCString(""), m_object_name.IsEmpty() ? "" : ")");254}255256Module::Module() : m_file_has_changed(false), m_first_file_changed_log(false) {257std::lock_guard<std::recursive_mutex> guard(258GetAllocationModuleCollectionMutex());259GetModuleCollection().push_back(this);260}261262Module::~Module() {263// Lock our module down while we tear everything down to make sure we don't264// get any access to the module while it is being destroyed265std::lock_guard<std::recursive_mutex> guard(m_mutex);266// Scope for locker below...267{268std::lock_guard<std::recursive_mutex> guard(269GetAllocationModuleCollectionMutex());270ModuleCollection &modules = GetModuleCollection();271ModuleCollection::iterator end = modules.end();272ModuleCollection::iterator pos = std::find(modules.begin(), end, this);273assert(pos != end);274modules.erase(pos);275}276Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules));277if (log != nullptr)278LLDB_LOGF(log, "%p Module::~Module((%s) '%s%s%s%s')",279static_cast<void *>(this), m_arch.GetArchitectureName(),280m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",281m_object_name.AsCString(""), m_object_name.IsEmpty() ? "" : ")");282// Release any auto pointers before we start tearing down our member283// variables since the object file and symbol files might need to make284// function calls back into this module object. The ordering is important285// here because symbol files can require the module object file. So we tear286// down the symbol file first, then the object file.287m_sections_up.reset();288m_symfile_up.reset();289m_objfile_sp.reset();290}291292ObjectFile *Module::GetMemoryObjectFile(const lldb::ProcessSP &process_sp,293lldb::addr_t header_addr, Status &error,294size_t size_to_read) {295if (m_objfile_sp) {296error.SetErrorString("object file already exists");297} else {298std::lock_guard<std::recursive_mutex> guard(m_mutex);299if (process_sp) {300m_did_load_objfile = true;301std::shared_ptr<DataBufferHeap> data_sp =302std::make_shared<DataBufferHeap>(size_to_read, 0);303Status readmem_error;304const size_t bytes_read =305process_sp->ReadMemory(header_addr, data_sp->GetBytes(),306data_sp->GetByteSize(), readmem_error);307if (bytes_read < size_to_read)308data_sp->SetByteSize(bytes_read);309if (data_sp->GetByteSize() > 0) {310m_objfile_sp = ObjectFile::FindPlugin(shared_from_this(), process_sp,311header_addr, data_sp);312if (m_objfile_sp) {313StreamString s;314s.Printf("0x%16.16" PRIx64, header_addr);315m_object_name.SetString(s.GetString());316317// Once we get the object file, update our module with the object318// file's architecture since it might differ in vendor/os if some319// parts were unknown.320m_arch = m_objfile_sp->GetArchitecture();321322// Augment the arch with the target's information in case323// we are unable to extract the os/environment from memory.324m_arch.MergeFrom(process_sp->GetTarget().GetArchitecture());325} else {326error.SetErrorString("unable to find suitable object file plug-in");327}328} else {329error.SetErrorStringWithFormat("unable to read header from memory: %s",330readmem_error.AsCString());331}332} else {333error.SetErrorString("invalid process");334}335}336return m_objfile_sp.get();337}338339const lldb_private::UUID &Module::GetUUID() {340if (!m_did_set_uuid.load()) {341std::lock_guard<std::recursive_mutex> guard(m_mutex);342if (!m_did_set_uuid.load()) {343ObjectFile *obj_file = GetObjectFile();344345if (obj_file != nullptr) {346m_uuid = obj_file->GetUUID();347m_did_set_uuid = true;348}349}350}351return m_uuid;352}353354void Module::SetUUID(const lldb_private::UUID &uuid) {355std::lock_guard<std::recursive_mutex> guard(m_mutex);356if (!m_did_set_uuid) {357m_uuid = uuid;358m_did_set_uuid = true;359} else {360lldbassert(0 && "Attempting to overwrite the existing module UUID");361}362}363364llvm::Expected<TypeSystemSP>365Module::GetTypeSystemForLanguage(LanguageType language) {366return m_type_system_map.GetTypeSystemForLanguage(language, this, true);367}368369void Module::ForEachTypeSystem(370llvm::function_ref<bool(lldb::TypeSystemSP)> callback) {371m_type_system_map.ForEach(callback);372}373374void Module::ParseAllDebugSymbols() {375std::lock_guard<std::recursive_mutex> guard(m_mutex);376size_t num_comp_units = GetNumCompileUnits();377if (num_comp_units == 0)378return;379380SymbolFile *symbols = GetSymbolFile();381382for (size_t cu_idx = 0; cu_idx < num_comp_units; cu_idx++) {383SymbolContext sc;384sc.module_sp = shared_from_this();385sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get();386if (!sc.comp_unit)387continue;388389symbols->ParseVariablesForContext(sc);390391symbols->ParseFunctions(*sc.comp_unit);392393sc.comp_unit->ForeachFunction([&sc, &symbols](const FunctionSP &f) {394symbols->ParseBlocksRecursive(*f);395396// Parse the variables for this function and all its blocks397sc.function = f.get();398symbols->ParseVariablesForContext(sc);399return false;400});401402// Parse all types for this compile unit403symbols->ParseTypes(*sc.comp_unit);404}405}406407void Module::CalculateSymbolContext(SymbolContext *sc) {408sc->module_sp = shared_from_this();409}410411ModuleSP Module::CalculateSymbolContextModule() { return shared_from_this(); }412413void Module::DumpSymbolContext(Stream *s) {414s->Printf(", Module{%p}", static_cast<void *>(this));415}416417size_t Module::GetNumCompileUnits() {418std::lock_guard<std::recursive_mutex> guard(m_mutex);419if (SymbolFile *symbols = GetSymbolFile())420return symbols->GetNumCompileUnits();421return 0;422}423424CompUnitSP Module::GetCompileUnitAtIndex(size_t index) {425std::lock_guard<std::recursive_mutex> guard(m_mutex);426size_t num_comp_units = GetNumCompileUnits();427CompUnitSP cu_sp;428429if (index < num_comp_units) {430if (SymbolFile *symbols = GetSymbolFile())431cu_sp = symbols->GetCompileUnitAtIndex(index);432}433return cu_sp;434}435436bool Module::ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) {437std::lock_guard<std::recursive_mutex> guard(m_mutex);438SectionList *section_list = GetSectionList();439if (section_list)440return so_addr.ResolveAddressUsingFileSections(vm_addr, section_list);441return false;442}443444uint32_t Module::ResolveSymbolContextForAddress(445const Address &so_addr, lldb::SymbolContextItem resolve_scope,446SymbolContext &sc, bool resolve_tail_call_address) {447std::lock_guard<std::recursive_mutex> guard(m_mutex);448uint32_t resolved_flags = 0;449450// Clear the result symbol context in case we don't find anything, but don't451// clear the target452sc.Clear(false);453454// Get the section from the section/offset address.455SectionSP section_sp(so_addr.GetSection());456457// Make sure the section matches this module before we try and match anything458if (section_sp && section_sp->GetModule().get() == this) {459// If the section offset based address resolved itself, then this is the460// right module.461sc.module_sp = shared_from_this();462resolved_flags |= eSymbolContextModule;463464SymbolFile *symfile = GetSymbolFile();465if (!symfile)466return resolved_flags;467468// Resolve the compile unit, function, block, line table or line entry if469// requested.470if (resolve_scope & eSymbolContextCompUnit ||471resolve_scope & eSymbolContextFunction ||472resolve_scope & eSymbolContextBlock ||473resolve_scope & eSymbolContextLineEntry ||474resolve_scope & eSymbolContextVariable) {475symfile->SetLoadDebugInfoEnabled();476resolved_flags |=477symfile->ResolveSymbolContext(so_addr, resolve_scope, sc);478}479480// Resolve the symbol if requested, but don't re-look it up if we've481// already found it.482if (resolve_scope & eSymbolContextSymbol &&483!(resolved_flags & eSymbolContextSymbol)) {484Symtab *symtab = symfile->GetSymtab();485if (symtab && so_addr.IsSectionOffset()) {486Symbol *matching_symbol = nullptr;487488symtab->ForEachSymbolContainingFileAddress(489so_addr.GetFileAddress(),490[&matching_symbol](Symbol *symbol) -> bool {491if (symbol->GetType() != eSymbolTypeInvalid) {492matching_symbol = symbol;493return false; // Stop iterating494}495return true; // Keep iterating496});497sc.symbol = matching_symbol;498if (!sc.symbol && resolve_scope & eSymbolContextFunction &&499!(resolved_flags & eSymbolContextFunction)) {500bool verify_unique = false; // No need to check again since501// ResolveSymbolContext failed to find a502// symbol at this address.503if (ObjectFile *obj_file = sc.module_sp->GetObjectFile())504sc.symbol =505obj_file->ResolveSymbolForAddress(so_addr, verify_unique);506}507508if (sc.symbol) {509if (sc.symbol->IsSynthetic()) {510// We have a synthetic symbol so lets check if the object file from511// the symbol file in the symbol vendor is different than the512// object file for the module, and if so search its symbol table to513// see if we can come up with a better symbol. For example dSYM514// files on MacOSX have an unstripped symbol table inside of them.515ObjectFile *symtab_objfile = symtab->GetObjectFile();516if (symtab_objfile && symtab_objfile->IsStripped()) {517ObjectFile *symfile_objfile = symfile->GetObjectFile();518if (symfile_objfile != symtab_objfile) {519Symtab *symfile_symtab = symfile_objfile->GetSymtab();520if (symfile_symtab) {521Symbol *symbol =522symfile_symtab->FindSymbolContainingFileAddress(523so_addr.GetFileAddress());524if (symbol && !symbol->IsSynthetic()) {525sc.symbol = symbol;526}527}528}529}530}531resolved_flags |= eSymbolContextSymbol;532}533}534}535536// For function symbols, so_addr may be off by one. This is a convention537// consistent with FDE row indices in eh_frame sections, but requires extra538// logic here to permit symbol lookup for disassembly and unwind.539if (resolve_scope & eSymbolContextSymbol &&540!(resolved_flags & eSymbolContextSymbol) && resolve_tail_call_address &&541so_addr.IsSectionOffset()) {542Address previous_addr = so_addr;543previous_addr.Slide(-1);544545bool do_resolve_tail_call_address = false; // prevent recursion546const uint32_t flags = ResolveSymbolContextForAddress(547previous_addr, resolve_scope, sc, do_resolve_tail_call_address);548if (flags & eSymbolContextSymbol) {549AddressRange addr_range;550if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,551false, addr_range)) {552if (addr_range.GetBaseAddress().GetSection() ==553so_addr.GetSection()) {554// If the requested address is one past the address range of a555// function (i.e. a tail call), or the decremented address is the556// start of a function (i.e. some forms of trampoline), indicate557// that the symbol has been resolved.558if (so_addr.GetOffset() ==559addr_range.GetBaseAddress().GetOffset() ||560so_addr.GetOffset() == addr_range.GetBaseAddress().GetOffset() +561addr_range.GetByteSize()) {562resolved_flags |= flags;563}564} else {565sc.symbol =566nullptr; // Don't trust the symbol if the sections didn't match.567}568}569}570}571}572return resolved_flags;573}574575uint32_t Module::ResolveSymbolContextForFilePath(576const char *file_path, uint32_t line, bool check_inlines,577lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {578FileSpec file_spec(file_path);579return ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,580resolve_scope, sc_list);581}582583uint32_t Module::ResolveSymbolContextsForFileSpec(584const FileSpec &file_spec, uint32_t line, bool check_inlines,585lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {586std::lock_guard<std::recursive_mutex> guard(m_mutex);587LLDB_SCOPED_TIMERF("Module::ResolveSymbolContextForFilePath (%s:%u, "588"check_inlines = %s, resolve_scope = 0x%8.8x)",589file_spec.GetPath().c_str(), line,590check_inlines ? "yes" : "no", resolve_scope);591592const uint32_t initial_count = sc_list.GetSize();593594if (SymbolFile *symbols = GetSymbolFile()) {595// TODO: Handle SourceLocationSpec column information596SourceLocationSpec location_spec(file_spec, line, /*column=*/std::nullopt,597check_inlines, /*exact_match=*/false);598599symbols->ResolveSymbolContext(location_spec, resolve_scope, sc_list);600}601602return sc_list.GetSize() - initial_count;603}604605void Module::FindGlobalVariables(ConstString name,606const CompilerDeclContext &parent_decl_ctx,607size_t max_matches, VariableList &variables) {608if (SymbolFile *symbols = GetSymbolFile())609symbols->FindGlobalVariables(name, parent_decl_ctx, max_matches, variables);610}611612void Module::FindGlobalVariables(const RegularExpression ®ex,613size_t max_matches, VariableList &variables) {614SymbolFile *symbols = GetSymbolFile();615if (symbols)616symbols->FindGlobalVariables(regex, max_matches, variables);617}618619void Module::FindCompileUnits(const FileSpec &path,620SymbolContextList &sc_list) {621const size_t num_compile_units = GetNumCompileUnits();622SymbolContext sc;623sc.module_sp = shared_from_this();624for (size_t i = 0; i < num_compile_units; ++i) {625sc.comp_unit = GetCompileUnitAtIndex(i).get();626if (sc.comp_unit) {627if (FileSpec::Match(path, sc.comp_unit->GetPrimaryFile()))628sc_list.Append(sc);629}630}631}632633Module::LookupInfo::LookupInfo(ConstString name,634FunctionNameType name_type_mask,635LanguageType language)636: m_name(name), m_lookup_name(), m_language(language) {637const char *name_cstr = name.GetCString();638llvm::StringRef basename;639llvm::StringRef context;640641if (name_type_mask & eFunctionNameTypeAuto) {642if (CPlusPlusLanguage::IsCPPMangledName(name_cstr))643m_name_type_mask = eFunctionNameTypeFull;644else if ((language == eLanguageTypeUnknown ||645Language::LanguageIsObjC(language)) &&646ObjCLanguage::IsPossibleObjCMethodName(name_cstr))647m_name_type_mask = eFunctionNameTypeFull;648else if (Language::LanguageIsC(language)) {649m_name_type_mask = eFunctionNameTypeFull;650} else {651if ((language == eLanguageTypeUnknown ||652Language::LanguageIsObjC(language)) &&653ObjCLanguage::IsPossibleObjCSelector(name_cstr))654m_name_type_mask |= eFunctionNameTypeSelector;655656CPlusPlusLanguage::MethodName cpp_method(name);657basename = cpp_method.GetBasename();658if (basename.empty()) {659if (CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,660basename))661m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);662else663m_name_type_mask |= eFunctionNameTypeFull;664} else {665m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);666}667}668} else {669m_name_type_mask = name_type_mask;670if (name_type_mask & eFunctionNameTypeMethod ||671name_type_mask & eFunctionNameTypeBase) {672// If they've asked for a CPP method or function name and it can't be673// that, we don't even need to search for CPP methods or names.674CPlusPlusLanguage::MethodName cpp_method(name);675if (cpp_method.IsValid()) {676basename = cpp_method.GetBasename();677678if (!cpp_method.GetQualifiers().empty()) {679// There is a "const" or other qualifier following the end of the680// function parens, this can't be a eFunctionNameTypeBase681m_name_type_mask &= ~(eFunctionNameTypeBase);682if (m_name_type_mask == eFunctionNameTypeNone)683return;684}685} else {686// If the CPP method parser didn't manage to chop this up, try to fill687// in the base name if we can. If a::b::c is passed in, we need to just688// look up "c", and then we'll filter the result later.689CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,690basename);691}692}693694if (name_type_mask & eFunctionNameTypeSelector) {695if (!ObjCLanguage::IsPossibleObjCSelector(name_cstr)) {696m_name_type_mask &= ~(eFunctionNameTypeSelector);697if (m_name_type_mask == eFunctionNameTypeNone)698return;699}700}701702// Still try and get a basename in case someone specifies a name type mask703// of eFunctionNameTypeFull and a name like "A::func"704if (basename.empty()) {705if (name_type_mask & eFunctionNameTypeFull &&706!CPlusPlusLanguage::IsCPPMangledName(name_cstr)) {707CPlusPlusLanguage::MethodName cpp_method(name);708basename = cpp_method.GetBasename();709if (basename.empty())710CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,711basename);712}713}714}715716if (!basename.empty()) {717// The name supplied was a partial C++ path like "a::count". In this case718// we want to do a lookup on the basename "count" and then make sure any719// matching results contain "a::count" so that it would match "b::a::count"720// and "a::count". This is why we set "match_name_after_lookup" to true721m_lookup_name.SetString(basename);722m_match_name_after_lookup = true;723} else {724// The name is already correct, just use the exact name as supplied, and we725// won't need to check if any matches contain "name"726m_lookup_name = name;727m_match_name_after_lookup = false;728}729}730731bool Module::LookupInfo::NameMatchesLookupInfo(732ConstString function_name, LanguageType language_type) const {733// We always keep unnamed symbols734if (!function_name)735return true;736737// If we match exactly, we can return early738if (m_name == function_name)739return true;740741// If function_name is mangled, we'll need to demangle it.742// In the pathologial case where the function name "looks" mangled but is743// actually demangled (e.g. a method named _Zonk), this operation should be744// relatively inexpensive since no demangling is actually occuring. See745// Mangled::SetValue for more context.746const bool function_name_may_be_mangled =747Mangled::GetManglingScheme(function_name) != Mangled::eManglingSchemeNone;748ConstString demangled_function_name = function_name;749if (function_name_may_be_mangled) {750Mangled mangled_function_name(function_name);751demangled_function_name = mangled_function_name.GetDemangledName();752}753754// If the symbol has a language, then let the language make the match.755// Otherwise just check that the demangled function name contains the756// demangled user-provided name.757if (Language *language = Language::FindPlugin(language_type))758return language->DemangledNameContainsPath(m_name, demangled_function_name);759760llvm::StringRef function_name_ref = demangled_function_name;761return function_name_ref.contains(m_name);762}763764void Module::LookupInfo::Prune(SymbolContextList &sc_list,765size_t start_idx) const {766if (m_match_name_after_lookup && m_name) {767SymbolContext sc;768size_t i = start_idx;769while (i < sc_list.GetSize()) {770if (!sc_list.GetContextAtIndex(i, sc))771break;772773bool keep_it =774NameMatchesLookupInfo(sc.GetFunctionName(), sc.GetLanguage());775if (keep_it)776++i;777else778sc_list.RemoveContextAtIndex(i);779}780}781782// If we have only full name matches we might have tried to set breakpoint on783// "func" and specified eFunctionNameTypeFull, but we might have found784// "a::func()", "a::b::func()", "c::func()", "func()" and "func". Only785// "func()" and "func" should end up matching.786if (m_name_type_mask == eFunctionNameTypeFull) {787SymbolContext sc;788size_t i = start_idx;789while (i < sc_list.GetSize()) {790if (!sc_list.GetContextAtIndex(i, sc))791break;792// Make sure the mangled and demangled names don't match before we try to793// pull anything out794ConstString mangled_name(sc.GetFunctionName(Mangled::ePreferMangled));795ConstString full_name(sc.GetFunctionName());796if (mangled_name != m_name && full_name != m_name) {797CPlusPlusLanguage::MethodName cpp_method(full_name);798if (cpp_method.IsValid()) {799if (cpp_method.GetContext().empty()) {800if (cpp_method.GetBasename().compare(m_name) != 0) {801sc_list.RemoveContextAtIndex(i);802continue;803}804} else {805std::string qualified_name;806llvm::StringRef anon_prefix("(anonymous namespace)");807if (cpp_method.GetContext() == anon_prefix)808qualified_name = cpp_method.GetBasename().str();809else810qualified_name = cpp_method.GetScopeQualifiedName();811if (qualified_name != m_name.GetCString()) {812sc_list.RemoveContextAtIndex(i);813continue;814}815}816}817}818++i;819}820}821}822823void Module::FindFunctions(const Module::LookupInfo &lookup_info,824const CompilerDeclContext &parent_decl_ctx,825const ModuleFunctionSearchOptions &options,826SymbolContextList &sc_list) {827// Find all the functions (not symbols, but debug information functions...828if (SymbolFile *symbols = GetSymbolFile()) {829symbols->FindFunctions(lookup_info, parent_decl_ctx,830options.include_inlines, sc_list);831// Now check our symbol table for symbols that are code symbols if832// requested833if (options.include_symbols) {834if (Symtab *symtab = symbols->GetSymtab()) {835symtab->FindFunctionSymbols(lookup_info.GetLookupName(),836lookup_info.GetNameTypeMask(), sc_list);837}838}839}840}841842void Module::FindFunctions(ConstString name,843const CompilerDeclContext &parent_decl_ctx,844FunctionNameType name_type_mask,845const ModuleFunctionSearchOptions &options,846SymbolContextList &sc_list) {847const size_t old_size = sc_list.GetSize();848LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);849FindFunctions(lookup_info, parent_decl_ctx, options, sc_list);850if (name_type_mask & eFunctionNameTypeAuto) {851const size_t new_size = sc_list.GetSize();852if (old_size < new_size)853lookup_info.Prune(sc_list, old_size);854}855}856857void Module::FindFunctions(llvm::ArrayRef<CompilerContext> compiler_ctx,858FunctionNameType name_type_mask,859const ModuleFunctionSearchOptions &options,860SymbolContextList &sc_list) {861if (compiler_ctx.empty() ||862compiler_ctx.back().kind != CompilerContextKind::Function)863return;864ConstString name = compiler_ctx.back().name;865SymbolContextList unfiltered;866FindFunctions(name, CompilerDeclContext(), name_type_mask, options,867unfiltered);868// Filter by context.869for (auto &sc : unfiltered)870if (sc.function && compiler_ctx.equals(sc.function->GetCompilerContext()))871sc_list.Append(sc);872}873874void Module::FindFunctions(const RegularExpression ®ex,875const ModuleFunctionSearchOptions &options,876SymbolContextList &sc_list) {877const size_t start_size = sc_list.GetSize();878879if (SymbolFile *symbols = GetSymbolFile()) {880symbols->FindFunctions(regex, options.include_inlines, sc_list);881882// Now check our symbol table for symbols that are code symbols if883// requested884if (options.include_symbols) {885Symtab *symtab = symbols->GetSymtab();886if (symtab) {887std::vector<uint32_t> symbol_indexes;888symtab->AppendSymbolIndexesMatchingRegExAndType(889regex, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny,890symbol_indexes);891const size_t num_matches = symbol_indexes.size();892if (num_matches) {893SymbolContext sc(this);894const size_t end_functions_added_index = sc_list.GetSize();895size_t num_functions_added_to_sc_list =896end_functions_added_index - start_size;897if (num_functions_added_to_sc_list == 0) {898// No functions were added, just symbols, so we can just append899// them900for (size_t i = 0; i < num_matches; ++i) {901sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);902SymbolType sym_type = sc.symbol->GetType();903if (sc.symbol && (sym_type == eSymbolTypeCode ||904sym_type == eSymbolTypeResolver))905sc_list.Append(sc);906}907} else {908typedef std::map<lldb::addr_t, uint32_t> FileAddrToIndexMap;909FileAddrToIndexMap file_addr_to_index;910for (size_t i = start_size; i < end_functions_added_index; ++i) {911const SymbolContext &sc = sc_list[i];912if (sc.block)913continue;914file_addr_to_index[sc.function->GetAddressRange()915.GetBaseAddress()916.GetFileAddress()] = i;917}918919FileAddrToIndexMap::const_iterator end = file_addr_to_index.end();920// Functions were added so we need to merge symbols into any921// existing function symbol contexts922for (size_t i = start_size; i < num_matches; ++i) {923sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);924SymbolType sym_type = sc.symbol->GetType();925if (sc.symbol && sc.symbol->ValueIsAddress() &&926(sym_type == eSymbolTypeCode ||927sym_type == eSymbolTypeResolver)) {928FileAddrToIndexMap::const_iterator pos =929file_addr_to_index.find(930sc.symbol->GetAddressRef().GetFileAddress());931if (pos == end)932sc_list.Append(sc);933else934sc_list[pos->second].symbol = sc.symbol;935}936}937}938}939}940}941}942}943944void Module::FindAddressesForLine(const lldb::TargetSP target_sp,945const FileSpec &file, uint32_t line,946Function *function,947std::vector<Address> &output_local,948std::vector<Address> &output_extern) {949SearchFilterByModule filter(target_sp, m_file);950951// TODO: Handle SourceLocationSpec column information952SourceLocationSpec location_spec(file, line, /*column=*/std::nullopt,953/*check_inlines=*/true,954/*exact_match=*/false);955AddressResolverFileLine resolver(location_spec);956resolver.ResolveAddress(filter);957958for (size_t n = 0; n < resolver.GetNumberOfAddresses(); n++) {959Address addr = resolver.GetAddressRangeAtIndex(n).GetBaseAddress();960Function *f = addr.CalculateSymbolContextFunction();961if (f && f == function)962output_local.push_back(addr);963else964output_extern.push_back(addr);965}966}967968void Module::FindTypes(const TypeQuery &query, TypeResults &results) {969if (SymbolFile *symbols = GetSymbolFile())970symbols->FindTypes(query, results);971}972973static Debugger::DebuggerList974DebuggersOwningModuleRequestingInterruption(Module &module) {975Debugger::DebuggerList requestors =976Debugger::DebuggersRequestingInterruption();977Debugger::DebuggerList interruptors;978if (requestors.empty())979return interruptors;980981for (auto debugger_sp : requestors) {982if (!debugger_sp->InterruptRequested())983continue;984if (debugger_sp->GetTargetList()985.AnyTargetContainsModule(module))986interruptors.push_back(debugger_sp);987}988return interruptors;989}990991SymbolFile *Module::GetSymbolFile(bool can_create, Stream *feedback_strm) {992if (!m_did_load_symfile.load()) {993std::lock_guard<std::recursive_mutex> guard(m_mutex);994if (!m_did_load_symfile.load() && can_create) {995Debugger::DebuggerList interruptors =996DebuggersOwningModuleRequestingInterruption(*this);997if (!interruptors.empty()) {998for (auto debugger_sp : interruptors) {999REPORT_INTERRUPTION(*(debugger_sp.get()),1000"Interrupted fetching symbols for module {0}",1001this->GetFileSpec());1002}1003return nullptr;1004}1005ObjectFile *obj_file = GetObjectFile();1006if (obj_file != nullptr) {1007LLDB_SCOPED_TIMER();1008m_symfile_up.reset(1009SymbolVendor::FindPlugin(shared_from_this(), feedback_strm));1010m_did_load_symfile = true;1011if (m_unwind_table)1012m_unwind_table->Update();1013}1014}1015}1016return m_symfile_up ? m_symfile_up->GetSymbolFile() : nullptr;1017}10181019Symtab *Module::GetSymtab() {1020if (SymbolFile *symbols = GetSymbolFile())1021return symbols->GetSymtab();1022return nullptr;1023}10241025void Module::SetFileSpecAndObjectName(const FileSpec &file,1026ConstString object_name) {1027// Container objects whose paths do not specify a file directly can call this1028// function to correct the file and object names.1029m_file = file;1030m_mod_time = FileSystem::Instance().GetModificationTime(file);1031m_object_name = object_name;1032}10331034const ArchSpec &Module::GetArchitecture() const { return m_arch; }10351036std::string Module::GetSpecificationDescription() const {1037std::string spec(GetFileSpec().GetPath());1038if (m_object_name) {1039spec += '(';1040spec += m_object_name.GetCString();1041spec += ')';1042}1043return spec;1044}10451046void Module::GetDescription(llvm::raw_ostream &s,1047lldb::DescriptionLevel level) {1048if (level >= eDescriptionLevelFull) {1049if (m_arch.IsValid())1050s << llvm::formatv("({0}) ", m_arch.GetArchitectureName());1051}10521053if (level == eDescriptionLevelBrief) {1054const char *filename = m_file.GetFilename().GetCString();1055if (filename)1056s << filename;1057} else {1058char path[PATH_MAX];1059if (m_file.GetPath(path, sizeof(path)))1060s << path;1061}10621063const char *object_name = m_object_name.GetCString();1064if (object_name)1065s << llvm::formatv("({0})", object_name);1066}10671068bool Module::FileHasChanged() const {1069// We have provided the DataBuffer for this module to avoid accessing the1070// filesystem. We never want to reload those files.1071if (m_data_sp)1072return false;1073if (!m_file_has_changed)1074m_file_has_changed =1075(FileSystem::Instance().GetModificationTime(m_file) != m_mod_time);1076return m_file_has_changed;1077}10781079void Module::ReportWarningOptimization(1080std::optional<lldb::user_id_t> debugger_id) {1081ConstString file_name = GetFileSpec().GetFilename();1082if (file_name.IsEmpty())1083return;10841085StreamString ss;1086ss << file_name1087<< " was compiled with optimization - stepping may behave "1088"oddly; variables may not be available.";1089Debugger::ReportWarning(std::string(ss.GetString()), debugger_id,1090&m_optimization_warning);1091}10921093void Module::ReportWarningUnsupportedLanguage(1094LanguageType language, std::optional<lldb::user_id_t> debugger_id) {1095StreamString ss;1096ss << "This version of LLDB has no plugin for the language \""1097<< Language::GetNameForLanguageType(language)1098<< "\". "1099"Inspection of frame variables will be limited.";1100Debugger::ReportWarning(std::string(ss.GetString()), debugger_id,1101&m_language_warning);1102}11031104void Module::ReportErrorIfModifyDetected(1105const llvm::formatv_object_base &payload) {1106if (!m_first_file_changed_log) {1107if (FileHasChanged()) {1108m_first_file_changed_log = true;1109StreamString strm;1110strm.PutCString("the object file ");1111GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelFull);1112strm.PutCString(" has been modified\n");1113strm.PutCString(payload.str());1114strm.PutCString("The debug session should be aborted as the original "1115"debug information has been overwritten.");1116Debugger::ReportError(std::string(strm.GetString()));1117}1118}1119}11201121void Module::ReportError(const llvm::formatv_object_base &payload) {1122StreamString strm;1123GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelBrief);1124strm.PutChar(' ');1125strm.PutCString(payload.str());1126Debugger::ReportError(strm.GetString().str());1127}11281129void Module::ReportWarning(const llvm::formatv_object_base &payload) {1130StreamString strm;1131GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelFull);1132strm.PutChar(' ');1133strm.PutCString(payload.str());1134Debugger::ReportWarning(std::string(strm.GetString()));1135}11361137void Module::LogMessage(Log *log, const llvm::formatv_object_base &payload) {1138StreamString log_message;1139GetDescription(log_message.AsRawOstream(), lldb::eDescriptionLevelFull);1140log_message.PutCString(": ");1141log_message.PutCString(payload.str());1142log->PutCString(log_message.GetData());1143}11441145void Module::LogMessageVerboseBacktrace(1146Log *log, const llvm::formatv_object_base &payload) {1147StreamString log_message;1148GetDescription(log_message.AsRawOstream(), lldb::eDescriptionLevelFull);1149log_message.PutCString(": ");1150log_message.PutCString(payload.str());1151if (log->GetVerbose()) {1152std::string back_trace;1153llvm::raw_string_ostream stream(back_trace);1154llvm::sys::PrintStackTrace(stream);1155log_message.PutCString(back_trace);1156}1157log->PutCString(log_message.GetData());1158}11591160void Module::Dump(Stream *s) {1161std::lock_guard<std::recursive_mutex> guard(m_mutex);1162// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);1163s->Indent();1164s->Printf("Module %s%s%s%s\n", m_file.GetPath().c_str(),1165m_object_name ? "(" : "",1166m_object_name ? m_object_name.GetCString() : "",1167m_object_name ? ")" : "");11681169s->IndentMore();11701171ObjectFile *objfile = GetObjectFile();1172if (objfile)1173objfile->Dump(s);11741175if (SymbolFile *symbols = GetSymbolFile())1176symbols->Dump(*s);11771178s->IndentLess();1179}11801181ConstString Module::GetObjectName() const { return m_object_name; }11821183ObjectFile *Module::GetObjectFile() {1184if (!m_did_load_objfile.load()) {1185std::lock_guard<std::recursive_mutex> guard(m_mutex);1186if (!m_did_load_objfile.load()) {1187LLDB_SCOPED_TIMERF("Module::GetObjectFile () module = %s",1188GetFileSpec().GetFilename().AsCString(""));1189lldb::offset_t data_offset = 0;1190lldb::offset_t file_size = 0;11911192if (m_data_sp)1193file_size = m_data_sp->GetByteSize();1194else if (m_file)1195file_size = FileSystem::Instance().GetByteSize(m_file);11961197if (file_size > m_object_offset) {1198m_did_load_objfile = true;1199// FindPlugin will modify its data_sp argument. Do not let it1200// modify our m_data_sp member.1201auto data_sp = m_data_sp;1202m_objfile_sp = ObjectFile::FindPlugin(1203shared_from_this(), &m_file, m_object_offset,1204file_size - m_object_offset, data_sp, data_offset);1205if (m_objfile_sp) {1206// Once we get the object file, update our module with the object1207// file's architecture since it might differ in vendor/os if some1208// parts were unknown. But since the matching arch might already be1209// more specific than the generic COFF architecture, only merge in1210// those values that overwrite unspecified unknown values.1211m_arch.MergeFrom(m_objfile_sp->GetArchitecture());1212} else {1213ReportError("failed to load objfile for {0}\nDebugging will be "1214"degraded for this module.",1215GetFileSpec().GetPath().c_str());1216}1217}1218}1219}1220return m_objfile_sp.get();1221}12221223SectionList *Module::GetSectionList() {1224// Populate m_sections_up with sections from objfile.1225if (!m_sections_up) {1226ObjectFile *obj_file = GetObjectFile();1227if (obj_file != nullptr)1228obj_file->CreateSections(*GetUnifiedSectionList());1229}1230return m_sections_up.get();1231}12321233void Module::SectionFileAddressesChanged() {1234ObjectFile *obj_file = GetObjectFile();1235if (obj_file)1236obj_file->SectionFileAddressesChanged();1237if (SymbolFile *symbols = GetSymbolFile())1238symbols->SectionFileAddressesChanged();1239}12401241UnwindTable &Module::GetUnwindTable() {1242if (!m_unwind_table) {1243if (!m_symfile_spec)1244SymbolLocator::DownloadSymbolFileAsync(GetUUID());1245m_unwind_table.emplace(*this);1246}1247return *m_unwind_table;1248}12491250SectionList *Module::GetUnifiedSectionList() {1251if (!m_sections_up)1252m_sections_up = std::make_unique<SectionList>();1253return m_sections_up.get();1254}12551256const Symbol *Module::FindFirstSymbolWithNameAndType(ConstString name,1257SymbolType symbol_type) {1258LLDB_SCOPED_TIMERF(1259"Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",1260name.AsCString(), symbol_type);1261if (Symtab *symtab = GetSymtab())1262return symtab->FindFirstSymbolWithNameAndType(1263name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);1264return nullptr;1265}1266void Module::SymbolIndicesToSymbolContextList(1267Symtab *symtab, std::vector<uint32_t> &symbol_indexes,1268SymbolContextList &sc_list) {1269// No need to protect this call using m_mutex all other method calls are1270// already thread safe.12711272size_t num_indices = symbol_indexes.size();1273if (num_indices > 0) {1274SymbolContext sc;1275CalculateSymbolContext(&sc);1276for (size_t i = 0; i < num_indices; i++) {1277sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);1278if (sc.symbol)1279sc_list.Append(sc);1280}1281}1282}12831284void Module::FindFunctionSymbols(ConstString name, uint32_t name_type_mask,1285SymbolContextList &sc_list) {1286LLDB_SCOPED_TIMERF("Module::FindSymbolsFunctions (name = %s, mask = 0x%8.8x)",1287name.AsCString(), name_type_mask);1288if (Symtab *symtab = GetSymtab())1289symtab->FindFunctionSymbols(name, name_type_mask, sc_list);1290}12911292void Module::FindSymbolsWithNameAndType(ConstString name,1293SymbolType symbol_type,1294SymbolContextList &sc_list) {1295// No need to protect this call using m_mutex all other method calls are1296// already thread safe.1297if (Symtab *symtab = GetSymtab()) {1298std::vector<uint32_t> symbol_indexes;1299symtab->FindAllSymbolsWithNameAndType(name, symbol_type, symbol_indexes);1300SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);1301}1302}13031304void Module::FindSymbolsMatchingRegExAndType(1305const RegularExpression ®ex, SymbolType symbol_type,1306SymbolContextList &sc_list, Mangled::NamePreference mangling_preference) {1307// No need to protect this call using m_mutex all other method calls are1308// already thread safe.1309LLDB_SCOPED_TIMERF(1310"Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",1311regex.GetText().str().c_str(), symbol_type);1312if (Symtab *symtab = GetSymtab()) {1313std::vector<uint32_t> symbol_indexes;1314symtab->FindAllSymbolsMatchingRexExAndType(1315regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny,1316symbol_indexes, mangling_preference);1317SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);1318}1319}13201321void Module::PreloadSymbols() {1322std::lock_guard<std::recursive_mutex> guard(m_mutex);1323SymbolFile *sym_file = GetSymbolFile();1324if (!sym_file)1325return;13261327// Load the object file symbol table and any symbols from the SymbolFile that1328// get appended using SymbolFile::AddSymbols(...).1329if (Symtab *symtab = sym_file->GetSymtab())1330symtab->PreloadSymbols();13311332// Now let the symbol file preload its data and the symbol table will be1333// available without needing to take the module lock.1334sym_file->PreloadSymbols();1335}13361337void Module::SetSymbolFileFileSpec(const FileSpec &file) {1338if (!FileSystem::Instance().Exists(file))1339return;1340if (m_symfile_up) {1341// Remove any sections in the unified section list that come from the1342// current symbol vendor.1343SectionList *section_list = GetSectionList();1344SymbolFile *symbol_file = GetSymbolFile();1345if (section_list && symbol_file) {1346ObjectFile *obj_file = symbol_file->GetObjectFile();1347// Make sure we have an object file and that the symbol vendor's objfile1348// isn't the same as the module's objfile before we remove any sections1349// for it...1350if (obj_file) {1351// Check to make sure we aren't trying to specify the file we already1352// have1353if (obj_file->GetFileSpec() == file) {1354// We are being told to add the exact same file that we already have1355// we don't have to do anything.1356return;1357}13581359// Cleare the current symtab as we are going to replace it with a new1360// one1361obj_file->ClearSymtab();13621363// The symbol file might be a directory bundle ("/tmp/a.out.dSYM")1364// instead of a full path to the symbol file within the bundle1365// ("/tmp/a.out.dSYM/Contents/Resources/DWARF/a.out"). So we need to1366// check this1367if (FileSystem::Instance().IsDirectory(file)) {1368std::string new_path(file.GetPath());1369std::string old_path(obj_file->GetFileSpec().GetPath());1370if (llvm::StringRef(old_path).starts_with(new_path)) {1371// We specified the same bundle as the symbol file that we already1372// have1373return;1374}1375}13761377if (obj_file != m_objfile_sp.get()) {1378size_t num_sections = section_list->GetNumSections(0);1379for (size_t idx = num_sections; idx > 0; --idx) {1380lldb::SectionSP section_sp(1381section_list->GetSectionAtIndex(idx - 1));1382if (section_sp->GetObjectFile() == obj_file) {1383section_list->DeleteSection(idx - 1);1384}1385}1386}1387}1388}1389// Keep all old symbol files around in case there are any lingering type1390// references in any SBValue objects that might have been handed out.1391m_old_symfiles.push_back(std::move(m_symfile_up));1392}1393m_symfile_spec = file;1394m_symfile_up.reset();1395m_did_load_symfile = false;1396}13971398bool Module::IsExecutable() {1399if (GetObjectFile() == nullptr)1400return false;1401else1402return GetObjectFile()->IsExecutable();1403}14041405bool Module::IsLoadedInTarget(Target *target) {1406ObjectFile *obj_file = GetObjectFile();1407if (obj_file) {1408SectionList *sections = GetSectionList();1409if (sections != nullptr) {1410size_t num_sections = sections->GetSize();1411for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++) {1412SectionSP section_sp = sections->GetSectionAtIndex(sect_idx);1413if (section_sp->GetLoadBaseAddress(target) != LLDB_INVALID_ADDRESS) {1414return true;1415}1416}1417}1418}1419return false;1420}14211422bool Module::LoadScriptingResourceInTarget(Target *target, Status &error,1423Stream &feedback_stream) {1424if (!target) {1425error.SetErrorString("invalid destination Target");1426return false;1427}14281429LoadScriptFromSymFile should_load =1430target->TargetProperties::GetLoadScriptFromSymbolFile();14311432if (should_load == eLoadScriptFromSymFileFalse)1433return false;14341435Debugger &debugger = target->GetDebugger();1436const ScriptLanguage script_language = debugger.GetScriptLanguage();1437if (script_language != eScriptLanguageNone) {14381439PlatformSP platform_sp(target->GetPlatform());14401441if (!platform_sp) {1442error.SetErrorString("invalid Platform");1443return false;1444}14451446FileSpecList file_specs = platform_sp->LocateExecutableScriptingResources(1447target, *this, feedback_stream);14481449const uint32_t num_specs = file_specs.GetSize();1450if (num_specs) {1451ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();1452if (script_interpreter) {1453for (uint32_t i = 0; i < num_specs; ++i) {1454FileSpec scripting_fspec(file_specs.GetFileSpecAtIndex(i));1455if (scripting_fspec &&1456FileSystem::Instance().Exists(scripting_fspec)) {1457if (should_load == eLoadScriptFromSymFileWarn) {1458feedback_stream.Printf(1459"warning: '%s' contains a debug script. To run this script "1460"in "1461"this debug session:\n\n command script import "1462"\"%s\"\n\n"1463"To run all discovered debug scripts in this session:\n\n"1464" settings set target.load-script-from-symbol-file "1465"true\n",1466GetFileSpec().GetFileNameStrippingExtension().GetCString(),1467scripting_fspec.GetPath().c_str());1468return false;1469}1470StreamString scripting_stream;1471scripting_fspec.Dump(scripting_stream.AsRawOstream());1472LoadScriptOptions options;1473bool did_load = script_interpreter->LoadScriptingModule(1474scripting_stream.GetData(), options, error);1475if (!did_load)1476return false;1477}1478}1479} else {1480error.SetErrorString("invalid ScriptInterpreter");1481return false;1482}1483}1484}1485return true;1486}14871488bool Module::SetArchitecture(const ArchSpec &new_arch) {1489if (!m_arch.IsValid()) {1490m_arch = new_arch;1491return true;1492}1493return m_arch.IsCompatibleMatch(new_arch);1494}14951496bool Module::SetLoadAddress(Target &target, lldb::addr_t value,1497bool value_is_offset, bool &changed) {1498ObjectFile *object_file = GetObjectFile();1499if (object_file != nullptr) {1500changed = object_file->SetLoadAddress(target, value, value_is_offset);1501return true;1502} else {1503changed = false;1504}1505return false;1506}15071508bool Module::MatchesModuleSpec(const ModuleSpec &module_ref) {1509const UUID &uuid = module_ref.GetUUID();15101511if (uuid.IsValid()) {1512// If the UUID matches, then nothing more needs to match...1513return (uuid == GetUUID());1514}15151516const FileSpec &file_spec = module_ref.GetFileSpec();1517if (!FileSpec::Match(file_spec, m_file) &&1518!FileSpec::Match(file_spec, m_platform_file))1519return false;15201521const FileSpec &platform_file_spec = module_ref.GetPlatformFileSpec();1522if (!FileSpec::Match(platform_file_spec, GetPlatformFileSpec()))1523return false;15241525const ArchSpec &arch = module_ref.GetArchitecture();1526if (arch.IsValid()) {1527if (!m_arch.IsCompatibleMatch(arch))1528return false;1529}15301531ConstString object_name = module_ref.GetObjectName();1532if (object_name) {1533if (object_name != GetObjectName())1534return false;1535}1536return true;1537}15381539bool Module::FindSourceFile(const FileSpec &orig_spec,1540FileSpec &new_spec) const {1541std::lock_guard<std::recursive_mutex> guard(m_mutex);1542if (auto remapped = m_source_mappings.FindFile(orig_spec)) {1543new_spec = *remapped;1544return true;1545}1546return false;1547}15481549std::optional<std::string> Module::RemapSourceFile(llvm::StringRef path) const {1550std::lock_guard<std::recursive_mutex> guard(m_mutex);1551if (auto remapped = m_source_mappings.RemapPath(path))1552return remapped->GetPath();1553return {};1554}15551556void Module::RegisterXcodeSDK(llvm::StringRef sdk_name,1557llvm::StringRef sysroot) {1558auto sdk_path_or_err =1559HostInfo::GetSDKRoot(HostInfo::SDKOptions{sdk_name.str()});15601561if (!sdk_path_or_err) {1562Debugger::ReportError("Error while searching for Xcode SDK: " +1563toString(sdk_path_or_err.takeError()));1564return;1565}15661567auto sdk_path = *sdk_path_or_err;1568if (sdk_path.empty())1569return;1570// If the SDK changed for a previously registered source path, update it.1571// This could happend with -fdebug-prefix-map, otherwise it's unlikely.1572if (!m_source_mappings.Replace(sysroot, sdk_path, true))1573// In the general case, however, append it to the list.1574m_source_mappings.Append(sysroot, sdk_path, false);1575}15761577bool Module::MergeArchitecture(const ArchSpec &arch_spec) {1578if (!arch_spec.IsValid())1579return false;1580LLDB_LOGF(GetLog(LLDBLog::Object | LLDBLog::Modules),1581"module has arch %s, merging/replacing with arch %s",1582m_arch.GetTriple().getTriple().c_str(),1583arch_spec.GetTriple().getTriple().c_str());1584if (!m_arch.IsCompatibleMatch(arch_spec)) {1585// The new architecture is different, we just need to replace it.1586return SetArchitecture(arch_spec);1587}15881589// Merge bits from arch_spec into "merged_arch" and set our architecture.1590ArchSpec merged_arch(m_arch);1591merged_arch.MergeFrom(arch_spec);1592// SetArchitecture() is a no-op if m_arch is already valid.1593m_arch = ArchSpec();1594return SetArchitecture(merged_arch);1595}15961597llvm::VersionTuple Module::GetVersion() {1598if (ObjectFile *obj_file = GetObjectFile())1599return obj_file->GetVersion();1600return llvm::VersionTuple();1601}16021603bool Module::GetIsDynamicLinkEditor() {1604ObjectFile *obj_file = GetObjectFile();16051606if (obj_file)1607return obj_file->GetIsDynamicLinkEditor();16081609return false;1610}16111612uint32_t Module::Hash() {1613std::string identifier;1614llvm::raw_string_ostream id_strm(identifier);1615id_strm << m_arch.GetTriple().str() << '-' << m_file.GetPath();1616if (m_object_name)1617id_strm << '(' << m_object_name << ')';1618if (m_object_offset > 0)1619id_strm << m_object_offset;1620const auto mtime = llvm::sys::toTimeT(m_object_mod_time);1621if (mtime > 0)1622id_strm << mtime;1623return llvm::djbHash(id_strm.str());1624}16251626std::string Module::GetCacheKey() {1627std::string key;1628llvm::raw_string_ostream strm(key);1629strm << m_arch.GetTriple().str() << '-' << m_file.GetFilename();1630if (m_object_name)1631strm << '(' << m_object_name << ')';1632strm << '-' << llvm::format_hex(Hash(), 10);1633return strm.str();1634}16351636DataFileCache *Module::GetIndexCache() {1637if (!ModuleList::GetGlobalModuleListProperties().GetEnableLLDBIndexCache())1638return nullptr;1639// NOTE: intentional leak so we don't crash if global destructor chain gets1640// called as other threads still use the result of this function1641static DataFileCache *g_data_file_cache =1642new DataFileCache(ModuleList::GetGlobalModuleListProperties()1643.GetLLDBIndexCachePath()1644.GetPath());1645return g_data_file_cache;1646}164716481649