brintos

brintos / llvm-project-archived public Read only

0
0
Text · 59.4 KiB · 815cc9d Raw
1647 lines · cpp
1//===-- Module.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/Core/Module.h"10 11#include "lldb/Core/AddressRange.h"12#include "lldb/Core/AddressResolverFileLine.h"13#include "lldb/Core/DataFileCache.h"14#include "lldb/Core/Debugger.h"15#include "lldb/Core/Mangled.h"16#include "lldb/Core/ModuleSpec.h"17#include "lldb/Core/SearchFilter.h"18#include "lldb/Core/Section.h"19#include "lldb/Host/FileSystem.h"20#include "lldb/Host/Host.h"21#include "lldb/Host/HostInfo.h"22#include "lldb/Interpreter/CommandInterpreter.h"23#include "lldb/Interpreter/ScriptInterpreter.h"24#include "lldb/Symbol/CompileUnit.h"25#include "lldb/Symbol/Function.h"26#include "lldb/Symbol/ObjectFile.h"27#include "lldb/Symbol/Symbol.h"28#include "lldb/Symbol/SymbolContext.h"29#include "lldb/Symbol/SymbolFile.h"30#include "lldb/Symbol/SymbolLocator.h"31#include "lldb/Symbol/SymbolVendor.h"32#include "lldb/Symbol/Symtab.h"33#include "lldb/Symbol/Type.h"34#include "lldb/Symbol/TypeList.h"35#include "lldb/Symbol/TypeMap.h"36#include "lldb/Symbol/TypeSystem.h"37#include "lldb/Target/Language.h"38#include "lldb/Target/Process.h"39#include "lldb/Target/Target.h"40#include "lldb/Utility/DataBufferHeap.h"41#include "lldb/Utility/FileSpecList.h"42#include "lldb/Utility/LLDBAssert.h"43#include "lldb/Utility/LLDBLog.h"44#include "lldb/Utility/Log.h"45#include "lldb/Utility/RegularExpression.h"46#include "lldb/Utility/Status.h"47#include "lldb/Utility/Stream.h"48#include "lldb/Utility/StreamString.h"49#include "lldb/Utility/Timer.h"50 51#if defined(_WIN32)52#include "lldb/Host/windows/PosixApi.h"53#endif54 55#include "llvm/ADT/STLExtras.h"56#include "llvm/Support/Compiler.h"57#include "llvm/Support/DJB.h"58#include "llvm/Support/FileSystem.h"59#include "llvm/Support/FormatVariadic.h"60#include "llvm/Support/JSON.h"61#include "llvm/Support/Signals.h"62#include "llvm/Support/raw_ostream.h"63 64#include <cassert>65#include <cinttypes>66#include <cstdarg>67#include <cstdint>68#include <cstring>69#include <map>70#include <optional>71#include <type_traits>72#include <utility>73 74namespace lldb_private {75class CompilerDeclContext;76}77namespace lldb_private {78class VariableList;79}80 81using namespace lldb;82using namespace lldb_private;83 84// Shared pointers to modules track module lifetimes in targets and in the85// global module, but this collection will track all module objects that are86// still alive87typedef std::vector<Module *> ModuleCollection;88 89static ModuleCollection &GetModuleCollection() {90  // This module collection needs to live past any module, so we could either91  // make it a shared pointer in each module or just leak is.  Since it is only92  // an empty vector by the time all the modules have gone away, we just leak93  // it for now.  If we decide this is a big problem we can introduce a94  // Finalize method that will tear everything down in a predictable order.95 96  static ModuleCollection *g_module_collection = nullptr;97  if (g_module_collection == nullptr)98    g_module_collection = new ModuleCollection();99 100  return *g_module_collection;101}102 103std::recursive_mutex &Module::GetAllocationModuleCollectionMutex() {104  // NOTE: The mutex below must be leaked since the global module list in105  // the ModuleList class will get torn at some point, and we can't know if it106  // will tear itself down before the "g_module_collection_mutex" below will.107  // So we leak a Mutex object below to safeguard against that108 109  static std::recursive_mutex *g_module_collection_mutex = nullptr;110  if (g_module_collection_mutex == nullptr)111    g_module_collection_mutex = new std::recursive_mutex; // NOTE: known leak112  return *g_module_collection_mutex;113}114 115size_t Module::GetNumberAllocatedModules() {116  std::lock_guard<std::recursive_mutex> guard(117      GetAllocationModuleCollectionMutex());118  return GetModuleCollection().size();119}120 121Module *Module::GetAllocatedModuleAtIndex(size_t idx) {122  std::lock_guard<std::recursive_mutex> guard(123      GetAllocationModuleCollectionMutex());124  ModuleCollection &modules = GetModuleCollection();125  if (idx < modules.size())126    return modules[idx];127  return nullptr;128}129 130static std::atomic<lldb::user_id_t> g_unique_id = 1;131 132Module::Module(const ModuleSpec &module_spec)133    : UserID(g_unique_id++), m_unwind_table(*this), m_file_has_changed(false),134      m_first_file_changed_log(false) {135  // Scope for locker below...136  {137    std::lock_guard<std::recursive_mutex> guard(138        GetAllocationModuleCollectionMutex());139    GetModuleCollection().push_back(this);140  }141 142  Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules));143  if (log != nullptr)144    LLDB_LOGF(log, "%p Module::Module((%s) '%s%s%s%s')",145              static_cast<void *>(this),146              module_spec.GetArchitecture().GetArchitectureName(),147              module_spec.GetFileSpec().GetPath().c_str(),148              module_spec.GetObjectName().IsEmpty() ? "" : "(",149              module_spec.GetObjectName().AsCString(""),150              module_spec.GetObjectName().IsEmpty() ? "" : ")");151 152  auto data_sp = module_spec.GetData();153  lldb::offset_t file_size = 0;154  if (data_sp)155    file_size = data_sp->GetByteSize();156 157  // First extract all module specifications from the file using the local file158  // path. If there are no specifications, then don't fill anything in159  ModuleSpecList modules_specs;160  if (ObjectFile::GetModuleSpecifications(161          module_spec.GetFileSpec(), 0, file_size, modules_specs, data_sp) == 0)162    return;163 164  // Now make sure that one of the module specifications matches what we just165  // extract. We might have a module specification that specifies a file166  // "/usr/lib/dyld" with UUID XXX, but we might have a local version of167  // "/usr/lib/dyld" that has168  // UUID YYY and we don't want those to match. If they don't match, just don't169  // fill any ivars in so we don't accidentally grab the wrong file later since170  // they don't match...171  ModuleSpec matching_module_spec;172  if (!modules_specs.FindMatchingModuleSpec(module_spec,173                                            matching_module_spec)) {174    if (log) {175      LLDB_LOGF(log, "Found local object file but the specs didn't match");176    }177    return;178  }179 180  // Set m_data_sp if it was initially provided in the ModuleSpec. Note that181  // we cannot use the data_sp variable here, because it will have been182  // modified by GetModuleSpecifications().183  if (auto module_spec_data_sp = module_spec.GetData()) {184    m_data_sp = module_spec_data_sp;185    m_mod_time = {};186  } else {187    if (module_spec.GetFileSpec())188      m_mod_time =189          FileSystem::Instance().GetModificationTime(module_spec.GetFileSpec());190    else if (matching_module_spec.GetFileSpec())191      m_mod_time = FileSystem::Instance().GetModificationTime(192          matching_module_spec.GetFileSpec());193  }194 195  // Copy the architecture from the actual spec if we got one back, else use196  // the one that was specified197  if (matching_module_spec.GetArchitecture().IsValid())198    m_arch = matching_module_spec.GetArchitecture();199  else if (module_spec.GetArchitecture().IsValid())200    m_arch = module_spec.GetArchitecture();201 202  // Copy the file spec over and use the specified one (if there was one) so we203  // don't use a path that might have gotten resolved a path in204  // 'matching_module_spec'205  if (module_spec.GetFileSpec())206    m_file = module_spec.GetFileSpec();207  else if (matching_module_spec.GetFileSpec())208    m_file = matching_module_spec.GetFileSpec();209 210  // Copy the platform file spec over211  if (module_spec.GetPlatformFileSpec())212    m_platform_file = module_spec.GetPlatformFileSpec();213  else if (matching_module_spec.GetPlatformFileSpec())214    m_platform_file = matching_module_spec.GetPlatformFileSpec();215 216  // Copy the symbol file spec over217  if (module_spec.GetSymbolFileSpec())218    m_symfile_spec = module_spec.GetSymbolFileSpec();219  else if (matching_module_spec.GetSymbolFileSpec())220    m_symfile_spec = matching_module_spec.GetSymbolFileSpec();221 222  // Copy the object name over223  if (matching_module_spec.GetObjectName())224    m_object_name = matching_module_spec.GetObjectName();225  else226    m_object_name = module_spec.GetObjectName();227 228  // Always trust the object offset (file offset) and object modification time229  // (for mod time in a BSD static archive) of from the matching module230  // specification231  m_object_offset = matching_module_spec.GetObjectOffset();232  m_object_mod_time = matching_module_spec.GetObjectModificationTime();233}234 235Module::Module(const FileSpec &file_spec, const ArchSpec &arch,236               ConstString object_name, lldb::offset_t object_offset,237               const llvm::sys::TimePoint<> &object_mod_time)238    : UserID(g_unique_id++),239      m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)),240      m_arch(arch), m_file(file_spec), m_object_name(object_name),241      m_object_offset(object_offset), m_object_mod_time(object_mod_time),242      m_unwind_table(*this), m_file_has_changed(false),243      m_first_file_changed_log(false) {244  // Scope for locker below...245  {246    std::lock_guard<std::recursive_mutex> guard(247        GetAllocationModuleCollectionMutex());248    GetModuleCollection().push_back(this);249  }250 251  Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules));252  if (log != nullptr)253    LLDB_LOGF(log, "%p Module::Module((%s) '%s%s%s%s')",254              static_cast<void *>(this), m_arch.GetArchitectureName(),255              m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",256              m_object_name.AsCString(""), m_object_name.IsEmpty() ? "" : ")");257}258 259Module::Module()260    : UserID(g_unique_id++), m_unwind_table(*this), m_file_has_changed(false),261      m_first_file_changed_log(false) {262  std::lock_guard<std::recursive_mutex> guard(263      GetAllocationModuleCollectionMutex());264  GetModuleCollection().push_back(this);265}266 267Module::~Module() {268  // Lock our module down while we tear everything down to make sure we don't269  // get any access to the module while it is being destroyed270  std::lock_guard<std::recursive_mutex> guard(m_mutex);271  // Scope for locker below...272  {273    std::lock_guard<std::recursive_mutex> guard(274        GetAllocationModuleCollectionMutex());275    ModuleCollection &modules = GetModuleCollection();276    ModuleCollection::iterator end = modules.end();277    ModuleCollection::iterator pos = std::find(modules.begin(), end, this);278    assert(pos != end);279    modules.erase(pos);280  }281  Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules));282  if (log != nullptr)283    LLDB_LOGF(log, "%p Module::~Module((%s) '%s%s%s%s')",284              static_cast<void *>(this), m_arch.GetArchitectureName(),285              m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",286              m_object_name.AsCString(""), m_object_name.IsEmpty() ? "" : ")");287  // Release any auto pointers before we start tearing down our member288  // variables since the object file and symbol files might need to make289  // function calls back into this module object. The ordering is important290  // here because symbol files can require the module object file. So we tear291  // down the symbol file first, then the object file.292  m_sections_up.reset();293  m_symfile_up.reset();294  m_objfile_sp.reset();295}296 297ObjectFile *Module::GetMemoryObjectFile(const lldb::ProcessSP &process_sp,298                                        lldb::addr_t header_addr, Status &error,299                                        size_t size_to_read) {300  if (m_objfile_sp) {301    error = Status::FromErrorString("object file already exists");302  } else {303    std::lock_guard<std::recursive_mutex> guard(m_mutex);304    if (process_sp) {305      m_did_load_objfile = true;306      std::shared_ptr<DataBufferHeap> data_sp =307          std::make_shared<DataBufferHeap>(size_to_read, 0);308      Status readmem_error;309      const size_t bytes_read =310          process_sp->ReadMemory(header_addr, data_sp->GetBytes(),311                                 data_sp->GetByteSize(), readmem_error);312      if (bytes_read < size_to_read)313        data_sp->SetByteSize(bytes_read);314      if (data_sp->GetByteSize() > 0) {315        m_objfile_sp = ObjectFile::FindPlugin(shared_from_this(), process_sp,316                                              header_addr, data_sp);317        if (m_objfile_sp) {318          StreamString s;319          s.Printf("0x%16.16" PRIx64, header_addr);320          m_object_name.SetString(s.GetString());321 322          // Once we get the object file, update our module with the object323          // file's architecture since it might differ in vendor/os if some324          // parts were unknown.325          m_arch = m_objfile_sp->GetArchitecture();326 327          // Augment the arch with the target's information in case328          // we are unable to extract the os/environment from memory.329          m_arch.MergeFrom(process_sp->GetTarget().GetArchitecture());330 331          m_unwind_table.ModuleWasUpdated();332        } else {333          error = Status::FromErrorString(334              "unable to find suitable object file plug-in");335        }336      } else {337        error = Status::FromErrorStringWithFormat(338            "unable to read header from memory: %s", readmem_error.AsCString());339      }340    } else {341      error = Status::FromErrorString("invalid process");342    }343  }344  return m_objfile_sp.get();345}346 347const lldb_private::UUID &Module::GetUUID() {348  if (!m_did_set_uuid.load()) {349    std::lock_guard<std::recursive_mutex> guard(m_mutex);350    if (!m_did_set_uuid.load()) {351      ObjectFile *obj_file = GetObjectFile();352 353      if (obj_file != nullptr) {354        m_uuid = obj_file->GetUUID();355        m_did_set_uuid = true;356      }357    }358  }359  return m_uuid;360}361 362void Module::SetUUID(const lldb_private::UUID &uuid) {363  std::lock_guard<std::recursive_mutex> guard(m_mutex);364  if (!m_did_set_uuid) {365    m_uuid = uuid;366    m_did_set_uuid = true;367  } else {368    lldbassert(0 && "Attempting to overwrite the existing module UUID");369  }370}371 372llvm::Expected<TypeSystemSP>373Module::GetTypeSystemForLanguage(LanguageType language) {374  return m_type_system_map.GetTypeSystemForLanguage(language, this, true);375}376 377void Module::ForEachTypeSystem(378    llvm::function_ref<bool(lldb::TypeSystemSP)> callback) {379  m_type_system_map.ForEach(callback);380}381 382void Module::ParseAllDebugSymbols() {383  std::lock_guard<std::recursive_mutex> guard(m_mutex);384  size_t num_comp_units = GetNumCompileUnits();385  if (num_comp_units == 0)386    return;387 388  SymbolFile *symbols = GetSymbolFile();389 390  for (size_t cu_idx = 0; cu_idx < num_comp_units; cu_idx++) {391    SymbolContext sc;392    sc.module_sp = shared_from_this();393    sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get();394    if (!sc.comp_unit)395      continue;396 397    symbols->ParseVariablesForContext(sc);398 399    symbols->ParseFunctions(*sc.comp_unit);400 401    sc.comp_unit->ForeachFunction([&sc, &symbols](const FunctionSP &f) {402      symbols->ParseBlocksRecursive(*f);403 404      // Parse the variables for this function and all its blocks405      sc.function = f.get();406      symbols->ParseVariablesForContext(sc);407      return false;408    });409 410    // Parse all types for this compile unit411    symbols->ParseTypes(*sc.comp_unit);412  }413}414 415void Module::CalculateSymbolContext(SymbolContext *sc) {416  sc->module_sp = shared_from_this();417}418 419ModuleSP Module::CalculateSymbolContextModule() { return shared_from_this(); }420 421void Module::DumpSymbolContext(Stream *s) {422  s->Printf(", Module{%p}", static_cast<void *>(this));423}424 425size_t Module::GetNumCompileUnits() {426  std::lock_guard<std::recursive_mutex> guard(m_mutex);427  if (SymbolFile *symbols = GetSymbolFile())428    return symbols->GetNumCompileUnits();429  return 0;430}431 432CompUnitSP Module::GetCompileUnitAtIndex(size_t index) {433  std::lock_guard<std::recursive_mutex> guard(m_mutex);434  size_t num_comp_units = GetNumCompileUnits();435  CompUnitSP cu_sp;436 437  if (index < num_comp_units) {438    if (SymbolFile *symbols = GetSymbolFile())439      cu_sp = symbols->GetCompileUnitAtIndex(index);440  }441  return cu_sp;442}443 444bool Module::ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) {445  std::lock_guard<std::recursive_mutex> guard(m_mutex);446  SectionList *section_list = GetSectionList();447  if (section_list)448    return so_addr.ResolveAddressUsingFileSections(vm_addr, section_list);449  return false;450}451 452uint32_t Module::ResolveSymbolContextForAddress(453    const Address &so_addr, lldb::SymbolContextItem resolve_scope,454    SymbolContext &sc, bool resolve_tail_call_address) {455  std::lock_guard<std::recursive_mutex> guard(m_mutex);456  uint32_t resolved_flags = 0;457 458  // Clear the result symbol context in case we don't find anything, but don't459  // clear the target460  sc.Clear(false);461 462  // Get the section from the section/offset address.463  SectionSP section_sp(so_addr.GetSection());464 465  // Make sure the section matches this module before we try and match anything466  if (section_sp && section_sp->GetModule().get() == this) {467    // If the section offset based address resolved itself, then this is the468    // right module.469    sc.module_sp = shared_from_this();470    resolved_flags |= eSymbolContextModule;471 472    SymbolFile *symfile = GetSymbolFile();473    if (!symfile)474      return resolved_flags;475 476    // Resolve the compile unit, function, block, line table or line entry if477    // requested.478    if (resolve_scope & eSymbolContextCompUnit ||479        resolve_scope & eSymbolContextFunction ||480        resolve_scope & eSymbolContextBlock ||481        resolve_scope & eSymbolContextLineEntry ||482        resolve_scope & eSymbolContextVariable) {483      symfile->SetLoadDebugInfoEnabled();484      resolved_flags |=485          symfile->ResolveSymbolContext(so_addr, resolve_scope, sc);486 487      if ((resolve_scope & eSymbolContextLineEntry) && sc.line_entry.IsValid())488        sc.line_entry.ApplyFileMappings(sc.target_sp);489    }490 491    // Resolve the symbol if requested, but don't re-look it up if we've492    // already found it.493    if (resolve_scope & eSymbolContextSymbol &&494        !(resolved_flags & eSymbolContextSymbol)) {495      Symtab *symtab = symfile->GetSymtab();496      if (symtab && so_addr.IsSectionOffset()) {497        Symbol *matching_symbol = nullptr;498 499        symtab->ForEachSymbolContainingFileAddress(500            so_addr.GetFileAddress(),501            [&matching_symbol](Symbol *symbol) -> bool {502              if (symbol->GetType() != eSymbolTypeInvalid) {503                matching_symbol = symbol;504                return false; // Stop iterating505              }506              return true; // Keep iterating507            });508        sc.symbol = matching_symbol;509        if (!sc.symbol && resolve_scope & eSymbolContextFunction &&510            !(resolved_flags & eSymbolContextFunction)) {511          bool verify_unique = false; // No need to check again since512                                      // ResolveSymbolContext failed to find a513                                      // symbol at this address.514          if (ObjectFile *obj_file = sc.module_sp->GetObjectFile())515            sc.symbol =516                obj_file->ResolveSymbolForAddress(so_addr, verify_unique);517        }518 519        if (sc.symbol) {520          if (sc.symbol->IsSynthetic()) {521            // We have a synthetic symbol so lets check if the object file from522            // the symbol file in the symbol vendor is different than the523            // object file for the module, and if so search its symbol table to524            // see if we can come up with a better symbol. For example dSYM525            // files on MacOSX have an unstripped symbol table inside of them.526            ObjectFile *symtab_objfile = symtab->GetObjectFile();527            if (symtab_objfile && symtab_objfile->IsStripped()) {528              ObjectFile *symfile_objfile = symfile->GetObjectFile();529              if (symfile_objfile != symtab_objfile) {530                Symtab *symfile_symtab = symfile_objfile->GetSymtab();531                if (symfile_symtab) {532                  Symbol *symbol =533                      symfile_symtab->FindSymbolContainingFileAddress(534                          so_addr.GetFileAddress());535                  if (symbol && !symbol->IsSynthetic()) {536                    sc.symbol = symbol;537                  }538                }539              }540            }541          }542          resolved_flags |= eSymbolContextSymbol;543        }544      }545    }546 547    // For function symbols, so_addr may be off by one.  This is a convention548    // consistent with FDE row indices in eh_frame sections, but requires extra549    // logic here to permit symbol lookup for disassembly and unwind.550    if (resolve_scope & eSymbolContextSymbol &&551        !(resolved_flags & eSymbolContextSymbol) && resolve_tail_call_address &&552        so_addr.IsSectionOffset()) {553      Address previous_addr = so_addr;554      previous_addr.Slide(-1);555 556      bool do_resolve_tail_call_address = false; // prevent recursion557      const uint32_t flags = ResolveSymbolContextForAddress(558          previous_addr, resolve_scope, sc, do_resolve_tail_call_address);559      if (flags & eSymbolContextSymbol) {560        AddressRange addr_range;561        if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,562                               false, addr_range)) {563          if (addr_range.GetBaseAddress().GetSection() ==564              so_addr.GetSection()) {565            // If the requested address is one past the address range of a566            // function (i.e. a tail call), or the decremented address is the567            // start of a function (i.e. some forms of trampoline), indicate568            // that the symbol has been resolved.569            if (so_addr.GetOffset() ==570                    addr_range.GetBaseAddress().GetOffset() ||571                so_addr.GetOffset() == addr_range.GetBaseAddress().GetOffset() +572                                           addr_range.GetByteSize()) {573              resolved_flags |= flags;574            }575          } else {576            sc.symbol =577                nullptr; // Don't trust the symbol if the sections didn't match.578          }579        }580      }581    }582  }583  return resolved_flags;584}585 586uint32_t Module::ResolveSymbolContextForFilePath(587    const char *file_path, uint32_t line, bool check_inlines,588    lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {589  FileSpec file_spec(file_path);590  return ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,591                                          resolve_scope, sc_list);592}593 594uint32_t Module::ResolveSymbolContextsForFileSpec(595    const FileSpec &file_spec, uint32_t line, bool check_inlines,596    lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {597  std::lock_guard<std::recursive_mutex> guard(m_mutex);598  LLDB_SCOPED_TIMERF("Module::ResolveSymbolContextForFilePath (%s:%u, "599                     "check_inlines = %s, resolve_scope = 0x%8.8x)",600                     file_spec.GetPath().c_str(), line,601                     check_inlines ? "yes" : "no", resolve_scope);602 603  const uint32_t initial_count = sc_list.GetSize();604 605  if (SymbolFile *symbols = GetSymbolFile()) {606    // TODO: Handle SourceLocationSpec column information607    SourceLocationSpec location_spec(file_spec, line, /*column=*/std::nullopt,608                                     check_inlines, /*exact_match=*/false);609 610    symbols->ResolveSymbolContext(location_spec, resolve_scope, sc_list);611  }612 613  return sc_list.GetSize() - initial_count;614}615 616void Module::FindGlobalVariables(ConstString name,617                                 const CompilerDeclContext &parent_decl_ctx,618                                 size_t max_matches, VariableList &variables) {619  if (SymbolFile *symbols = GetSymbolFile())620    symbols->FindGlobalVariables(name, parent_decl_ctx, max_matches, variables);621}622 623void Module::FindGlobalVariables(const RegularExpression &regex,624                                 size_t max_matches, VariableList &variables) {625  SymbolFile *symbols = GetSymbolFile();626  if (symbols)627    symbols->FindGlobalVariables(regex, max_matches, variables);628}629 630void Module::FindCompileUnits(const FileSpec &path,631                              SymbolContextList &sc_list) {632  const size_t num_compile_units = GetNumCompileUnits();633  SymbolContext sc;634  sc.module_sp = shared_from_this();635  for (size_t i = 0; i < num_compile_units; ++i) {636    sc.comp_unit = GetCompileUnitAtIndex(i).get();637    if (sc.comp_unit) {638      if (FileSpec::Match(path, sc.comp_unit->GetPrimaryFile()))639        sc_list.Append(sc);640    }641  }642}643 644Module::LookupInfo::LookupInfo(ConstString name,645                               FunctionNameType name_type_mask,646                               LanguageType language)647    : m_name(name), m_lookup_name(name), m_language(language) {648  std::optional<ConstString> basename;649 650  std::vector<Language *> languages;651  {652    std::vector<LanguageType> lang_types;653    if (language != eLanguageTypeUnknown)654      lang_types.push_back(language);655    else656      lang_types = {eLanguageTypeObjC, eLanguageTypeC_plus_plus};657 658    for (LanguageType lang_type : lang_types) {659      if (Language *lang = Language::FindPlugin(lang_type))660        languages.push_back(lang);661    }662  }663 664  if (name_type_mask & eFunctionNameTypeAuto) {665    for (Language *lang : languages) {666      auto info = lang->GetFunctionNameInfo(name);667      if (info.first != eFunctionNameTypeNone) {668        m_name_type_mask |= info.first;669        if (!basename && info.second)670          basename = info.second;671      }672    }673 674    // NOTE: There are several ways to get here, but this is a fallback path in675    // case the above does not succeed at extracting any useful information from676    // the loaded language plugins.677    if (m_name_type_mask == eFunctionNameTypeNone)678      m_name_type_mask = eFunctionNameTypeFull;679 680  } else {681    m_name_type_mask = name_type_mask;682    for (Language *lang : languages) {683      auto info = lang->GetFunctionNameInfo(name);684      if (info.first & m_name_type_mask) {685        // If the user asked for FunctionNameTypes that aren't possible,686        // then filter those out. (e.g. asking for Selectors on687        // C++ symbols, or even if the symbol given can't be a selector in688        // ObjC)689        m_name_type_mask &= info.first;690        basename = info.second;691        break;692      }693      // Still try and get a basename in case someone specifies a name type mask694      // of eFunctionNameTypeFull and a name like "A::func"695      if (name_type_mask & eFunctionNameTypeFull &&696          info.first != eFunctionNameTypeNone && !basename && info.second) {697        basename = info.second;698        break;699      }700    }701  }702 703  if (basename) {704    // The name supplied was incomplete for lookup purposes. For example, in C++705    // we may have gotten something like "a::count". In this case, we want to do706    // a lookup on the basename "count" and then make sure any matching results707    // contain "a::count" so that it would match "b::a::count" and "a::count".708    // This is why we set match_name_after_lookup to true.709    m_lookup_name.SetString(*basename);710    m_match_name_after_lookup = true;711  }712}713 714bool Module::LookupInfo::NameMatchesLookupInfo(715    ConstString function_name, LanguageType language_type) const {716  // We always keep unnamed symbols717  if (!function_name)718    return true;719 720  // If we match exactly, we can return early721  if (m_name == function_name)722    return true;723 724  // If function_name is mangled, we'll need to demangle it.725  // In the pathologial case where the function name "looks" mangled but is726  // actually demangled (e.g. a method named _Zonk), this operation should be727  // relatively inexpensive since no demangling is actually occuring. See728  // Mangled::SetValue for more context.729  const bool function_name_may_be_mangled =730      Mangled::GetManglingScheme(function_name) != Mangled::eManglingSchemeNone;731  ConstString demangled_function_name = function_name;732  if (function_name_may_be_mangled) {733    Mangled mangled_function_name(function_name);734    demangled_function_name = mangled_function_name.GetDemangledName();735  }736 737  // If the symbol has a language, then let the language make the match.738  // Otherwise just check that the demangled function name contains the739  // demangled user-provided name.740  if (Language *language = Language::FindPlugin(language_type))741    return language->DemangledNameContainsPath(m_name, demangled_function_name);742 743  llvm::StringRef function_name_ref = demangled_function_name;744  return function_name_ref.contains(m_name);745}746 747void Module::LookupInfo::Prune(SymbolContextList &sc_list,748                               size_t start_idx) const {749  if (m_match_name_after_lookup && m_name) {750    SymbolContext sc;751    size_t i = start_idx;752    while (i < sc_list.GetSize()) {753      if (!sc_list.GetContextAtIndex(i, sc))754        break;755 756      bool keep_it =757          NameMatchesLookupInfo(sc.GetFunctionName(), sc.GetLanguage());758      if (keep_it)759        ++i;760      else761        sc_list.RemoveContextAtIndex(i);762    }763  }764 765  // If we have only full name matches we might have tried to set breakpoint on766  // "func" and specified eFunctionNameTypeFull, but we might have found767  // "a::func()", "a::b::func()", "c::func()", "func()" and "func". Only768  // "func()" and "func" should end up matching.769  auto *lang = Language::FindPlugin(eLanguageTypeC_plus_plus);770  if (lang && m_name_type_mask == eFunctionNameTypeFull) {771    SymbolContext sc;772    size_t i = start_idx;773    while (i < sc_list.GetSize()) {774      if (!sc_list.GetContextAtIndex(i, sc))775        break;776      // Make sure the mangled and demangled names don't match before we try to777      // pull anything out778      ConstString mangled_name(sc.GetFunctionName(Mangled::ePreferMangled));779      ConstString full_name(sc.GetFunctionName());780      if (mangled_name != m_name && full_name != m_name) {781        std::unique_ptr<Language::MethodName> cpp_method =782            lang->GetMethodName(full_name);783        if (cpp_method->IsValid()) {784          if (cpp_method->GetContext().empty()) {785            if (cpp_method->GetBasename().compare(m_name) != 0) {786              sc_list.RemoveContextAtIndex(i);787              continue;788            }789          } else {790            std::string qualified_name;791            llvm::StringRef anon_prefix("(anonymous namespace)");792            if (cpp_method->GetContext() == anon_prefix)793              qualified_name = cpp_method->GetBasename().str();794            else795              qualified_name = cpp_method->GetScopeQualifiedName();796            if (qualified_name != m_name.GetCString()) {797              sc_list.RemoveContextAtIndex(i);798              continue;799            }800          }801        }802      }803      ++i;804    }805  }806}807 808void Module::FindFunctions(const Module::LookupInfo &lookup_info,809                           const CompilerDeclContext &parent_decl_ctx,810                           const ModuleFunctionSearchOptions &options,811                           SymbolContextList &sc_list) {812  // Find all the functions (not symbols, but debug information functions...813  if (SymbolFile *symbols = GetSymbolFile()) {814    symbols->FindFunctions(lookup_info, parent_decl_ctx,815                           options.include_inlines, sc_list);816    // Now check our symbol table for symbols that are code symbols if817    // requested818    if (options.include_symbols) {819      if (Symtab *symtab = symbols->GetSymtab()) {820        symtab->FindFunctionSymbols(lookup_info.GetLookupName(),821                                    lookup_info.GetNameTypeMask(), sc_list);822      }823    }824  }825}826 827void Module::FindFunctions(ConstString name,828                           const CompilerDeclContext &parent_decl_ctx,829                           FunctionNameType name_type_mask,830                           const ModuleFunctionSearchOptions &options,831                           SymbolContextList &sc_list) {832  const size_t old_size = sc_list.GetSize();833  LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);834  FindFunctions(lookup_info, parent_decl_ctx, options, sc_list);835  if (name_type_mask & eFunctionNameTypeAuto) {836    const size_t new_size = sc_list.GetSize();837    if (old_size < new_size)838      lookup_info.Prune(sc_list, old_size);839  }840}841 842void Module::FindFunctions(llvm::ArrayRef<CompilerContext> compiler_ctx,843                           FunctionNameType name_type_mask,844                           const ModuleFunctionSearchOptions &options,845                           SymbolContextList &sc_list) {846  if (compiler_ctx.empty() ||847      compiler_ctx.back().kind != CompilerContextKind::Function)848    return;849  ConstString name = compiler_ctx.back().name;850  SymbolContextList unfiltered;851  FindFunctions(name, CompilerDeclContext(), name_type_mask, options,852                unfiltered);853  // Filter by context.854  for (auto &sc : unfiltered)855    if (sc.function && compiler_ctx.equals(sc.function->GetCompilerContext()))856      sc_list.Append(sc);857}858 859void Module::FindFunctions(const RegularExpression &regex,860                           const ModuleFunctionSearchOptions &options,861                           SymbolContextList &sc_list) {862  const size_t start_size = sc_list.GetSize();863 864  if (SymbolFile *symbols = GetSymbolFile()) {865    symbols->FindFunctions(regex, options.include_inlines, sc_list);866 867    // Now check our symbol table for symbols that are code symbols if868    // requested869    if (options.include_symbols) {870      Symtab *symtab = symbols->GetSymtab();871      if (symtab) {872        std::vector<uint32_t> symbol_indexes;873        symtab->AppendSymbolIndexesMatchingRegExAndType(874            regex, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny,875            symbol_indexes);876        const size_t num_matches = symbol_indexes.size();877        if (num_matches) {878          SymbolContext sc(this);879          const size_t end_functions_added_index = sc_list.GetSize();880          size_t num_functions_added_to_sc_list =881              end_functions_added_index - start_size;882          if (num_functions_added_to_sc_list == 0) {883            // No functions were added, just symbols, so we can just append884            // them885            for (size_t i = 0; i < num_matches; ++i) {886              sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);887              SymbolType sym_type = sc.symbol->GetType();888              if (sc.symbol && (sym_type == eSymbolTypeCode ||889                                sym_type == eSymbolTypeResolver))890                sc_list.Append(sc);891            }892          } else {893            typedef std::map<lldb::addr_t, uint32_t> FileAddrToIndexMap;894            FileAddrToIndexMap file_addr_to_index;895            for (size_t i = start_size; i < end_functions_added_index; ++i) {896              const SymbolContext &sc = sc_list[i];897              if (sc.block)898                continue;899              file_addr_to_index[sc.function->GetAddress().GetFileAddress()] =900                  i;901            }902 903            FileAddrToIndexMap::const_iterator end = file_addr_to_index.end();904            // Functions were added so we need to merge symbols into any905            // existing function symbol contexts906            for (size_t i = start_size; i < num_matches; ++i) {907              sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);908              SymbolType sym_type = sc.symbol->GetType();909              if (sc.symbol && sc.symbol->ValueIsAddress() &&910                  (sym_type == eSymbolTypeCode ||911                   sym_type == eSymbolTypeResolver)) {912                FileAddrToIndexMap::const_iterator pos =913                    file_addr_to_index.find(914                        sc.symbol->GetAddressRef().GetFileAddress());915                if (pos == end)916                  sc_list.Append(sc);917                else918                  sc_list[pos->second].symbol = sc.symbol;919              }920            }921          }922        }923      }924    }925  }926}927 928void Module::FindAddressesForLine(const lldb::TargetSP target_sp,929                                  const FileSpec &file, uint32_t line,930                                  Function *function,931                                  std::vector<Address> &output_local,932                                  std::vector<Address> &output_extern) {933  SearchFilterByModule filter(target_sp, m_file);934 935  // TODO: Handle SourceLocationSpec column information936  SourceLocationSpec location_spec(file, line, /*column=*/std::nullopt,937                                   /*check_inlines=*/true,938                                   /*exact_match=*/false);939  AddressResolverFileLine resolver(location_spec);940  resolver.ResolveAddress(filter);941 942  for (size_t n = 0; n < resolver.GetNumberOfAddresses(); n++) {943    Address addr = resolver.GetAddressRangeAtIndex(n).GetBaseAddress();944    Function *f = addr.CalculateSymbolContextFunction();945    if (f && f == function)946      output_local.push_back(addr);947    else948      output_extern.push_back(addr);949  }950}951 952void Module::FindTypes(const TypeQuery &query, TypeResults &results) {953  if (SymbolFile *symbols = GetSymbolFile())954    symbols->FindTypes(query, results);955}956 957static Debugger::DebuggerList958DebuggersOwningModuleRequestingInterruption(Module &module) {959  Debugger::DebuggerList requestors =960      Debugger::DebuggersRequestingInterruption();961  Debugger::DebuggerList interruptors;962  if (requestors.empty())963    return interruptors;964 965  for (auto debugger_sp : requestors) {966    if (!debugger_sp->InterruptRequested())967      continue;968    if (debugger_sp->GetTargetList().AnyTargetContainsModule(module))969      interruptors.push_back(debugger_sp);970  }971  return interruptors;972}973 974SymbolFile *Module::GetSymbolFile(bool can_create, Stream *feedback_strm) {975  if (!m_did_load_symfile.load()) {976    std::lock_guard<std::recursive_mutex> guard(m_mutex);977    if (!m_did_load_symfile.load() && can_create) {978      Debugger::DebuggerList interruptors =979          DebuggersOwningModuleRequestingInterruption(*this);980      if (!interruptors.empty()) {981        for (auto debugger_sp : interruptors) {982          REPORT_INTERRUPTION(*(debugger_sp.get()),983                              "Interrupted fetching symbols for module {0}",984                              this->GetFileSpec());985        }986        return nullptr;987      }988      ObjectFile *obj_file = GetObjectFile();989      if (obj_file != nullptr) {990        LLDB_SCOPED_TIMER();991        m_symfile_up.reset(992            SymbolVendor::FindPlugin(shared_from_this(), feedback_strm));993        m_did_load_symfile = true;994        m_unwind_table.ModuleWasUpdated();995      }996    }997  }998  return m_symfile_up ? m_symfile_up->GetSymbolFile() : nullptr;999}1000 1001Symtab *Module::GetSymtab(bool can_create) {1002  if (SymbolFile *symbols = GetSymbolFile(can_create))1003    return symbols->GetSymtab(can_create);1004  return nullptr;1005}1006 1007void Module::SetFileSpecAndObjectName(const FileSpec &file,1008                                      ConstString object_name) {1009  // Container objects whose paths do not specify a file directly can call this1010  // function to correct the file and object names.1011  m_file = file;1012  m_mod_time = FileSystem::Instance().GetModificationTime(file);1013  m_object_name = object_name;1014}1015 1016const ArchSpec &Module::GetArchitecture() const { return m_arch; }1017 1018std::string Module::GetSpecificationDescription() const {1019  std::string spec(GetFileSpec().GetPath());1020  if (m_object_name) {1021    spec += '(';1022    spec += m_object_name.GetCString();1023    spec += ')';1024  }1025  return spec;1026}1027 1028void Module::GetDescription(llvm::raw_ostream &s,1029                            lldb::DescriptionLevel level) {1030  if (level >= eDescriptionLevelFull) {1031    if (m_arch.IsValid())1032      s << llvm::formatv("({0}) ", m_arch.GetArchitectureName());1033  }1034 1035  if (level == eDescriptionLevelBrief) {1036    const char *filename = m_file.GetFilename().GetCString();1037    if (filename)1038      s << filename;1039  } else {1040    char path[PATH_MAX];1041    if (m_file.GetPath(path, sizeof(path)))1042      s << path;1043  }1044 1045  const char *object_name = m_object_name.GetCString();1046  if (object_name)1047    s << llvm::formatv("({0})", object_name);1048}1049 1050bool Module::FileHasChanged() const {1051  // We have provided the DataBuffer for this module to avoid accessing the1052  // filesystem. We never want to reload those files.1053  if (m_data_sp)1054    return false;1055  if (!m_file_has_changed)1056    m_file_has_changed =1057        (FileSystem::Instance().GetModificationTime(m_file) != m_mod_time);1058  return m_file_has_changed;1059}1060 1061void Module::ReportWarningOptimization(1062    std::optional<lldb::user_id_t> debugger_id) {1063  ConstString file_name = GetFileSpec().GetFilename();1064  if (file_name.IsEmpty())1065    return;1066 1067  StreamString ss;1068  ss << file_name1069     << " was compiled with optimization - stepping may behave "1070        "oddly; variables may not be available.";1071  llvm::StringRef msg = ss.GetString();1072  Debugger::ReportWarning(msg.str(), debugger_id, GetDiagnosticOnceFlag(msg));1073}1074 1075void Module::ReportWarningUnsupportedLanguage(1076    LanguageType language, std::optional<lldb::user_id_t> debugger_id) {1077  StreamString ss;1078  ss << "This version of LLDB has no plugin for the language \""1079     << Language::GetNameForLanguageType(language)1080     << "\". "1081        "Inspection of frame variables will be limited.";1082  llvm::StringRef msg = ss.GetString();1083  Debugger::ReportWarning(msg.str(), debugger_id, GetDiagnosticOnceFlag(msg));1084}1085 1086void Module::ReportErrorIfModifyDetected(1087    const llvm::formatv_object_base &payload) {1088  if (!m_first_file_changed_log) {1089    if (FileHasChanged()) {1090      m_first_file_changed_log = true;1091      StreamString strm;1092      strm.PutCString("the object file ");1093      GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelFull);1094      strm.PutCString(" has been modified\n");1095      strm.PutCString(payload.str());1096      strm.PutCString("The debug session should be aborted as the original "1097                      "debug information has been overwritten.");1098      Debugger::ReportError(std::string(strm.GetString()));1099    }1100  }1101}1102 1103std::once_flag *Module::GetDiagnosticOnceFlag(llvm::StringRef msg) {1104  std::lock_guard<std::recursive_mutex> guard(m_diagnostic_mutex);1105  auto &once_ptr = m_shown_diagnostics[llvm::stable_hash_name(msg)];1106  if (!once_ptr)1107    once_ptr = std::make_unique<std::once_flag>();1108  return once_ptr.get();1109}1110 1111void Module::ReportError(const llvm::formatv_object_base &payload) {1112  StreamString strm;1113  GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelBrief);1114  std::string msg = payload.str();1115  strm << ' ' << msg;1116  Debugger::ReportError(strm.GetString().str(), {}, GetDiagnosticOnceFlag(msg));1117}1118 1119void Module::ReportWarning(const llvm::formatv_object_base &payload) {1120  StreamString strm;1121  GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelFull);1122  std::string msg = payload.str();1123  strm << ' ' << msg;1124  Debugger::ReportWarning(strm.GetString().str(), {},1125                          GetDiagnosticOnceFlag(msg));1126}1127 1128void Module::LogMessage(Log *log, const llvm::formatv_object_base &payload) {1129  StreamString log_message;1130  GetDescription(log_message.AsRawOstream(), lldb::eDescriptionLevelFull);1131  log_message.PutCString(": ");1132  log_message.PutCString(payload.str());1133  log->PutCString(log_message.GetData());1134}1135 1136void Module::LogMessageVerboseBacktrace(1137    Log *log, const llvm::formatv_object_base &payload) {1138  StreamString log_message;1139  GetDescription(log_message.AsRawOstream(), lldb::eDescriptionLevelFull);1140  log_message.PutCString(": ");1141  log_message.PutCString(payload.str());1142  if (log->GetVerbose()) {1143    std::string back_trace;1144    llvm::raw_string_ostream stream(back_trace);1145    llvm::sys::PrintStackTrace(stream);1146    log_message.PutCString(back_trace);1147  }1148  log->PutCString(log_message.GetData());1149}1150 1151void Module::Dump(Stream *s) {1152  std::lock_guard<std::recursive_mutex> guard(m_mutex);1153  // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);1154  s->Indent();1155  s->Printf("Module %s%s%s%s\n", m_file.GetPath().c_str(),1156            m_object_name ? "(" : "",1157            m_object_name ? m_object_name.GetCString() : "",1158            m_object_name ? ")" : "");1159 1160  s->IndentMore();1161 1162  ObjectFile *objfile = GetObjectFile();1163  if (objfile)1164    objfile->Dump(s);1165 1166  if (SymbolFile *symbols = GetSymbolFile())1167    symbols->Dump(*s);1168 1169  s->IndentLess();1170}1171 1172ConstString Module::GetObjectName() const { return m_object_name; }1173 1174ObjectFile *Module::GetObjectFile() {1175  if (!m_did_load_objfile.load()) {1176    std::lock_guard<std::recursive_mutex> guard(m_mutex);1177    if (!m_did_load_objfile.load()) {1178      LLDB_SCOPED_TIMERF("Module::GetObjectFile () module = %s",1179                         GetFileSpec().GetFilename().AsCString(""));1180      lldb::offset_t data_offset = 0;1181      lldb::offset_t file_size = 0;1182 1183      if (m_data_sp)1184        file_size = m_data_sp->GetByteSize();1185      else if (m_file)1186        file_size = FileSystem::Instance().GetByteSize(m_file);1187 1188      if (file_size > m_object_offset) {1189        m_did_load_objfile = true;1190        // FindPlugin will modify its data_sp argument. Do not let it1191        // modify our m_data_sp member.1192        auto data_sp = m_data_sp;1193        m_objfile_sp = ObjectFile::FindPlugin(1194            shared_from_this(), &m_file, m_object_offset,1195            file_size - m_object_offset, data_sp, data_offset);1196        if (m_objfile_sp) {1197          // Once we get the object file, update our module with the object1198          // file's architecture since it might differ in vendor/os if some1199          // parts were unknown.  But since the matching arch might already be1200          // more specific than the generic COFF architecture, only merge in1201          // those values that overwrite unspecified unknown values.1202          m_arch.MergeFrom(m_objfile_sp->GetArchitecture());1203 1204          m_unwind_table.ModuleWasUpdated();1205        } else {1206          ReportError("failed to load objfile for {0}\nDebugging will be "1207                      "degraded for this module.",1208                      GetFileSpec().GetPath().c_str());1209        }1210      }1211    }1212  }1213  return m_objfile_sp.get();1214}1215 1216SectionList *Module::GetSectionList() {1217  // Populate m_sections_up with sections from objfile.1218  if (!m_sections_up) {1219    ObjectFile *obj_file = GetObjectFile();1220    if (obj_file != nullptr)1221      obj_file->CreateSections(*GetUnifiedSectionList());1222  }1223  return m_sections_up.get();1224}1225 1226void Module::SectionFileAddressesChanged() {1227  ObjectFile *obj_file = GetObjectFile();1228  if (obj_file)1229    obj_file->SectionFileAddressesChanged();1230  if (SymbolFile *symbols = GetSymbolFile())1231    symbols->SectionFileAddressesChanged();1232}1233 1234UnwindTable &Module::GetUnwindTable() {1235  if (!m_symfile_spec)1236    SymbolLocator::DownloadSymbolFileAsync(GetUUID());1237  return m_unwind_table;1238}1239 1240SectionList *Module::GetUnifiedSectionList() {1241  if (!m_sections_up)1242    m_sections_up = std::make_unique<SectionList>();1243  return m_sections_up.get();1244}1245 1246const Symbol *Module::FindFirstSymbolWithNameAndType(ConstString name,1247                                                     SymbolType symbol_type) {1248  LLDB_SCOPED_TIMERF(1249      "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",1250      name.AsCString(), symbol_type);1251  if (Symtab *symtab = GetSymtab())1252    return symtab->FindFirstSymbolWithNameAndType(1253        name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);1254  return nullptr;1255}1256void Module::SymbolIndicesToSymbolContextList(1257    Symtab *symtab, std::vector<uint32_t> &symbol_indexes,1258    SymbolContextList &sc_list) {1259  // No need to protect this call using m_mutex all other method calls are1260  // already thread safe.1261 1262  size_t num_indices = symbol_indexes.size();1263  if (num_indices > 0) {1264    SymbolContext sc;1265    CalculateSymbolContext(&sc);1266    for (size_t i = 0; i < num_indices; i++) {1267      sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);1268      if (sc.symbol)1269        sc_list.Append(sc);1270    }1271  }1272}1273 1274void Module::FindFunctionSymbols(ConstString name, uint32_t name_type_mask,1275                                 SymbolContextList &sc_list) {1276  LLDB_SCOPED_TIMERF("Module::FindSymbolsFunctions (name = %s, mask = 0x%8.8x)",1277                     name.AsCString(), name_type_mask);1278  if (Symtab *symtab = GetSymtab())1279    symtab->FindFunctionSymbols(name, name_type_mask, sc_list);1280}1281 1282void Module::FindSymbolsWithNameAndType(ConstString name,1283                                        SymbolType symbol_type,1284                                        SymbolContextList &sc_list) {1285  // No need to protect this call using m_mutex all other method calls are1286  // already thread safe.1287  if (Symtab *symtab = GetSymtab()) {1288    std::vector<uint32_t> symbol_indexes;1289    symtab->FindAllSymbolsWithNameAndType(name, symbol_type, symbol_indexes);1290    SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);1291  }1292}1293 1294void Module::FindSymbolsMatchingRegExAndType(1295    const RegularExpression &regex, SymbolType symbol_type,1296    SymbolContextList &sc_list, Mangled::NamePreference mangling_preference) {1297  // No need to protect this call using m_mutex all other method calls are1298  // already thread safe.1299  LLDB_SCOPED_TIMERF(1300      "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",1301      regex.GetText().str().c_str(), symbol_type);1302  if (Symtab *symtab = GetSymtab()) {1303    std::vector<uint32_t> symbol_indexes;1304    symtab->FindAllSymbolsMatchingRexExAndType(1305        regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny,1306        symbol_indexes, mangling_preference);1307    SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);1308  }1309}1310 1311void Module::PreloadSymbols() {1312  std::lock_guard<std::recursive_mutex> guard(m_mutex);1313  SymbolFile *sym_file = GetSymbolFile();1314  if (!sym_file)1315    return;1316 1317  // Load the object file symbol table and any symbols from the SymbolFile that1318  // get appended using SymbolFile::AddSymbols(...).1319  if (Symtab *symtab = sym_file->GetSymtab())1320    symtab->PreloadSymbols();1321 1322  // Now let the symbol file preload its data and the symbol table will be1323  // available without needing to take the module lock.1324  sym_file->PreloadSymbols();1325}1326 1327void Module::SetSymbolFileFileSpec(const FileSpec &file) {1328  if (!FileSystem::Instance().Exists(file))1329    return;1330  if (m_symfile_up) {1331    // Remove any sections in the unified section list that come from the1332    // current symbol vendor.1333    SectionList *section_list = GetSectionList();1334    SymbolFile *symbol_file = GetSymbolFile();1335    if (section_list && symbol_file) {1336      ObjectFile *obj_file = symbol_file->GetObjectFile();1337      // Make sure we have an object file and that the symbol vendor's objfile1338      // isn't the same as the module's objfile before we remove any sections1339      // for it...1340      if (obj_file) {1341        // Check to make sure we aren't trying to specify the file we already1342        // have1343        if (obj_file->GetFileSpec() == file) {1344          // We are being told to add the exact same file that we already have1345          // we don't have to do anything.1346          return;1347        }1348 1349        // Cleare the current symtab as we are going to replace it with a new1350        // one1351        obj_file->ClearSymtab();1352 1353        // The symbol file might be a directory bundle ("/tmp/a.out.dSYM")1354        // instead of a full path to the symbol file within the bundle1355        // ("/tmp/a.out.dSYM/Contents/Resources/DWARF/a.out"). So we need to1356        // check this1357        if (FileSystem::Instance().IsDirectory(file)) {1358          std::string new_path(file.GetPath());1359          std::string old_path(obj_file->GetFileSpec().GetPath());1360          if (llvm::StringRef(old_path).starts_with(new_path)) {1361            // We specified the same bundle as the symbol file that we already1362            // have1363            return;1364          }1365        }1366 1367        if (obj_file != m_objfile_sp.get()) {1368          size_t num_sections = section_list->GetNumSections(0);1369          for (size_t idx = num_sections; idx > 0; --idx) {1370            lldb::SectionSP section_sp(1371                section_list->GetSectionAtIndex(idx - 1));1372            if (section_sp->GetObjectFile() == obj_file) {1373              section_list->DeleteSection(idx - 1);1374            }1375          }1376        }1377      }1378    }1379    // Keep all old symbol files around in case there are any lingering type1380    // references in any SBValue objects that might have been handed out.1381    m_old_symfiles.push_back(std::move(m_symfile_up));1382  }1383  m_symfile_spec = file;1384  m_symfile_up.reset();1385  m_did_load_symfile = false;1386}1387 1388bool Module::IsExecutable() {1389  if (GetObjectFile() == nullptr)1390    return false;1391  else1392    return GetObjectFile()->IsExecutable();1393}1394 1395bool Module::IsLoadedInTarget(Target *target) {1396  ObjectFile *obj_file = GetObjectFile();1397  if (obj_file) {1398    SectionList *sections = GetSectionList();1399    if (sections != nullptr) {1400      size_t num_sections = sections->GetSize();1401      for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++) {1402        SectionSP section_sp = sections->GetSectionAtIndex(sect_idx);1403        if (section_sp->GetLoadBaseAddress(target) != LLDB_INVALID_ADDRESS) {1404          return true;1405        }1406      }1407    }1408  }1409  return false;1410}1411 1412bool Module::LoadScriptingResourceInTarget(Target *target, Status &error,1413                                           Stream &feedback_stream) {1414  if (!target) {1415    error = Status::FromErrorString("invalid destination Target");1416    return false;1417  }1418 1419  LoadScriptFromSymFile should_load =1420      target->TargetProperties::GetLoadScriptFromSymbolFile();1421 1422  if (should_load == eLoadScriptFromSymFileFalse)1423    return false;1424 1425  Debugger &debugger = target->GetDebugger();1426  const ScriptLanguage script_language = debugger.GetScriptLanguage();1427  if (script_language != eScriptLanguageNone) {1428 1429    PlatformSP platform_sp(target->GetPlatform());1430 1431    if (!platform_sp) {1432      error = Status::FromErrorString("invalid Platform");1433      return false;1434    }1435 1436    FileSpecList file_specs = platform_sp->LocateExecutableScriptingResources(1437        target, *this, feedback_stream);1438 1439    const uint32_t num_specs = file_specs.GetSize();1440    if (num_specs) {1441      ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();1442      if (script_interpreter) {1443        for (uint32_t i = 0; i < num_specs; ++i) {1444          FileSpec scripting_fspec(file_specs.GetFileSpecAtIndex(i));1445          if (scripting_fspec &&1446              FileSystem::Instance().Exists(scripting_fspec)) {1447            if (should_load == eLoadScriptFromSymFileWarn) {1448              feedback_stream.Printf(1449                  "warning: '%s' contains a debug script. To run this script "1450                  "in "1451                  "this debug session:\n\n    command script import "1452                  "\"%s\"\n\n"1453                  "To run all discovered debug scripts in this session:\n\n"1454                  "    settings set target.load-script-from-symbol-file "1455                  "true\n",1456                  GetFileSpec().GetFileNameStrippingExtension().GetCString(),1457                  scripting_fspec.GetPath().c_str());1458              return false;1459            }1460            StreamString scripting_stream;1461            scripting_fspec.Dump(scripting_stream.AsRawOstream());1462            LoadScriptOptions options;1463            bool did_load = script_interpreter->LoadScriptingModule(1464                scripting_stream.GetData(), options, error,1465                /*module_sp*/ nullptr, /*extra_path*/ {},1466                target->shared_from_this());1467            if (!did_load)1468              return false;1469          }1470        }1471      } else {1472        error = Status::FromErrorString("invalid ScriptInterpreter");1473        return false;1474      }1475    }1476  }1477  return true;1478}1479 1480bool Module::SetArchitecture(const ArchSpec &new_arch) {1481  if (!m_arch.IsValid()) {1482    m_arch = new_arch;1483    return true;1484  }1485  return m_arch.IsCompatibleMatch(new_arch);1486}1487 1488bool Module::SetLoadAddress(Target &target, lldb::addr_t value,1489                            bool value_is_offset, bool &changed) {1490  ObjectFile *object_file = GetObjectFile();1491  if (object_file != nullptr) {1492    changed = object_file->SetLoadAddress(target, value, value_is_offset);1493    return true;1494  } else {1495    changed = false;1496  }1497  return false;1498}1499 1500bool Module::MatchesModuleSpec(const ModuleSpec &module_ref) {1501  const UUID &uuid = module_ref.GetUUID();1502 1503  if (uuid.IsValid()) {1504    // If the UUID matches, then nothing more needs to match...1505    return (uuid == GetUUID());1506  }1507 1508  const FileSpec &file_spec = module_ref.GetFileSpec();1509  if (!FileSpec::Match(file_spec, m_file) &&1510      !FileSpec::Match(file_spec, m_platform_file))1511    return false;1512 1513  const FileSpec &platform_file_spec = module_ref.GetPlatformFileSpec();1514  if (!FileSpec::Match(platform_file_spec, GetPlatformFileSpec()))1515    return false;1516 1517  const ArchSpec &arch = module_ref.GetArchitecture();1518  if (arch.IsValid()) {1519    if (!m_arch.IsCompatibleMatch(arch))1520      return false;1521  }1522 1523  ConstString object_name = module_ref.GetObjectName();1524  if (object_name) {1525    if (object_name != GetObjectName())1526      return false;1527  }1528  return true;1529}1530 1531bool Module::FindSourceFile(const FileSpec &orig_spec,1532                            FileSpec &new_spec) const {1533  std::lock_guard<std::recursive_mutex> guard(m_mutex);1534  if (auto remapped = m_source_mappings.FindFile(orig_spec)) {1535    new_spec = *remapped;1536    return true;1537  }1538  return false;1539}1540 1541std::optional<std::string> Module::RemapSourceFile(llvm::StringRef path) const {1542  std::lock_guard<std::recursive_mutex> guard(m_mutex);1543  if (auto remapped = m_source_mappings.RemapPath(path))1544    return remapped->GetPath();1545  return {};1546}1547 1548void Module::RegisterXcodeSDK(llvm::StringRef sdk_name,1549                              llvm::StringRef sysroot) {1550  auto sdk_path_or_err =1551      HostInfo::GetSDKRoot(HostInfo::SDKOptions{sdk_name.str()});1552 1553  if (!sdk_path_or_err) {1554    Debugger::ReportError("Error while searching for Xcode SDK: " +1555                          toString(sdk_path_or_err.takeError()));1556    return;1557  }1558 1559  auto sdk_path = *sdk_path_or_err;1560  if (sdk_path.empty())1561    return;1562  // If the SDK changed for a previously registered source path, update it.1563  // This could happend with -fdebug-prefix-map, otherwise it's unlikely.1564  if (!m_source_mappings.Replace(sysroot, sdk_path, true))1565    // In the general case, however, append it to the list.1566    m_source_mappings.Append(sysroot, sdk_path, false);1567}1568 1569bool Module::MergeArchitecture(const ArchSpec &arch_spec) {1570  if (!arch_spec.IsValid())1571    return false;1572  LLDB_LOGF(GetLog(LLDBLog::Object | LLDBLog::Modules),1573            "module has arch %s, merging/replacing with arch %s",1574            m_arch.GetTriple().getTriple().c_str(),1575            arch_spec.GetTriple().getTriple().c_str());1576  if (!m_arch.IsCompatibleMatch(arch_spec)) {1577    // The new architecture is different, we just need to replace it.1578    return SetArchitecture(arch_spec);1579  }1580 1581  // Merge bits from arch_spec into "merged_arch" and set our architecture.1582  ArchSpec merged_arch(m_arch);1583  merged_arch.MergeFrom(arch_spec);1584  // SetArchitecture() is a no-op if m_arch is already valid.1585  m_arch = ArchSpec();1586  return SetArchitecture(merged_arch);1587}1588 1589void Module::ResetStatistics() {1590  m_symtab_parse_time.reset();1591  m_symtab_index_time.reset();1592  SymbolFile *sym_file = GetSymbolFile();1593  if (sym_file)1594    sym_file->ResetStatistics();1595}1596 1597llvm::VersionTuple Module::GetVersion() {1598  if (ObjectFile *obj_file = GetObjectFile())1599    return obj_file->GetVersion();1600  return llvm::VersionTuple();1601}1602 1603bool Module::GetIsDynamicLinkEditor() {1604  ObjectFile *obj_file = GetObjectFile();1605 1606  if (obj_file)1607    return obj_file->GetIsDynamicLinkEditor();1608 1609  return false;1610}1611 1612uint32_t Module::Hash() {1613  std::string identifier;1614  llvm::raw_string_ostream id_strm(identifier);1615  id_strm << m_arch.GetTriple().str() << '-' << m_file.GetPath();1616  if (m_object_name)1617    id_strm << '(' << m_object_name << ')';1618  if (m_object_offset > 0)1619    id_strm << m_object_offset;1620  const auto mtime = llvm::sys::toTimeT(m_object_mod_time);1621  if (mtime > 0)1622    id_strm << mtime;1623  return llvm::djbHash(identifier);1624}1625 1626std::string Module::GetCacheKey() {1627  std::string key;1628  llvm::raw_string_ostream strm(key);1629  strm << m_arch.GetTriple().str() << '-' << m_file.GetFilename();1630  if (m_object_name)1631    strm << '(' << m_object_name << ')';1632  strm << '-' << llvm::format_hex(Hash(), 10);1633  return key;1634}1635 1636DataFileCache *Module::GetIndexCache() {1637  if (!ModuleList::GetGlobalModuleListProperties().GetEnableLLDBIndexCache())1638    return 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 function1641  static DataFileCache *g_data_file_cache =1642      new DataFileCache(ModuleList::GetGlobalModuleListProperties()1643                            .GetLLDBIndexCachePath()1644                            .GetPath());1645  return g_data_file_cache;1646}1647