xref: /freebsd-src/contrib/llvm-project/lldb/source/Core/Module.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15ffd83dbSDimitry Andric //===-- Module.cpp --------------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "lldb/Core/Module.h"
100b57cec5SDimitry Andric 
110b57cec5SDimitry Andric #include "lldb/Core/AddressRange.h"
120b57cec5SDimitry Andric #include "lldb/Core/AddressResolverFileLine.h"
130eae32dcSDimitry Andric #include "lldb/Core/DataFileCache.h"
140b57cec5SDimitry Andric #include "lldb/Core/Debugger.h"
150b57cec5SDimitry Andric #include "lldb/Core/Mangled.h"
160b57cec5SDimitry Andric #include "lldb/Core/ModuleSpec.h"
170b57cec5SDimitry Andric #include "lldb/Core/SearchFilter.h"
180b57cec5SDimitry Andric #include "lldb/Core/Section.h"
190b57cec5SDimitry Andric #include "lldb/Host/FileSystem.h"
200b57cec5SDimitry Andric #include "lldb/Host/Host.h"
215ffd83dbSDimitry Andric #include "lldb/Host/HostInfo.h"
220b57cec5SDimitry Andric #include "lldb/Interpreter/CommandInterpreter.h"
230b57cec5SDimitry Andric #include "lldb/Interpreter/ScriptInterpreter.h"
240b57cec5SDimitry Andric #include "lldb/Symbol/CompileUnit.h"
250b57cec5SDimitry Andric #include "lldb/Symbol/Function.h"
260b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h"
270b57cec5SDimitry Andric #include "lldb/Symbol/Symbol.h"
280b57cec5SDimitry Andric #include "lldb/Symbol/SymbolContext.h"
290b57cec5SDimitry Andric #include "lldb/Symbol/SymbolFile.h"
305f757f3fSDimitry Andric #include "lldb/Symbol/SymbolLocator.h"
310b57cec5SDimitry Andric #include "lldb/Symbol/SymbolVendor.h"
320b57cec5SDimitry Andric #include "lldb/Symbol/Symtab.h"
330b57cec5SDimitry Andric #include "lldb/Symbol/Type.h"
340b57cec5SDimitry Andric #include "lldb/Symbol/TypeList.h"
350b57cec5SDimitry Andric #include "lldb/Symbol/TypeMap.h"
360b57cec5SDimitry Andric #include "lldb/Symbol/TypeSystem.h"
370b57cec5SDimitry Andric #include "lldb/Target/Language.h"
380b57cec5SDimitry Andric #include "lldb/Target/Process.h"
390b57cec5SDimitry Andric #include "lldb/Target/Target.h"
400b57cec5SDimitry Andric #include "lldb/Utility/DataBufferHeap.h"
4106c3fb27SDimitry Andric #include "lldb/Utility/FileSpecList.h"
420b57cec5SDimitry Andric #include "lldb/Utility/LLDBAssert.h"
4381ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h"
440b57cec5SDimitry Andric #include "lldb/Utility/Log.h"
450b57cec5SDimitry Andric #include "lldb/Utility/RegularExpression.h"
460b57cec5SDimitry Andric #include "lldb/Utility/Status.h"
470b57cec5SDimitry Andric #include "lldb/Utility/Stream.h"
480b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h"
490b57cec5SDimitry Andric #include "lldb/Utility/Timer.h"
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric #if defined(_WIN32)
520b57cec5SDimitry Andric #include "lldb/Host/windows/PosixApi.h"
530b57cec5SDimitry Andric #endif
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
560b57cec5SDimitry Andric #include "Plugins/Language/ObjC/ObjCLanguage.h"
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
590b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
600eae32dcSDimitry Andric #include "llvm/Support/DJB.h"
610b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
620eae32dcSDimitry Andric #include "llvm/Support/FormatVariadic.h"
630eae32dcSDimitry Andric #include "llvm/Support/JSON.h"
640b57cec5SDimitry Andric #include "llvm/Support/Signals.h"
650b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
660b57cec5SDimitry Andric 
67fe6060f1SDimitry Andric #include <cassert>
68fe6060f1SDimitry Andric #include <cinttypes>
69fe6060f1SDimitry Andric #include <cstdarg>
700b57cec5SDimitry Andric #include <cstdint>
71fe6060f1SDimitry Andric #include <cstring>
720b57cec5SDimitry Andric #include <map>
73bdd1243dSDimitry Andric #include <optional>
740b57cec5SDimitry Andric #include <type_traits>
750b57cec5SDimitry Andric #include <utility>
760b57cec5SDimitry Andric 
770b57cec5SDimitry Andric namespace lldb_private {
780b57cec5SDimitry Andric class CompilerDeclContext;
790b57cec5SDimitry Andric }
800b57cec5SDimitry Andric namespace lldb_private {
810b57cec5SDimitry Andric class VariableList;
820b57cec5SDimitry Andric }
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric using namespace lldb;
850b57cec5SDimitry Andric using namespace lldb_private;
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric // Shared pointers to modules track module lifetimes in targets and in the
880b57cec5SDimitry Andric // global module, but this collection will track all module objects that are
890b57cec5SDimitry Andric // still alive
900b57cec5SDimitry Andric typedef std::vector<Module *> ModuleCollection;
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric static ModuleCollection &GetModuleCollection() {
930b57cec5SDimitry Andric   // This module collection needs to live past any module, so we could either
940b57cec5SDimitry Andric   // make it a shared pointer in each module or just leak is.  Since it is only
950b57cec5SDimitry Andric   // an empty vector by the time all the modules have gone away, we just leak
960b57cec5SDimitry Andric   // it for now.  If we decide this is a big problem we can introduce a
970b57cec5SDimitry Andric   // Finalize method that will tear everything down in a predictable order.
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   static ModuleCollection *g_module_collection = nullptr;
1000b57cec5SDimitry Andric   if (g_module_collection == nullptr)
1010b57cec5SDimitry Andric     g_module_collection = new ModuleCollection();
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric   return *g_module_collection;
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric std::recursive_mutex &Module::GetAllocationModuleCollectionMutex() {
1070b57cec5SDimitry Andric   // NOTE: The mutex below must be leaked since the global module list in
1080b57cec5SDimitry Andric   // the ModuleList class will get torn at some point, and we can't know if it
1090b57cec5SDimitry Andric   // will tear itself down before the "g_module_collection_mutex" below will.
1100b57cec5SDimitry Andric   // So we leak a Mutex object below to safeguard against that
1110b57cec5SDimitry Andric 
1120b57cec5SDimitry Andric   static std::recursive_mutex *g_module_collection_mutex = nullptr;
1130b57cec5SDimitry Andric   if (g_module_collection_mutex == nullptr)
1140b57cec5SDimitry Andric     g_module_collection_mutex = new std::recursive_mutex; // NOTE: known leak
1150b57cec5SDimitry Andric   return *g_module_collection_mutex;
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric size_t Module::GetNumberAllocatedModules() {
1190b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(
1200b57cec5SDimitry Andric       GetAllocationModuleCollectionMutex());
1210b57cec5SDimitry Andric   return GetModuleCollection().size();
1220b57cec5SDimitry Andric }
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric Module *Module::GetAllocatedModuleAtIndex(size_t idx) {
1250b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(
1260b57cec5SDimitry Andric       GetAllocationModuleCollectionMutex());
1270b57cec5SDimitry Andric   ModuleCollection &modules = GetModuleCollection();
1280b57cec5SDimitry Andric   if (idx < modules.size())
1290b57cec5SDimitry Andric     return modules[idx];
1300b57cec5SDimitry Andric   return nullptr;
1310b57cec5SDimitry Andric }
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric Module::Module(const ModuleSpec &module_spec)
13481ad6265SDimitry Andric     : m_file_has_changed(false), m_first_file_changed_log(false) {
1350b57cec5SDimitry Andric   // Scope for locker below...
1360b57cec5SDimitry Andric   {
1370b57cec5SDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
1380b57cec5SDimitry Andric         GetAllocationModuleCollectionMutex());
1390b57cec5SDimitry Andric     GetModuleCollection().push_back(this);
1400b57cec5SDimitry Andric   }
1410b57cec5SDimitry Andric 
14281ad6265SDimitry Andric   Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules));
1430b57cec5SDimitry Andric   if (log != nullptr)
1449dba64beSDimitry Andric     LLDB_LOGF(log, "%p Module::Module((%s) '%s%s%s%s')",
1459dba64beSDimitry Andric               static_cast<void *>(this),
1460b57cec5SDimitry Andric               module_spec.GetArchitecture().GetArchitectureName(),
1470b57cec5SDimitry Andric               module_spec.GetFileSpec().GetPath().c_str(),
1480b57cec5SDimitry Andric               module_spec.GetObjectName().IsEmpty() ? "" : "(",
149753f127fSDimitry Andric               module_spec.GetObjectName().AsCString(""),
1500b57cec5SDimitry Andric               module_spec.GetObjectName().IsEmpty() ? "" : ")");
1510b57cec5SDimitry Andric 
1525ffd83dbSDimitry Andric   auto data_sp = module_spec.GetData();
1535ffd83dbSDimitry Andric   lldb::offset_t file_size = 0;
1545ffd83dbSDimitry Andric   if (data_sp)
1555ffd83dbSDimitry Andric     file_size = data_sp->GetByteSize();
1565ffd83dbSDimitry Andric 
1570b57cec5SDimitry Andric   // First extract all module specifications from the file using the local file
1580b57cec5SDimitry Andric   // path. If there are no specifications, then don't fill anything in
1590b57cec5SDimitry Andric   ModuleSpecList modules_specs;
1605ffd83dbSDimitry Andric   if (ObjectFile::GetModuleSpecifications(
1615ffd83dbSDimitry Andric           module_spec.GetFileSpec(), 0, file_size, modules_specs, data_sp) == 0)
1620b57cec5SDimitry Andric     return;
1630b57cec5SDimitry Andric 
1640b57cec5SDimitry Andric   // Now make sure that one of the module specifications matches what we just
1650b57cec5SDimitry Andric   // extract. We might have a module specification that specifies a file
1660b57cec5SDimitry Andric   // "/usr/lib/dyld" with UUID XXX, but we might have a local version of
1670b57cec5SDimitry Andric   // "/usr/lib/dyld" that has
1680b57cec5SDimitry Andric   // UUID YYY and we don't want those to match. If they don't match, just don't
1690b57cec5SDimitry Andric   // fill any ivars in so we don't accidentally grab the wrong file later since
1700b57cec5SDimitry Andric   // they don't match...
1710b57cec5SDimitry Andric   ModuleSpec matching_module_spec;
1720b57cec5SDimitry Andric   if (!modules_specs.FindMatchingModuleSpec(module_spec,
1730b57cec5SDimitry Andric                                             matching_module_spec)) {
1740b57cec5SDimitry Andric     if (log) {
1759dba64beSDimitry Andric       LLDB_LOGF(log, "Found local object file but the specs didn't match");
1760b57cec5SDimitry Andric     }
1770b57cec5SDimitry Andric     return;
1780b57cec5SDimitry Andric   }
1790b57cec5SDimitry Andric 
1805ffd83dbSDimitry Andric   // Set m_data_sp if it was initially provided in the ModuleSpec. Note that
1815ffd83dbSDimitry Andric   // we cannot use the data_sp variable here, because it will have been
1825ffd83dbSDimitry Andric   // modified by GetModuleSpecifications().
1835ffd83dbSDimitry Andric   if (auto module_spec_data_sp = module_spec.GetData()) {
1845ffd83dbSDimitry Andric     m_data_sp = module_spec_data_sp;
1855ffd83dbSDimitry Andric     m_mod_time = {};
1865ffd83dbSDimitry Andric   } else {
1870b57cec5SDimitry Andric     if (module_spec.GetFileSpec())
1880b57cec5SDimitry Andric       m_mod_time =
1895ffd83dbSDimitry Andric           FileSystem::Instance().GetModificationTime(module_spec.GetFileSpec());
1905ffd83dbSDimitry Andric     else if (matching_module_spec.GetFileSpec())
1915ffd83dbSDimitry Andric       m_mod_time = FileSystem::Instance().GetModificationTime(
1925ffd83dbSDimitry Andric           matching_module_spec.GetFileSpec());
1935ffd83dbSDimitry Andric   }
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric   // Copy the architecture from the actual spec if we got one back, else use
1960b57cec5SDimitry Andric   // the one that was specified
1970b57cec5SDimitry Andric   if (matching_module_spec.GetArchitecture().IsValid())
1980b57cec5SDimitry Andric     m_arch = matching_module_spec.GetArchitecture();
1990b57cec5SDimitry Andric   else if (module_spec.GetArchitecture().IsValid())
2000b57cec5SDimitry Andric     m_arch = module_spec.GetArchitecture();
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric   // Copy the file spec over and use the specified one (if there was one) so we
2030b57cec5SDimitry Andric   // don't use a path that might have gotten resolved a path in
2040b57cec5SDimitry Andric   // 'matching_module_spec'
2050b57cec5SDimitry Andric   if (module_spec.GetFileSpec())
2060b57cec5SDimitry Andric     m_file = module_spec.GetFileSpec();
2070b57cec5SDimitry Andric   else if (matching_module_spec.GetFileSpec())
2080b57cec5SDimitry Andric     m_file = matching_module_spec.GetFileSpec();
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric   // Copy the platform file spec over
2110b57cec5SDimitry Andric   if (module_spec.GetPlatformFileSpec())
2120b57cec5SDimitry Andric     m_platform_file = module_spec.GetPlatformFileSpec();
2130b57cec5SDimitry Andric   else if (matching_module_spec.GetPlatformFileSpec())
2140b57cec5SDimitry Andric     m_platform_file = matching_module_spec.GetPlatformFileSpec();
2150b57cec5SDimitry Andric 
2160b57cec5SDimitry Andric   // Copy the symbol file spec over
2170b57cec5SDimitry Andric   if (module_spec.GetSymbolFileSpec())
2180b57cec5SDimitry Andric     m_symfile_spec = module_spec.GetSymbolFileSpec();
2190b57cec5SDimitry Andric   else if (matching_module_spec.GetSymbolFileSpec())
2200b57cec5SDimitry Andric     m_symfile_spec = matching_module_spec.GetSymbolFileSpec();
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric   // Copy the object name over
2230b57cec5SDimitry Andric   if (matching_module_spec.GetObjectName())
2240b57cec5SDimitry Andric     m_object_name = matching_module_spec.GetObjectName();
2250b57cec5SDimitry Andric   else
2260b57cec5SDimitry Andric     m_object_name = module_spec.GetObjectName();
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric   // Always trust the object offset (file offset) and object modification time
2290b57cec5SDimitry Andric   // (for mod time in a BSD static archive) of from the matching module
2300b57cec5SDimitry Andric   // specification
2310b57cec5SDimitry Andric   m_object_offset = matching_module_spec.GetObjectOffset();
2320b57cec5SDimitry Andric   m_object_mod_time = matching_module_spec.GetObjectModificationTime();
2330b57cec5SDimitry Andric }
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric Module::Module(const FileSpec &file_spec, const ArchSpec &arch,
2365f757f3fSDimitry Andric                ConstString object_name, lldb::offset_t object_offset,
2370b57cec5SDimitry Andric                const llvm::sys::TimePoint<> &object_mod_time)
2380eae32dcSDimitry Andric     : m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)),
2395f757f3fSDimitry Andric       m_arch(arch), m_file(file_spec), m_object_name(object_name),
2405f757f3fSDimitry Andric       m_object_offset(object_offset), m_object_mod_time(object_mod_time),
2415f757f3fSDimitry Andric       m_file_has_changed(false), m_first_file_changed_log(false) {
2420b57cec5SDimitry Andric   // Scope for locker below...
2430b57cec5SDimitry Andric   {
2440b57cec5SDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
2450b57cec5SDimitry Andric         GetAllocationModuleCollectionMutex());
2460b57cec5SDimitry Andric     GetModuleCollection().push_back(this);
2470b57cec5SDimitry Andric   }
2480b57cec5SDimitry Andric 
24981ad6265SDimitry Andric   Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules));
2500b57cec5SDimitry Andric   if (log != nullptr)
2519dba64beSDimitry Andric     LLDB_LOGF(log, "%p Module::Module((%s) '%s%s%s%s')",
2529dba64beSDimitry Andric               static_cast<void *>(this), m_arch.GetArchitectureName(),
2539dba64beSDimitry Andric               m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",
254753f127fSDimitry Andric               m_object_name.AsCString(""), m_object_name.IsEmpty() ? "" : ")");
2550b57cec5SDimitry Andric }
2560b57cec5SDimitry Andric 
257fe6060f1SDimitry Andric Module::Module() : m_file_has_changed(false), m_first_file_changed_log(false) {
2580b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(
2590b57cec5SDimitry Andric       GetAllocationModuleCollectionMutex());
2600b57cec5SDimitry Andric   GetModuleCollection().push_back(this);
2610b57cec5SDimitry Andric }
2620b57cec5SDimitry Andric 
2630b57cec5SDimitry Andric Module::~Module() {
2640b57cec5SDimitry Andric   // Lock our module down while we tear everything down to make sure we don't
2650b57cec5SDimitry Andric   // get any access to the module while it is being destroyed
2660b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
2670b57cec5SDimitry Andric   // Scope for locker below...
2680b57cec5SDimitry Andric   {
2690b57cec5SDimitry Andric     std::lock_guard<std::recursive_mutex> guard(
2700b57cec5SDimitry Andric         GetAllocationModuleCollectionMutex());
2710b57cec5SDimitry Andric     ModuleCollection &modules = GetModuleCollection();
2720b57cec5SDimitry Andric     ModuleCollection::iterator end = modules.end();
2730b57cec5SDimitry Andric     ModuleCollection::iterator pos = std::find(modules.begin(), end, this);
2740b57cec5SDimitry Andric     assert(pos != end);
2750b57cec5SDimitry Andric     modules.erase(pos);
2760b57cec5SDimitry Andric   }
27781ad6265SDimitry Andric   Log *log(GetLog(LLDBLog::Object | LLDBLog::Modules));
2780b57cec5SDimitry Andric   if (log != nullptr)
2799dba64beSDimitry Andric     LLDB_LOGF(log, "%p Module::~Module((%s) '%s%s%s%s')",
2800b57cec5SDimitry Andric               static_cast<void *>(this), m_arch.GetArchitectureName(),
2810b57cec5SDimitry Andric               m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",
282753f127fSDimitry Andric               m_object_name.AsCString(""), m_object_name.IsEmpty() ? "" : ")");
2830b57cec5SDimitry Andric   // Release any auto pointers before we start tearing down our member
2840b57cec5SDimitry Andric   // variables since the object file and symbol files might need to make
2850b57cec5SDimitry Andric   // function calls back into this module object. The ordering is important
2860b57cec5SDimitry Andric   // here because symbol files can require the module object file. So we tear
2870b57cec5SDimitry Andric   // down the symbol file first, then the object file.
2880b57cec5SDimitry Andric   m_sections_up.reset();
2890b57cec5SDimitry Andric   m_symfile_up.reset();
2900b57cec5SDimitry Andric   m_objfile_sp.reset();
2910b57cec5SDimitry Andric }
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric ObjectFile *Module::GetMemoryObjectFile(const lldb::ProcessSP &process_sp,
2940b57cec5SDimitry Andric                                         lldb::addr_t header_addr, Status &error,
2950b57cec5SDimitry Andric                                         size_t size_to_read) {
2960b57cec5SDimitry Andric   if (m_objfile_sp) {
2970b57cec5SDimitry Andric     error.SetErrorString("object file already exists");
2980b57cec5SDimitry Andric   } else {
2990b57cec5SDimitry Andric     std::lock_guard<std::recursive_mutex> guard(m_mutex);
3000b57cec5SDimitry Andric     if (process_sp) {
3010b57cec5SDimitry Andric       m_did_load_objfile = true;
30281ad6265SDimitry Andric       std::shared_ptr<DataBufferHeap> data_sp =
30381ad6265SDimitry Andric           std::make_shared<DataBufferHeap>(size_to_read, 0);
3040b57cec5SDimitry Andric       Status readmem_error;
3050b57cec5SDimitry Andric       const size_t bytes_read =
30681ad6265SDimitry Andric           process_sp->ReadMemory(header_addr, data_sp->GetBytes(),
30781ad6265SDimitry Andric                                  data_sp->GetByteSize(), readmem_error);
3085ffd83dbSDimitry Andric       if (bytes_read < size_to_read)
30981ad6265SDimitry Andric         data_sp->SetByteSize(bytes_read);
31081ad6265SDimitry Andric       if (data_sp->GetByteSize() > 0) {
3110b57cec5SDimitry Andric         m_objfile_sp = ObjectFile::FindPlugin(shared_from_this(), process_sp,
3120b57cec5SDimitry Andric                                               header_addr, data_sp);
3130b57cec5SDimitry Andric         if (m_objfile_sp) {
3140b57cec5SDimitry Andric           StreamString s;
3150b57cec5SDimitry Andric           s.Printf("0x%16.16" PRIx64, header_addr);
3160b57cec5SDimitry Andric           m_object_name.SetString(s.GetString());
3170b57cec5SDimitry Andric 
3180b57cec5SDimitry Andric           // Once we get the object file, update our module with the object
3190b57cec5SDimitry Andric           // file's architecture since it might differ in vendor/os if some
3200b57cec5SDimitry Andric           // parts were unknown.
3210b57cec5SDimitry Andric           m_arch = m_objfile_sp->GetArchitecture();
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric           // Augment the arch with the target's information in case
3240b57cec5SDimitry Andric           // we are unable to extract the os/environment from memory.
3250b57cec5SDimitry Andric           m_arch.MergeFrom(process_sp->GetTarget().GetArchitecture());
3260b57cec5SDimitry Andric         } else {
3270b57cec5SDimitry Andric           error.SetErrorString("unable to find suitable object file plug-in");
3280b57cec5SDimitry Andric         }
3290b57cec5SDimitry Andric       } else {
3300b57cec5SDimitry Andric         error.SetErrorStringWithFormat("unable to read header from memory: %s",
3310b57cec5SDimitry Andric                                        readmem_error.AsCString());
3320b57cec5SDimitry Andric       }
3330b57cec5SDimitry Andric     } else {
3340b57cec5SDimitry Andric       error.SetErrorString("invalid process");
3350b57cec5SDimitry Andric     }
3360b57cec5SDimitry Andric   }
3370b57cec5SDimitry Andric   return m_objfile_sp.get();
3380b57cec5SDimitry Andric }
3390b57cec5SDimitry Andric 
3400b57cec5SDimitry Andric const lldb_private::UUID &Module::GetUUID() {
3410b57cec5SDimitry Andric   if (!m_did_set_uuid.load()) {
3420b57cec5SDimitry Andric     std::lock_guard<std::recursive_mutex> guard(m_mutex);
3430b57cec5SDimitry Andric     if (!m_did_set_uuid.load()) {
3440b57cec5SDimitry Andric       ObjectFile *obj_file = GetObjectFile();
3450b57cec5SDimitry Andric 
3460b57cec5SDimitry Andric       if (obj_file != nullptr) {
3470b57cec5SDimitry Andric         m_uuid = obj_file->GetUUID();
3480b57cec5SDimitry Andric         m_did_set_uuid = true;
3490b57cec5SDimitry Andric       }
3500b57cec5SDimitry Andric     }
3510b57cec5SDimitry Andric   }
3520b57cec5SDimitry Andric   return m_uuid;
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric 
3550b57cec5SDimitry Andric void Module::SetUUID(const lldb_private::UUID &uuid) {
3560b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
3570b57cec5SDimitry Andric   if (!m_did_set_uuid) {
3580b57cec5SDimitry Andric     m_uuid = uuid;
3590b57cec5SDimitry Andric     m_did_set_uuid = true;
3600b57cec5SDimitry Andric   } else {
3610b57cec5SDimitry Andric     lldbassert(0 && "Attempting to overwrite the existing module UUID");
3620b57cec5SDimitry Andric   }
3630b57cec5SDimitry Andric }
3640b57cec5SDimitry Andric 
365bdd1243dSDimitry Andric llvm::Expected<TypeSystemSP>
3669dba64beSDimitry Andric Module::GetTypeSystemForLanguage(LanguageType language) {
3670b57cec5SDimitry Andric   return m_type_system_map.GetTypeSystemForLanguage(language, this, true);
3680b57cec5SDimitry Andric }
3690b57cec5SDimitry Andric 
370bdd1243dSDimitry Andric void Module::ForEachTypeSystem(
371bdd1243dSDimitry Andric     llvm::function_ref<bool(lldb::TypeSystemSP)> callback) {
372bdd1243dSDimitry Andric   m_type_system_map.ForEach(callback);
373bdd1243dSDimitry Andric }
374bdd1243dSDimitry Andric 
3750b57cec5SDimitry Andric void Module::ParseAllDebugSymbols() {
3760b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
3770b57cec5SDimitry Andric   size_t num_comp_units = GetNumCompileUnits();
3780b57cec5SDimitry Andric   if (num_comp_units == 0)
3790b57cec5SDimitry Andric     return;
3800b57cec5SDimitry Andric 
3819dba64beSDimitry Andric   SymbolFile *symbols = GetSymbolFile();
3820b57cec5SDimitry Andric 
3830b57cec5SDimitry Andric   for (size_t cu_idx = 0; cu_idx < num_comp_units; cu_idx++) {
3845ffd83dbSDimitry Andric     SymbolContext sc;
3855ffd83dbSDimitry Andric     sc.module_sp = shared_from_this();
3860b57cec5SDimitry Andric     sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get();
3870b57cec5SDimitry Andric     if (!sc.comp_unit)
3880b57cec5SDimitry Andric       continue;
3890b57cec5SDimitry Andric 
3900b57cec5SDimitry Andric     symbols->ParseVariablesForContext(sc);
3910b57cec5SDimitry Andric 
3920b57cec5SDimitry Andric     symbols->ParseFunctions(*sc.comp_unit);
3930b57cec5SDimitry Andric 
3940b57cec5SDimitry Andric     sc.comp_unit->ForeachFunction([&sc, &symbols](const FunctionSP &f) {
3950b57cec5SDimitry Andric       symbols->ParseBlocksRecursive(*f);
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric       // Parse the variables for this function and all its blocks
3980b57cec5SDimitry Andric       sc.function = f.get();
3990b57cec5SDimitry Andric       symbols->ParseVariablesForContext(sc);
4000b57cec5SDimitry Andric       return false;
4010b57cec5SDimitry Andric     });
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric     // Parse all types for this compile unit
4040b57cec5SDimitry Andric     symbols->ParseTypes(*sc.comp_unit);
4050b57cec5SDimitry Andric   }
4060b57cec5SDimitry Andric }
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric void Module::CalculateSymbolContext(SymbolContext *sc) {
4090b57cec5SDimitry Andric   sc->module_sp = shared_from_this();
4100b57cec5SDimitry Andric }
4110b57cec5SDimitry Andric 
4120b57cec5SDimitry Andric ModuleSP Module::CalculateSymbolContextModule() { return shared_from_this(); }
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric void Module::DumpSymbolContext(Stream *s) {
4150b57cec5SDimitry Andric   s->Printf(", Module{%p}", static_cast<void *>(this));
4160b57cec5SDimitry Andric }
4170b57cec5SDimitry Andric 
4180b57cec5SDimitry Andric size_t Module::GetNumCompileUnits() {
4190b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
4209dba64beSDimitry Andric   if (SymbolFile *symbols = GetSymbolFile())
4210b57cec5SDimitry Andric     return symbols->GetNumCompileUnits();
4220b57cec5SDimitry Andric   return 0;
4230b57cec5SDimitry Andric }
4240b57cec5SDimitry Andric 
4250b57cec5SDimitry Andric CompUnitSP Module::GetCompileUnitAtIndex(size_t index) {
4260b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
4270b57cec5SDimitry Andric   size_t num_comp_units = GetNumCompileUnits();
4280b57cec5SDimitry Andric   CompUnitSP cu_sp;
4290b57cec5SDimitry Andric 
4300b57cec5SDimitry Andric   if (index < num_comp_units) {
4319dba64beSDimitry Andric     if (SymbolFile *symbols = GetSymbolFile())
4320b57cec5SDimitry Andric       cu_sp = symbols->GetCompileUnitAtIndex(index);
4330b57cec5SDimitry Andric   }
4340b57cec5SDimitry Andric   return cu_sp;
4350b57cec5SDimitry Andric }
4360b57cec5SDimitry Andric 
4370b57cec5SDimitry Andric bool Module::ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) {
4380b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
4390b57cec5SDimitry Andric   SectionList *section_list = GetSectionList();
4400b57cec5SDimitry Andric   if (section_list)
4410b57cec5SDimitry Andric     return so_addr.ResolveAddressUsingFileSections(vm_addr, section_list);
4420b57cec5SDimitry Andric   return false;
4430b57cec5SDimitry Andric }
4440b57cec5SDimitry Andric 
4450b57cec5SDimitry Andric uint32_t Module::ResolveSymbolContextForAddress(
4460b57cec5SDimitry Andric     const Address &so_addr, lldb::SymbolContextItem resolve_scope,
4470b57cec5SDimitry Andric     SymbolContext &sc, bool resolve_tail_call_address) {
4480b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
4490b57cec5SDimitry Andric   uint32_t resolved_flags = 0;
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric   // Clear the result symbol context in case we don't find anything, but don't
4520b57cec5SDimitry Andric   // clear the target
4530b57cec5SDimitry Andric   sc.Clear(false);
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric   // Get the section from the section/offset address.
4560b57cec5SDimitry Andric   SectionSP section_sp(so_addr.GetSection());
4570b57cec5SDimitry Andric 
4580b57cec5SDimitry Andric   // Make sure the section matches this module before we try and match anything
4590b57cec5SDimitry Andric   if (section_sp && section_sp->GetModule().get() == this) {
4600b57cec5SDimitry Andric     // If the section offset based address resolved itself, then this is the
4610b57cec5SDimitry Andric     // right module.
4620b57cec5SDimitry Andric     sc.module_sp = shared_from_this();
4630b57cec5SDimitry Andric     resolved_flags |= eSymbolContextModule;
4640b57cec5SDimitry Andric 
4659dba64beSDimitry Andric     SymbolFile *symfile = GetSymbolFile();
4669dba64beSDimitry Andric     if (!symfile)
4670b57cec5SDimitry Andric       return resolved_flags;
4680b57cec5SDimitry Andric 
4690b57cec5SDimitry Andric     // Resolve the compile unit, function, block, line table or line entry if
4700b57cec5SDimitry Andric     // requested.
4710b57cec5SDimitry Andric     if (resolve_scope & eSymbolContextCompUnit ||
4720b57cec5SDimitry Andric         resolve_scope & eSymbolContextFunction ||
4730b57cec5SDimitry Andric         resolve_scope & eSymbolContextBlock ||
4740b57cec5SDimitry Andric         resolve_scope & eSymbolContextLineEntry ||
4750b57cec5SDimitry Andric         resolve_scope & eSymbolContextVariable) {
47681ad6265SDimitry Andric       symfile->SetLoadDebugInfoEnabled();
4770b57cec5SDimitry Andric       resolved_flags |=
4789dba64beSDimitry Andric           symfile->ResolveSymbolContext(so_addr, resolve_scope, sc);
4790b57cec5SDimitry Andric     }
4800b57cec5SDimitry Andric 
4810b57cec5SDimitry Andric     // Resolve the symbol if requested, but don't re-look it up if we've
4820b57cec5SDimitry Andric     // already found it.
4830b57cec5SDimitry Andric     if (resolve_scope & eSymbolContextSymbol &&
4840b57cec5SDimitry Andric         !(resolved_flags & eSymbolContextSymbol)) {
4859dba64beSDimitry Andric       Symtab *symtab = symfile->GetSymtab();
4860b57cec5SDimitry Andric       if (symtab && so_addr.IsSectionOffset()) {
4870b57cec5SDimitry Andric         Symbol *matching_symbol = nullptr;
4880b57cec5SDimitry Andric 
4890b57cec5SDimitry Andric         symtab->ForEachSymbolContainingFileAddress(
4900b57cec5SDimitry Andric             so_addr.GetFileAddress(),
4910b57cec5SDimitry Andric             [&matching_symbol](Symbol *symbol) -> bool {
4920b57cec5SDimitry Andric               if (symbol->GetType() != eSymbolTypeInvalid) {
4930b57cec5SDimitry Andric                 matching_symbol = symbol;
4940b57cec5SDimitry Andric                 return false; // Stop iterating
4950b57cec5SDimitry Andric               }
4960b57cec5SDimitry Andric               return true; // Keep iterating
4970b57cec5SDimitry Andric             });
4980b57cec5SDimitry Andric         sc.symbol = matching_symbol;
4990b57cec5SDimitry Andric         if (!sc.symbol && resolve_scope & eSymbolContextFunction &&
5000b57cec5SDimitry Andric             !(resolved_flags & eSymbolContextFunction)) {
5010b57cec5SDimitry Andric           bool verify_unique = false; // No need to check again since
5020b57cec5SDimitry Andric                                       // ResolveSymbolContext failed to find a
5030b57cec5SDimitry Andric                                       // symbol at this address.
5040b57cec5SDimitry Andric           if (ObjectFile *obj_file = sc.module_sp->GetObjectFile())
5050b57cec5SDimitry Andric             sc.symbol =
5060b57cec5SDimitry Andric                 obj_file->ResolveSymbolForAddress(so_addr, verify_unique);
5070b57cec5SDimitry Andric         }
5080b57cec5SDimitry Andric 
5090b57cec5SDimitry Andric         if (sc.symbol) {
5100b57cec5SDimitry Andric           if (sc.symbol->IsSynthetic()) {
5110b57cec5SDimitry Andric             // We have a synthetic symbol so lets check if the object file from
5120b57cec5SDimitry Andric             // the symbol file in the symbol vendor is different than the
5130b57cec5SDimitry Andric             // object file for the module, and if so search its symbol table to
5140b57cec5SDimitry Andric             // see if we can come up with a better symbol. For example dSYM
5150b57cec5SDimitry Andric             // files on MacOSX have an unstripped symbol table inside of them.
5160b57cec5SDimitry Andric             ObjectFile *symtab_objfile = symtab->GetObjectFile();
5170b57cec5SDimitry Andric             if (symtab_objfile && symtab_objfile->IsStripped()) {
5180b57cec5SDimitry Andric               ObjectFile *symfile_objfile = symfile->GetObjectFile();
5190b57cec5SDimitry Andric               if (symfile_objfile != symtab_objfile) {
5200b57cec5SDimitry Andric                 Symtab *symfile_symtab = symfile_objfile->GetSymtab();
5210b57cec5SDimitry Andric                 if (symfile_symtab) {
5220b57cec5SDimitry Andric                   Symbol *symbol =
5230b57cec5SDimitry Andric                       symfile_symtab->FindSymbolContainingFileAddress(
5240b57cec5SDimitry Andric                           so_addr.GetFileAddress());
5250b57cec5SDimitry Andric                   if (symbol && !symbol->IsSynthetic()) {
5260b57cec5SDimitry Andric                     sc.symbol = symbol;
5270b57cec5SDimitry Andric                   }
5280b57cec5SDimitry Andric                 }
5290b57cec5SDimitry Andric               }
5300b57cec5SDimitry Andric             }
5310b57cec5SDimitry Andric           }
5320b57cec5SDimitry Andric           resolved_flags |= eSymbolContextSymbol;
5330b57cec5SDimitry Andric         }
5340b57cec5SDimitry Andric       }
5350b57cec5SDimitry Andric     }
5360b57cec5SDimitry Andric 
5370b57cec5SDimitry Andric     // For function symbols, so_addr may be off by one.  This is a convention
5380b57cec5SDimitry Andric     // consistent with FDE row indices in eh_frame sections, but requires extra
5390b57cec5SDimitry Andric     // logic here to permit symbol lookup for disassembly and unwind.
5400b57cec5SDimitry Andric     if (resolve_scope & eSymbolContextSymbol &&
5410b57cec5SDimitry Andric         !(resolved_flags & eSymbolContextSymbol) && resolve_tail_call_address &&
5420b57cec5SDimitry Andric         so_addr.IsSectionOffset()) {
5430b57cec5SDimitry Andric       Address previous_addr = so_addr;
5440b57cec5SDimitry Andric       previous_addr.Slide(-1);
5450b57cec5SDimitry Andric 
5460b57cec5SDimitry Andric       bool do_resolve_tail_call_address = false; // prevent recursion
5470b57cec5SDimitry Andric       const uint32_t flags = ResolveSymbolContextForAddress(
5480b57cec5SDimitry Andric           previous_addr, resolve_scope, sc, do_resolve_tail_call_address);
5490b57cec5SDimitry Andric       if (flags & eSymbolContextSymbol) {
5500b57cec5SDimitry Andric         AddressRange addr_range;
5510b57cec5SDimitry Andric         if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
5520b57cec5SDimitry Andric                                false, addr_range)) {
5530b57cec5SDimitry Andric           if (addr_range.GetBaseAddress().GetSection() ==
5540b57cec5SDimitry Andric               so_addr.GetSection()) {
5550b57cec5SDimitry Andric             // If the requested address is one past the address range of a
5560b57cec5SDimitry Andric             // function (i.e. a tail call), or the decremented address is the
5570b57cec5SDimitry Andric             // start of a function (i.e. some forms of trampoline), indicate
5580b57cec5SDimitry Andric             // that the symbol has been resolved.
5590b57cec5SDimitry Andric             if (so_addr.GetOffset() ==
5600b57cec5SDimitry Andric                     addr_range.GetBaseAddress().GetOffset() ||
5610eae32dcSDimitry Andric                 so_addr.GetOffset() == addr_range.GetBaseAddress().GetOffset() +
5620b57cec5SDimitry Andric                                            addr_range.GetByteSize()) {
5630b57cec5SDimitry Andric               resolved_flags |= flags;
5640b57cec5SDimitry Andric             }
5650b57cec5SDimitry Andric           } else {
5660b57cec5SDimitry Andric             sc.symbol =
5670b57cec5SDimitry Andric                 nullptr; // Don't trust the symbol if the sections didn't match.
5680b57cec5SDimitry Andric           }
5690b57cec5SDimitry Andric         }
5700b57cec5SDimitry Andric       }
5710b57cec5SDimitry Andric     }
5720b57cec5SDimitry Andric   }
5730b57cec5SDimitry Andric   return resolved_flags;
5740b57cec5SDimitry Andric }
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric uint32_t Module::ResolveSymbolContextForFilePath(
5770b57cec5SDimitry Andric     const char *file_path, uint32_t line, bool check_inlines,
5780b57cec5SDimitry Andric     lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
5790b57cec5SDimitry Andric   FileSpec file_spec(file_path);
5800b57cec5SDimitry Andric   return ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
5810b57cec5SDimitry Andric                                           resolve_scope, sc_list);
5820b57cec5SDimitry Andric }
5830b57cec5SDimitry Andric 
5840b57cec5SDimitry Andric uint32_t Module::ResolveSymbolContextsForFileSpec(
5850b57cec5SDimitry Andric     const FileSpec &file_spec, uint32_t line, bool check_inlines,
5860b57cec5SDimitry Andric     lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
5870b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
588e8d8bef9SDimitry Andric   LLDB_SCOPED_TIMERF("Module::ResolveSymbolContextForFilePath (%s:%u, "
5890b57cec5SDimitry Andric                      "check_inlines = %s, resolve_scope = 0x%8.8x)",
5900b57cec5SDimitry Andric                      file_spec.GetPath().c_str(), line,
5910b57cec5SDimitry Andric                      check_inlines ? "yes" : "no", resolve_scope);
5920b57cec5SDimitry Andric 
5930b57cec5SDimitry Andric   const uint32_t initial_count = sc_list.GetSize();
5940b57cec5SDimitry Andric 
595fe6060f1SDimitry Andric   if (SymbolFile *symbols = GetSymbolFile()) {
596fe6060f1SDimitry Andric     // TODO: Handle SourceLocationSpec column information
597bdd1243dSDimitry Andric     SourceLocationSpec location_spec(file_spec, line, /*column=*/std::nullopt,
598fe6060f1SDimitry Andric                                      check_inlines, /*exact_match=*/false);
599fe6060f1SDimitry Andric 
600fe6060f1SDimitry Andric     symbols->ResolveSymbolContext(location_spec, resolve_scope, sc_list);
601fe6060f1SDimitry Andric   }
6020b57cec5SDimitry Andric 
6030b57cec5SDimitry Andric   return sc_list.GetSize() - initial_count;
6040b57cec5SDimitry Andric }
6050b57cec5SDimitry Andric 
6069dba64beSDimitry Andric void Module::FindGlobalVariables(ConstString name,
6075ffd83dbSDimitry Andric                                  const CompilerDeclContext &parent_decl_ctx,
6089dba64beSDimitry Andric                                  size_t max_matches, VariableList &variables) {
6099dba64beSDimitry Andric   if (SymbolFile *symbols = GetSymbolFile())
6109dba64beSDimitry Andric     symbols->FindGlobalVariables(name, parent_decl_ctx, max_matches, variables);
6110b57cec5SDimitry Andric }
6120b57cec5SDimitry Andric 
6139dba64beSDimitry Andric void Module::FindGlobalVariables(const RegularExpression &regex,
6149dba64beSDimitry Andric                                  size_t max_matches, VariableList &variables) {
6159dba64beSDimitry Andric   SymbolFile *symbols = GetSymbolFile();
6160b57cec5SDimitry Andric   if (symbols)
6179dba64beSDimitry Andric     symbols->FindGlobalVariables(regex, max_matches, variables);
6180b57cec5SDimitry Andric }
6190b57cec5SDimitry Andric 
6209dba64beSDimitry Andric void Module::FindCompileUnits(const FileSpec &path,
6210b57cec5SDimitry Andric                               SymbolContextList &sc_list) {
6220b57cec5SDimitry Andric   const size_t num_compile_units = GetNumCompileUnits();
6230b57cec5SDimitry Andric   SymbolContext sc;
6240b57cec5SDimitry Andric   sc.module_sp = shared_from_this();
6250b57cec5SDimitry Andric   for (size_t i = 0; i < num_compile_units; ++i) {
6260b57cec5SDimitry Andric     sc.comp_unit = GetCompileUnitAtIndex(i).get();
6270b57cec5SDimitry Andric     if (sc.comp_unit) {
628480093f4SDimitry Andric       if (FileSpec::Match(path, sc.comp_unit->GetPrimaryFile()))
6290b57cec5SDimitry Andric         sc_list.Append(sc);
6300b57cec5SDimitry Andric     }
6310b57cec5SDimitry Andric   }
6320b57cec5SDimitry Andric }
6330b57cec5SDimitry Andric 
6340b57cec5SDimitry Andric Module::LookupInfo::LookupInfo(ConstString name,
6350b57cec5SDimitry Andric                                FunctionNameType name_type_mask,
6360b57cec5SDimitry Andric                                LanguageType language)
63781ad6265SDimitry Andric     : m_name(name), m_lookup_name(), m_language(language) {
6380b57cec5SDimitry Andric   const char *name_cstr = name.GetCString();
6390b57cec5SDimitry Andric   llvm::StringRef basename;
6400b57cec5SDimitry Andric   llvm::StringRef context;
6410b57cec5SDimitry Andric 
6420b57cec5SDimitry Andric   if (name_type_mask & eFunctionNameTypeAuto) {
6430b57cec5SDimitry Andric     if (CPlusPlusLanguage::IsCPPMangledName(name_cstr))
6440b57cec5SDimitry Andric       m_name_type_mask = eFunctionNameTypeFull;
6450b57cec5SDimitry Andric     else if ((language == eLanguageTypeUnknown ||
6460b57cec5SDimitry Andric               Language::LanguageIsObjC(language)) &&
6470b57cec5SDimitry Andric              ObjCLanguage::IsPossibleObjCMethodName(name_cstr))
6480b57cec5SDimitry Andric       m_name_type_mask = eFunctionNameTypeFull;
6490b57cec5SDimitry Andric     else if (Language::LanguageIsC(language)) {
6500b57cec5SDimitry Andric       m_name_type_mask = eFunctionNameTypeFull;
6510b57cec5SDimitry Andric     } else {
6520b57cec5SDimitry Andric       if ((language == eLanguageTypeUnknown ||
6530b57cec5SDimitry Andric            Language::LanguageIsObjC(language)) &&
6540b57cec5SDimitry Andric           ObjCLanguage::IsPossibleObjCSelector(name_cstr))
6550b57cec5SDimitry Andric         m_name_type_mask |= eFunctionNameTypeSelector;
6560b57cec5SDimitry Andric 
6570b57cec5SDimitry Andric       CPlusPlusLanguage::MethodName cpp_method(name);
6580b57cec5SDimitry Andric       basename = cpp_method.GetBasename();
6590b57cec5SDimitry Andric       if (basename.empty()) {
6600b57cec5SDimitry Andric         if (CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
6610b57cec5SDimitry Andric                                                            basename))
6620b57cec5SDimitry Andric           m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
6630b57cec5SDimitry Andric         else
6640b57cec5SDimitry Andric           m_name_type_mask |= eFunctionNameTypeFull;
6650b57cec5SDimitry Andric       } else {
6660b57cec5SDimitry Andric         m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
6670b57cec5SDimitry Andric       }
6680b57cec5SDimitry Andric     }
6690b57cec5SDimitry Andric   } else {
6700b57cec5SDimitry Andric     m_name_type_mask = name_type_mask;
6710b57cec5SDimitry Andric     if (name_type_mask & eFunctionNameTypeMethod ||
6720b57cec5SDimitry Andric         name_type_mask & eFunctionNameTypeBase) {
6730b57cec5SDimitry Andric       // If they've asked for a CPP method or function name and it can't be
6740b57cec5SDimitry Andric       // that, we don't even need to search for CPP methods or names.
6750b57cec5SDimitry Andric       CPlusPlusLanguage::MethodName cpp_method(name);
6760b57cec5SDimitry Andric       if (cpp_method.IsValid()) {
6770b57cec5SDimitry Andric         basename = cpp_method.GetBasename();
6780b57cec5SDimitry Andric 
6790b57cec5SDimitry Andric         if (!cpp_method.GetQualifiers().empty()) {
6800b57cec5SDimitry Andric           // There is a "const" or other qualifier following the end of the
6810b57cec5SDimitry Andric           // function parens, this can't be a eFunctionNameTypeBase
6820b57cec5SDimitry Andric           m_name_type_mask &= ~(eFunctionNameTypeBase);
6830b57cec5SDimitry Andric           if (m_name_type_mask == eFunctionNameTypeNone)
6840b57cec5SDimitry Andric             return;
6850b57cec5SDimitry Andric         }
6860b57cec5SDimitry Andric       } else {
6870b57cec5SDimitry Andric         // If the CPP method parser didn't manage to chop this up, try to fill
6880b57cec5SDimitry Andric         // in the base name if we can. If a::b::c is passed in, we need to just
6890b57cec5SDimitry Andric         // look up "c", and then we'll filter the result later.
6900b57cec5SDimitry Andric         CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
6910b57cec5SDimitry Andric                                                        basename);
6920b57cec5SDimitry Andric       }
6930b57cec5SDimitry Andric     }
6940b57cec5SDimitry Andric 
6950b57cec5SDimitry Andric     if (name_type_mask & eFunctionNameTypeSelector) {
6960b57cec5SDimitry Andric       if (!ObjCLanguage::IsPossibleObjCSelector(name_cstr)) {
6970b57cec5SDimitry Andric         m_name_type_mask &= ~(eFunctionNameTypeSelector);
6980b57cec5SDimitry Andric         if (m_name_type_mask == eFunctionNameTypeNone)
6990b57cec5SDimitry Andric           return;
7000b57cec5SDimitry Andric       }
7010b57cec5SDimitry Andric     }
7020b57cec5SDimitry Andric 
7030b57cec5SDimitry Andric     // Still try and get a basename in case someone specifies a name type mask
7040b57cec5SDimitry Andric     // of eFunctionNameTypeFull and a name like "A::func"
7050b57cec5SDimitry Andric     if (basename.empty()) {
7060b57cec5SDimitry Andric       if (name_type_mask & eFunctionNameTypeFull &&
7070b57cec5SDimitry Andric           !CPlusPlusLanguage::IsCPPMangledName(name_cstr)) {
7080b57cec5SDimitry Andric         CPlusPlusLanguage::MethodName cpp_method(name);
7090b57cec5SDimitry Andric         basename = cpp_method.GetBasename();
7100b57cec5SDimitry Andric         if (basename.empty())
7110b57cec5SDimitry Andric           CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
7120b57cec5SDimitry Andric                                                          basename);
7130b57cec5SDimitry Andric       }
7140b57cec5SDimitry Andric     }
7150b57cec5SDimitry Andric   }
7160b57cec5SDimitry Andric 
7170b57cec5SDimitry Andric   if (!basename.empty()) {
7180b57cec5SDimitry Andric     // The name supplied was a partial C++ path like "a::count". In this case
7190b57cec5SDimitry Andric     // we want to do a lookup on the basename "count" and then make sure any
7200b57cec5SDimitry Andric     // matching results contain "a::count" so that it would match "b::a::count"
7210b57cec5SDimitry Andric     // and "a::count". This is why we set "match_name_after_lookup" to true
7220b57cec5SDimitry Andric     m_lookup_name.SetString(basename);
7230b57cec5SDimitry Andric     m_match_name_after_lookup = true;
7240b57cec5SDimitry Andric   } else {
7250b57cec5SDimitry Andric     // The name is already correct, just use the exact name as supplied, and we
7260b57cec5SDimitry Andric     // won't need to check if any matches contain "name"
7270b57cec5SDimitry Andric     m_lookup_name = name;
7280b57cec5SDimitry Andric     m_match_name_after_lookup = false;
7290b57cec5SDimitry Andric   }
7300b57cec5SDimitry Andric }
7310b57cec5SDimitry Andric 
732bdd1243dSDimitry Andric bool Module::LookupInfo::NameMatchesLookupInfo(
733bdd1243dSDimitry Andric     ConstString function_name, LanguageType language_type) const {
734bdd1243dSDimitry Andric   // We always keep unnamed symbols
735bdd1243dSDimitry Andric   if (!function_name)
736bdd1243dSDimitry Andric     return true;
737bdd1243dSDimitry Andric 
738bdd1243dSDimitry Andric   // If we match exactly, we can return early
739bdd1243dSDimitry Andric   if (m_name == function_name)
740bdd1243dSDimitry Andric     return true;
741bdd1243dSDimitry Andric 
742bdd1243dSDimitry Andric   // If function_name is mangled, we'll need to demangle it.
743bdd1243dSDimitry Andric   // In the pathologial case where the function name "looks" mangled but is
744bdd1243dSDimitry Andric   // actually demangled (e.g. a method named _Zonk), this operation should be
745bdd1243dSDimitry Andric   // relatively inexpensive since no demangling is actually occuring. See
746bdd1243dSDimitry Andric   // Mangled::SetValue for more context.
747bdd1243dSDimitry Andric   const bool function_name_may_be_mangled =
74806c3fb27SDimitry Andric       Mangled::GetManglingScheme(function_name) != Mangled::eManglingSchemeNone;
749bdd1243dSDimitry Andric   ConstString demangled_function_name = function_name;
750bdd1243dSDimitry Andric   if (function_name_may_be_mangled) {
751bdd1243dSDimitry Andric     Mangled mangled_function_name(function_name);
752bdd1243dSDimitry Andric     demangled_function_name = mangled_function_name.GetDemangledName();
753bdd1243dSDimitry Andric   }
754bdd1243dSDimitry Andric 
755bdd1243dSDimitry Andric   // If the symbol has a language, then let the language make the match.
756bdd1243dSDimitry Andric   // Otherwise just check that the demangled function name contains the
757bdd1243dSDimitry Andric   // demangled user-provided name.
758bdd1243dSDimitry Andric   if (Language *language = Language::FindPlugin(language_type))
75906c3fb27SDimitry Andric     return language->DemangledNameContainsPath(m_name, demangled_function_name);
760bdd1243dSDimitry Andric 
76106c3fb27SDimitry Andric   llvm::StringRef function_name_ref = demangled_function_name;
76206c3fb27SDimitry Andric   return function_name_ref.contains(m_name);
763bdd1243dSDimitry Andric }
764bdd1243dSDimitry Andric 
7650b57cec5SDimitry Andric void Module::LookupInfo::Prune(SymbolContextList &sc_list,
7660b57cec5SDimitry Andric                                size_t start_idx) const {
7670b57cec5SDimitry Andric   if (m_match_name_after_lookup && m_name) {
7680b57cec5SDimitry Andric     SymbolContext sc;
7690b57cec5SDimitry Andric     size_t i = start_idx;
7700b57cec5SDimitry Andric     while (i < sc_list.GetSize()) {
7710b57cec5SDimitry Andric       if (!sc_list.GetContextAtIndex(i, sc))
7720b57cec5SDimitry Andric         break;
77381ad6265SDimitry Andric 
774bdd1243dSDimitry Andric       bool keep_it =
775bdd1243dSDimitry Andric           NameMatchesLookupInfo(sc.GetFunctionName(), sc.GetLanguage());
77681ad6265SDimitry Andric       if (keep_it)
77781ad6265SDimitry Andric         ++i;
77881ad6265SDimitry Andric       else
77981ad6265SDimitry Andric         sc_list.RemoveContextAtIndex(i);
7800b57cec5SDimitry Andric     }
7810b57cec5SDimitry Andric   }
7820b57cec5SDimitry Andric 
7830b57cec5SDimitry Andric   // If we have only full name matches we might have tried to set breakpoint on
7840b57cec5SDimitry Andric   // "func" and specified eFunctionNameTypeFull, but we might have found
7850b57cec5SDimitry Andric   // "a::func()", "a::b::func()", "c::func()", "func()" and "func". Only
7860b57cec5SDimitry Andric   // "func()" and "func" should end up matching.
7870b57cec5SDimitry Andric   if (m_name_type_mask == eFunctionNameTypeFull) {
7880b57cec5SDimitry Andric     SymbolContext sc;
7890b57cec5SDimitry Andric     size_t i = start_idx;
7900b57cec5SDimitry Andric     while (i < sc_list.GetSize()) {
7910b57cec5SDimitry Andric       if (!sc_list.GetContextAtIndex(i, sc))
7920b57cec5SDimitry Andric         break;
7930b57cec5SDimitry Andric       // Make sure the mangled and demangled names don't match before we try to
7940b57cec5SDimitry Andric       // pull anything out
7950b57cec5SDimitry Andric       ConstString mangled_name(sc.GetFunctionName(Mangled::ePreferMangled));
7960b57cec5SDimitry Andric       ConstString full_name(sc.GetFunctionName());
7970eae32dcSDimitry Andric       if (mangled_name != m_name && full_name != m_name) {
7980b57cec5SDimitry Andric         CPlusPlusLanguage::MethodName cpp_method(full_name);
7990b57cec5SDimitry Andric         if (cpp_method.IsValid()) {
8000b57cec5SDimitry Andric           if (cpp_method.GetContext().empty()) {
80106c3fb27SDimitry Andric             if (cpp_method.GetBasename().compare(m_name) != 0) {
8020b57cec5SDimitry Andric               sc_list.RemoveContextAtIndex(i);
8030b57cec5SDimitry Andric               continue;
8040b57cec5SDimitry Andric             }
8050b57cec5SDimitry Andric           } else {
8060b57cec5SDimitry Andric             std::string qualified_name;
8070b57cec5SDimitry Andric             llvm::StringRef anon_prefix("(anonymous namespace)");
8080b57cec5SDimitry Andric             if (cpp_method.GetContext() == anon_prefix)
8090b57cec5SDimitry Andric               qualified_name = cpp_method.GetBasename().str();
8100b57cec5SDimitry Andric             else
8110b57cec5SDimitry Andric               qualified_name = cpp_method.GetScopeQualifiedName();
8120b57cec5SDimitry Andric             if (qualified_name != m_name.GetCString()) {
8130b57cec5SDimitry Andric               sc_list.RemoveContextAtIndex(i);
8140b57cec5SDimitry Andric               continue;
8150b57cec5SDimitry Andric             }
8160b57cec5SDimitry Andric           }
8170b57cec5SDimitry Andric         }
8180b57cec5SDimitry Andric       }
8190b57cec5SDimitry Andric       ++i;
8200b57cec5SDimitry Andric     }
8210b57cec5SDimitry Andric   }
8220b57cec5SDimitry Andric }
8230b57cec5SDimitry Andric 
824bdd1243dSDimitry Andric void Module::FindFunctions(const Module::LookupInfo &lookup_info,
825bdd1243dSDimitry Andric                            const CompilerDeclContext &parent_decl_ctx,
826bdd1243dSDimitry Andric                            const ModuleFunctionSearchOptions &options,
827bdd1243dSDimitry Andric                            SymbolContextList &sc_list) {
828bdd1243dSDimitry Andric   // Find all the functions (not symbols, but debug information functions...
829bdd1243dSDimitry Andric   if (SymbolFile *symbols = GetSymbolFile()) {
830bdd1243dSDimitry Andric     symbols->FindFunctions(lookup_info, parent_decl_ctx,
831bdd1243dSDimitry Andric                            options.include_inlines, sc_list);
832bdd1243dSDimitry Andric     // Now check our symbol table for symbols that are code symbols if
833bdd1243dSDimitry Andric     // requested
834bdd1243dSDimitry Andric     if (options.include_symbols) {
835bdd1243dSDimitry Andric       if (Symtab *symtab = symbols->GetSymtab()) {
836bdd1243dSDimitry Andric         symtab->FindFunctionSymbols(lookup_info.GetLookupName(),
837bdd1243dSDimitry Andric                                     lookup_info.GetNameTypeMask(), sc_list);
838bdd1243dSDimitry Andric       }
839bdd1243dSDimitry Andric     }
840bdd1243dSDimitry Andric   }
841bdd1243dSDimitry Andric }
842bdd1243dSDimitry Andric 
8439dba64beSDimitry Andric void Module::FindFunctions(ConstString name,
8445ffd83dbSDimitry Andric                            const CompilerDeclContext &parent_decl_ctx,
8450b57cec5SDimitry Andric                            FunctionNameType name_type_mask,
846349cc55cSDimitry Andric                            const ModuleFunctionSearchOptions &options,
8479dba64beSDimitry Andric                            SymbolContextList &sc_list) {
8480b57cec5SDimitry Andric   const size_t old_size = sc_list.GetSize();
8490b57cec5SDimitry Andric   LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
850bdd1243dSDimitry Andric   FindFunctions(lookup_info, parent_decl_ctx, options, sc_list);
851bdd1243dSDimitry Andric   if (name_type_mask & eFunctionNameTypeAuto) {
8520b57cec5SDimitry Andric     const size_t new_size = sc_list.GetSize();
8530b57cec5SDimitry Andric     if (old_size < new_size)
8540b57cec5SDimitry Andric       lookup_info.Prune(sc_list, old_size);
8550b57cec5SDimitry Andric   }
8560b57cec5SDimitry Andric }
8570b57cec5SDimitry Andric 
858297eecfbSDimitry Andric void Module::FindFunctions(llvm::ArrayRef<CompilerContext> compiler_ctx,
859297eecfbSDimitry Andric                            FunctionNameType name_type_mask,
860297eecfbSDimitry Andric                            const ModuleFunctionSearchOptions &options,
861297eecfbSDimitry Andric                            SymbolContextList &sc_list) {
862297eecfbSDimitry Andric   if (compiler_ctx.empty() ||
863297eecfbSDimitry Andric       compiler_ctx.back().kind != CompilerContextKind::Function)
864297eecfbSDimitry Andric     return;
865297eecfbSDimitry Andric   ConstString name = compiler_ctx.back().name;
866297eecfbSDimitry Andric   SymbolContextList unfiltered;
867297eecfbSDimitry Andric   FindFunctions(name, CompilerDeclContext(), name_type_mask, options,
868297eecfbSDimitry Andric                 unfiltered);
869297eecfbSDimitry Andric   // Filter by context.
870297eecfbSDimitry Andric   for (auto &sc : unfiltered)
871297eecfbSDimitry Andric     if (sc.function && compiler_ctx.equals(sc.function->GetCompilerContext()))
872297eecfbSDimitry Andric       sc_list.Append(sc);
873297eecfbSDimitry Andric }
874297eecfbSDimitry Andric 
875349cc55cSDimitry Andric void Module::FindFunctions(const RegularExpression &regex,
876349cc55cSDimitry Andric                            const ModuleFunctionSearchOptions &options,
8779dba64beSDimitry Andric                            SymbolContextList &sc_list) {
8780b57cec5SDimitry Andric   const size_t start_size = sc_list.GetSize();
8790b57cec5SDimitry Andric 
8809dba64beSDimitry Andric   if (SymbolFile *symbols = GetSymbolFile()) {
881349cc55cSDimitry Andric     symbols->FindFunctions(regex, options.include_inlines, sc_list);
8820b57cec5SDimitry Andric 
8830b57cec5SDimitry Andric     // Now check our symbol table for symbols that are code symbols if
8840b57cec5SDimitry Andric     // requested
885349cc55cSDimitry Andric     if (options.include_symbols) {
8860b57cec5SDimitry Andric       Symtab *symtab = symbols->GetSymtab();
8870b57cec5SDimitry Andric       if (symtab) {
8880b57cec5SDimitry Andric         std::vector<uint32_t> symbol_indexes;
8890b57cec5SDimitry Andric         symtab->AppendSymbolIndexesMatchingRegExAndType(
8900b57cec5SDimitry Andric             regex, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny,
8910b57cec5SDimitry Andric             symbol_indexes);
8920b57cec5SDimitry Andric         const size_t num_matches = symbol_indexes.size();
8930b57cec5SDimitry Andric         if (num_matches) {
8940b57cec5SDimitry Andric           SymbolContext sc(this);
8950b57cec5SDimitry Andric           const size_t end_functions_added_index = sc_list.GetSize();
8960b57cec5SDimitry Andric           size_t num_functions_added_to_sc_list =
8970b57cec5SDimitry Andric               end_functions_added_index - start_size;
8980b57cec5SDimitry Andric           if (num_functions_added_to_sc_list == 0) {
8990b57cec5SDimitry Andric             // No functions were added, just symbols, so we can just append
9000b57cec5SDimitry Andric             // them
9010b57cec5SDimitry Andric             for (size_t i = 0; i < num_matches; ++i) {
9020b57cec5SDimitry Andric               sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
9030b57cec5SDimitry Andric               SymbolType sym_type = sc.symbol->GetType();
9040b57cec5SDimitry Andric               if (sc.symbol && (sym_type == eSymbolTypeCode ||
9050b57cec5SDimitry Andric                                 sym_type == eSymbolTypeResolver))
9060b57cec5SDimitry Andric                 sc_list.Append(sc);
9070b57cec5SDimitry Andric             }
9080b57cec5SDimitry Andric           } else {
9090b57cec5SDimitry Andric             typedef std::map<lldb::addr_t, uint32_t> FileAddrToIndexMap;
9100b57cec5SDimitry Andric             FileAddrToIndexMap file_addr_to_index;
9110b57cec5SDimitry Andric             for (size_t i = start_size; i < end_functions_added_index; ++i) {
9120b57cec5SDimitry Andric               const SymbolContext &sc = sc_list[i];
9130b57cec5SDimitry Andric               if (sc.block)
9140b57cec5SDimitry Andric                 continue;
9150b57cec5SDimitry Andric               file_addr_to_index[sc.function->GetAddressRange()
9160b57cec5SDimitry Andric                                      .GetBaseAddress()
9170b57cec5SDimitry Andric                                      .GetFileAddress()] = i;
9180b57cec5SDimitry Andric             }
9190b57cec5SDimitry Andric 
9200b57cec5SDimitry Andric             FileAddrToIndexMap::const_iterator end = file_addr_to_index.end();
9210b57cec5SDimitry Andric             // Functions were added so we need to merge symbols into any
9220b57cec5SDimitry Andric             // existing function symbol contexts
9230b57cec5SDimitry Andric             for (size_t i = start_size; i < num_matches; ++i) {
9240b57cec5SDimitry Andric               sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
9250b57cec5SDimitry Andric               SymbolType sym_type = sc.symbol->GetType();
9260b57cec5SDimitry Andric               if (sc.symbol && sc.symbol->ValueIsAddress() &&
9270b57cec5SDimitry Andric                   (sym_type == eSymbolTypeCode ||
9280b57cec5SDimitry Andric                    sym_type == eSymbolTypeResolver)) {
9290b57cec5SDimitry Andric                 FileAddrToIndexMap::const_iterator pos =
9300b57cec5SDimitry Andric                     file_addr_to_index.find(
9310b57cec5SDimitry Andric                         sc.symbol->GetAddressRef().GetFileAddress());
9320b57cec5SDimitry Andric                 if (pos == end)
9330b57cec5SDimitry Andric                   sc_list.Append(sc);
9340b57cec5SDimitry Andric                 else
9350b57cec5SDimitry Andric                   sc_list[pos->second].symbol = sc.symbol;
9360b57cec5SDimitry Andric               }
9370b57cec5SDimitry Andric             }
9380b57cec5SDimitry Andric           }
9390b57cec5SDimitry Andric         }
9400b57cec5SDimitry Andric       }
9410b57cec5SDimitry Andric     }
9420b57cec5SDimitry Andric   }
9430b57cec5SDimitry Andric }
9440b57cec5SDimitry Andric 
9450b57cec5SDimitry Andric void Module::FindAddressesForLine(const lldb::TargetSP target_sp,
9460b57cec5SDimitry Andric                                   const FileSpec &file, uint32_t line,
9470b57cec5SDimitry Andric                                   Function *function,
9480b57cec5SDimitry Andric                                   std::vector<Address> &output_local,
9490b57cec5SDimitry Andric                                   std::vector<Address> &output_extern) {
9500b57cec5SDimitry Andric   SearchFilterByModule filter(target_sp, m_file);
951fe6060f1SDimitry Andric 
952fe6060f1SDimitry Andric   // TODO: Handle SourceLocationSpec column information
953bdd1243dSDimitry Andric   SourceLocationSpec location_spec(file, line, /*column=*/std::nullopt,
954fe6060f1SDimitry Andric                                    /*check_inlines=*/true,
955fe6060f1SDimitry Andric                                    /*exact_match=*/false);
956fe6060f1SDimitry Andric   AddressResolverFileLine resolver(location_spec);
9570b57cec5SDimitry Andric   resolver.ResolveAddress(filter);
9580b57cec5SDimitry Andric 
9590b57cec5SDimitry Andric   for (size_t n = 0; n < resolver.GetNumberOfAddresses(); n++) {
9600b57cec5SDimitry Andric     Address addr = resolver.GetAddressRangeAtIndex(n).GetBaseAddress();
9610b57cec5SDimitry Andric     Function *f = addr.CalculateSymbolContextFunction();
9620b57cec5SDimitry Andric     if (f && f == function)
9630b57cec5SDimitry Andric       output_local.push_back(addr);
9640b57cec5SDimitry Andric     else
9650b57cec5SDimitry Andric       output_extern.push_back(addr);
9660b57cec5SDimitry Andric   }
9670b57cec5SDimitry Andric }
9680b57cec5SDimitry Andric 
9695f757f3fSDimitry Andric void Module::FindTypes(const TypeQuery &query, TypeResults &results) {
9709dba64beSDimitry Andric   if (SymbolFile *symbols = GetSymbolFile())
9715f757f3fSDimitry Andric     symbols->FindTypes(query, results);
9729dba64beSDimitry Andric }
9739dba64beSDimitry Andric 
97406c3fb27SDimitry Andric static Debugger::DebuggerList
97506c3fb27SDimitry Andric DebuggersOwningModuleRequestingInterruption(Module &module) {
9767a6dacacSDimitry Andric   Debugger::DebuggerList requestors =
9777a6dacacSDimitry Andric       Debugger::DebuggersRequestingInterruption();
97806c3fb27SDimitry Andric   Debugger::DebuggerList interruptors;
97906c3fb27SDimitry Andric   if (requestors.empty())
98006c3fb27SDimitry Andric     return interruptors;
98106c3fb27SDimitry Andric 
98206c3fb27SDimitry Andric   for (auto debugger_sp : requestors) {
98306c3fb27SDimitry Andric     if (!debugger_sp->InterruptRequested())
98406c3fb27SDimitry Andric       continue;
98506c3fb27SDimitry Andric     if (debugger_sp->GetTargetList()
98606c3fb27SDimitry Andric         .AnyTargetContainsModule(module))
98706c3fb27SDimitry Andric       interruptors.push_back(debugger_sp);
98806c3fb27SDimitry Andric   }
98906c3fb27SDimitry Andric   return interruptors;
99006c3fb27SDimitry Andric }
99106c3fb27SDimitry Andric 
9929dba64beSDimitry Andric SymbolFile *Module::GetSymbolFile(bool can_create, Stream *feedback_strm) {
9939dba64beSDimitry Andric   if (!m_did_load_symfile.load()) {
9940b57cec5SDimitry Andric     std::lock_guard<std::recursive_mutex> guard(m_mutex);
9959dba64beSDimitry Andric     if (!m_did_load_symfile.load() && can_create) {
9967a6dacacSDimitry Andric       Debugger::DebuggerList interruptors =
9977a6dacacSDimitry Andric           DebuggersOwningModuleRequestingInterruption(*this);
99806c3fb27SDimitry Andric       if (!interruptors.empty()) {
99906c3fb27SDimitry Andric         for (auto debugger_sp : interruptors) {
100006c3fb27SDimitry Andric           REPORT_INTERRUPTION(*(debugger_sp.get()),
100106c3fb27SDimitry Andric                               "Interrupted fetching symbols for module {0}",
100206c3fb27SDimitry Andric                               this->GetFileSpec());
100306c3fb27SDimitry Andric         }
100406c3fb27SDimitry Andric         return nullptr;
100506c3fb27SDimitry Andric       }
10060b57cec5SDimitry Andric       ObjectFile *obj_file = GetObjectFile();
10070b57cec5SDimitry Andric       if (obj_file != nullptr) {
1008e8d8bef9SDimitry Andric         LLDB_SCOPED_TIMER();
10090b57cec5SDimitry Andric         m_symfile_up.reset(
10100b57cec5SDimitry Andric             SymbolVendor::FindPlugin(shared_from_this(), feedback_strm));
10119dba64beSDimitry Andric         m_did_load_symfile = true;
1012*0fca6ea1SDimitry Andric         if (m_unwind_table)
1013*0fca6ea1SDimitry Andric           m_unwind_table->Update();
10140b57cec5SDimitry Andric       }
10150b57cec5SDimitry Andric     }
10160b57cec5SDimitry Andric   }
10179dba64beSDimitry Andric   return m_symfile_up ? m_symfile_up->GetSymbolFile() : nullptr;
10189dba64beSDimitry Andric }
10199dba64beSDimitry Andric 
10209dba64beSDimitry Andric Symtab *Module::GetSymtab() {
10219dba64beSDimitry Andric   if (SymbolFile *symbols = GetSymbolFile())
10229dba64beSDimitry Andric     return symbols->GetSymtab();
10239dba64beSDimitry Andric   return nullptr;
10240b57cec5SDimitry Andric }
10250b57cec5SDimitry Andric 
10260b57cec5SDimitry Andric void Module::SetFileSpecAndObjectName(const FileSpec &file,
10270b57cec5SDimitry Andric                                       ConstString object_name) {
10280b57cec5SDimitry Andric   // Container objects whose paths do not specify a file directly can call this
10290b57cec5SDimitry Andric   // function to correct the file and object names.
10300b57cec5SDimitry Andric   m_file = file;
10310b57cec5SDimitry Andric   m_mod_time = FileSystem::Instance().GetModificationTime(file);
10320b57cec5SDimitry Andric   m_object_name = object_name;
10330b57cec5SDimitry Andric }
10340b57cec5SDimitry Andric 
10350b57cec5SDimitry Andric const ArchSpec &Module::GetArchitecture() const { return m_arch; }
10360b57cec5SDimitry Andric 
10370b57cec5SDimitry Andric std::string Module::GetSpecificationDescription() const {
10380b57cec5SDimitry Andric   std::string spec(GetFileSpec().GetPath());
10390b57cec5SDimitry Andric   if (m_object_name) {
10400b57cec5SDimitry Andric     spec += '(';
10410b57cec5SDimitry Andric     spec += m_object_name.GetCString();
10420b57cec5SDimitry Andric     spec += ')';
10430b57cec5SDimitry Andric   }
10440b57cec5SDimitry Andric   return spec;
10450b57cec5SDimitry Andric }
10460b57cec5SDimitry Andric 
1047480093f4SDimitry Andric void Module::GetDescription(llvm::raw_ostream &s,
1048480093f4SDimitry Andric                             lldb::DescriptionLevel level) {
10490b57cec5SDimitry Andric   if (level >= eDescriptionLevelFull) {
10500b57cec5SDimitry Andric     if (m_arch.IsValid())
1051480093f4SDimitry Andric       s << llvm::formatv("({0}) ", m_arch.GetArchitectureName());
10520b57cec5SDimitry Andric   }
10530b57cec5SDimitry Andric 
10540b57cec5SDimitry Andric   if (level == eDescriptionLevelBrief) {
10550b57cec5SDimitry Andric     const char *filename = m_file.GetFilename().GetCString();
10560b57cec5SDimitry Andric     if (filename)
1057480093f4SDimitry Andric       s << filename;
10580b57cec5SDimitry Andric   } else {
10590b57cec5SDimitry Andric     char path[PATH_MAX];
10600b57cec5SDimitry Andric     if (m_file.GetPath(path, sizeof(path)))
1061480093f4SDimitry Andric       s << path;
10620b57cec5SDimitry Andric   }
10630b57cec5SDimitry Andric 
10640b57cec5SDimitry Andric   const char *object_name = m_object_name.GetCString();
10650b57cec5SDimitry Andric   if (object_name)
1066480093f4SDimitry Andric     s << llvm::formatv("({0})", object_name);
10670b57cec5SDimitry Andric }
10680b57cec5SDimitry Andric 
10690b57cec5SDimitry Andric bool Module::FileHasChanged() const {
10705ffd83dbSDimitry Andric   // We have provided the DataBuffer for this module to avoid accessing the
10715ffd83dbSDimitry Andric   // filesystem. We never want to reload those files.
10725ffd83dbSDimitry Andric   if (m_data_sp)
10735ffd83dbSDimitry Andric     return false;
10740b57cec5SDimitry Andric   if (!m_file_has_changed)
10750b57cec5SDimitry Andric     m_file_has_changed =
10760b57cec5SDimitry Andric         (FileSystem::Instance().GetModificationTime(m_file) != m_mod_time);
10770b57cec5SDimitry Andric   return m_file_has_changed;
10780b57cec5SDimitry Andric }
10790b57cec5SDimitry Andric 
108081ad6265SDimitry Andric void Module::ReportWarningOptimization(
1081bdd1243dSDimitry Andric     std::optional<lldb::user_id_t> debugger_id) {
108281ad6265SDimitry Andric   ConstString file_name = GetFileSpec().GetFilename();
108381ad6265SDimitry Andric   if (file_name.IsEmpty())
108481ad6265SDimitry Andric     return;
108581ad6265SDimitry Andric 
108681ad6265SDimitry Andric   StreamString ss;
108706c3fb27SDimitry Andric   ss << file_name
108881ad6265SDimitry Andric      << " was compiled with optimization - stepping may behave "
108981ad6265SDimitry Andric         "oddly; variables may not be available.";
109081ad6265SDimitry Andric   Debugger::ReportWarning(std::string(ss.GetString()), debugger_id,
109181ad6265SDimitry Andric                           &m_optimization_warning);
109281ad6265SDimitry Andric }
109381ad6265SDimitry Andric 
109481ad6265SDimitry Andric void Module::ReportWarningUnsupportedLanguage(
1095bdd1243dSDimitry Andric     LanguageType language, std::optional<lldb::user_id_t> debugger_id) {
109681ad6265SDimitry Andric   StreamString ss;
109781ad6265SDimitry Andric   ss << "This version of LLDB has no plugin for the language \""
109881ad6265SDimitry Andric      << Language::GetNameForLanguageType(language)
109981ad6265SDimitry Andric      << "\". "
110081ad6265SDimitry Andric         "Inspection of frame variables will be limited.";
110181ad6265SDimitry Andric   Debugger::ReportWarning(std::string(ss.GetString()), debugger_id,
110281ad6265SDimitry Andric                           &m_language_warning);
110381ad6265SDimitry Andric }
110481ad6265SDimitry Andric 
1105bdd1243dSDimitry Andric void Module::ReportErrorIfModifyDetected(
1106bdd1243dSDimitry Andric     const llvm::formatv_object_base &payload) {
11070b57cec5SDimitry Andric   if (!m_first_file_changed_log) {
11080b57cec5SDimitry Andric     if (FileHasChanged()) {
11090b57cec5SDimitry Andric       m_first_file_changed_log = true;
11100b57cec5SDimitry Andric       StreamString strm;
111181ad6265SDimitry Andric       strm.PutCString("the object file ");
1112480093f4SDimitry Andric       GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelFull);
11130b57cec5SDimitry Andric       strm.PutCString(" has been modified\n");
1114bdd1243dSDimitry Andric       strm.PutCString(payload.str());
11150b57cec5SDimitry Andric       strm.PutCString("The debug session should be aborted as the original "
111681ad6265SDimitry Andric                       "debug information has been overwritten.");
111781ad6265SDimitry Andric       Debugger::ReportError(std::string(strm.GetString()));
11180b57cec5SDimitry Andric     }
11190b57cec5SDimitry Andric   }
11200b57cec5SDimitry Andric }
11210b57cec5SDimitry Andric 
1122bdd1243dSDimitry Andric void Module::ReportError(const llvm::formatv_object_base &payload) {
112381ad6265SDimitry Andric   StreamString strm;
112481ad6265SDimitry Andric   GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelBrief);
112581ad6265SDimitry Andric   strm.PutChar(' ');
1126bdd1243dSDimitry Andric   strm.PutCString(payload.str());
1127bdd1243dSDimitry Andric   Debugger::ReportError(strm.GetString().str());
112881ad6265SDimitry Andric }
112981ad6265SDimitry Andric 
1130bdd1243dSDimitry Andric void Module::ReportWarning(const llvm::formatv_object_base &payload) {
11310b57cec5SDimitry Andric   StreamString strm;
1132480093f4SDimitry Andric   GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelFull);
11330b57cec5SDimitry Andric   strm.PutChar(' ');
1134bdd1243dSDimitry Andric   strm.PutCString(payload.str());
113581ad6265SDimitry Andric   Debugger::ReportWarning(std::string(strm.GetString()));
11360b57cec5SDimitry Andric }
11370b57cec5SDimitry Andric 
1138bdd1243dSDimitry Andric void Module::LogMessage(Log *log, const llvm::formatv_object_base &payload) {
11390b57cec5SDimitry Andric   StreamString log_message;
1140480093f4SDimitry Andric   GetDescription(log_message.AsRawOstream(), lldb::eDescriptionLevelFull);
11410b57cec5SDimitry Andric   log_message.PutCString(": ");
1142bdd1243dSDimitry Andric   log_message.PutCString(payload.str());
11430b57cec5SDimitry Andric   log->PutCString(log_message.GetData());
11440b57cec5SDimitry Andric }
11450b57cec5SDimitry Andric 
1146bdd1243dSDimitry Andric void Module::LogMessageVerboseBacktrace(
1147bdd1243dSDimitry Andric     Log *log, const llvm::formatv_object_base &payload) {
11480b57cec5SDimitry Andric   StreamString log_message;
1149480093f4SDimitry Andric   GetDescription(log_message.AsRawOstream(), lldb::eDescriptionLevelFull);
11500b57cec5SDimitry Andric   log_message.PutCString(": ");
1151bdd1243dSDimitry Andric   log_message.PutCString(payload.str());
11520b57cec5SDimitry Andric   if (log->GetVerbose()) {
11530b57cec5SDimitry Andric     std::string back_trace;
11540b57cec5SDimitry Andric     llvm::raw_string_ostream stream(back_trace);
11550b57cec5SDimitry Andric     llvm::sys::PrintStackTrace(stream);
11560b57cec5SDimitry Andric     log_message.PutCString(back_trace);
11570b57cec5SDimitry Andric   }
11580b57cec5SDimitry Andric   log->PutCString(log_message.GetData());
11590b57cec5SDimitry Andric }
11600b57cec5SDimitry Andric 
11610b57cec5SDimitry Andric void Module::Dump(Stream *s) {
11620b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
11630b57cec5SDimitry Andric   // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
11640b57cec5SDimitry Andric   s->Indent();
11650b57cec5SDimitry Andric   s->Printf("Module %s%s%s%s\n", m_file.GetPath().c_str(),
11660b57cec5SDimitry Andric             m_object_name ? "(" : "",
11670b57cec5SDimitry Andric             m_object_name ? m_object_name.GetCString() : "",
11680b57cec5SDimitry Andric             m_object_name ? ")" : "");
11690b57cec5SDimitry Andric 
11700b57cec5SDimitry Andric   s->IndentMore();
11710b57cec5SDimitry Andric 
11720b57cec5SDimitry Andric   ObjectFile *objfile = GetObjectFile();
11730b57cec5SDimitry Andric   if (objfile)
11740b57cec5SDimitry Andric     objfile->Dump(s);
11750b57cec5SDimitry Andric 
11769dba64beSDimitry Andric   if (SymbolFile *symbols = GetSymbolFile())
11779dba64beSDimitry Andric     symbols->Dump(*s);
11780b57cec5SDimitry Andric 
11790b57cec5SDimitry Andric   s->IndentLess();
11800b57cec5SDimitry Andric }
11810b57cec5SDimitry Andric 
11820b57cec5SDimitry Andric ConstString Module::GetObjectName() const { return m_object_name; }
11830b57cec5SDimitry Andric 
11840b57cec5SDimitry Andric ObjectFile *Module::GetObjectFile() {
11850b57cec5SDimitry Andric   if (!m_did_load_objfile.load()) {
11860b57cec5SDimitry Andric     std::lock_guard<std::recursive_mutex> guard(m_mutex);
11870b57cec5SDimitry Andric     if (!m_did_load_objfile.load()) {
1188e8d8bef9SDimitry Andric       LLDB_SCOPED_TIMERF("Module::GetObjectFile () module = %s",
11890b57cec5SDimitry Andric                          GetFileSpec().GetFilename().AsCString(""));
11900b57cec5SDimitry Andric       lldb::offset_t data_offset = 0;
11915ffd83dbSDimitry Andric       lldb::offset_t file_size = 0;
11925ffd83dbSDimitry Andric 
11935ffd83dbSDimitry Andric       if (m_data_sp)
11945ffd83dbSDimitry Andric         file_size = m_data_sp->GetByteSize();
11955ffd83dbSDimitry Andric       else if (m_file)
11965ffd83dbSDimitry Andric         file_size = FileSystem::Instance().GetByteSize(m_file);
11975ffd83dbSDimitry Andric 
11980b57cec5SDimitry Andric       if (file_size > m_object_offset) {
11990b57cec5SDimitry Andric         m_did_load_objfile = true;
12005ffd83dbSDimitry Andric         // FindPlugin will modify its data_sp argument. Do not let it
12015ffd83dbSDimitry Andric         // modify our m_data_sp member.
12025ffd83dbSDimitry Andric         auto data_sp = m_data_sp;
12030b57cec5SDimitry Andric         m_objfile_sp = ObjectFile::FindPlugin(
12040b57cec5SDimitry Andric             shared_from_this(), &m_file, m_object_offset,
12050b57cec5SDimitry Andric             file_size - m_object_offset, data_sp, data_offset);
12060b57cec5SDimitry Andric         if (m_objfile_sp) {
12070b57cec5SDimitry Andric           // Once we get the object file, update our module with the object
12080b57cec5SDimitry Andric           // file's architecture since it might differ in vendor/os if some
12090b57cec5SDimitry Andric           // parts were unknown.  But since the matching arch might already be
12100b57cec5SDimitry Andric           // more specific than the generic COFF architecture, only merge in
12110b57cec5SDimitry Andric           // those values that overwrite unspecified unknown values.
12120b57cec5SDimitry Andric           m_arch.MergeFrom(m_objfile_sp->GetArchitecture());
12130b57cec5SDimitry Andric         } else {
12145f757f3fSDimitry Andric           ReportError("failed to load objfile for {0}\nDebugging will be "
12155f757f3fSDimitry Andric                       "degraded for this module.",
12160b57cec5SDimitry Andric                       GetFileSpec().GetPath().c_str());
12170b57cec5SDimitry Andric         }
12180b57cec5SDimitry Andric       }
12190b57cec5SDimitry Andric     }
12200b57cec5SDimitry Andric   }
12210b57cec5SDimitry Andric   return m_objfile_sp.get();
12220b57cec5SDimitry Andric }
12230b57cec5SDimitry Andric 
12240b57cec5SDimitry Andric SectionList *Module::GetSectionList() {
12250b57cec5SDimitry Andric   // Populate m_sections_up with sections from objfile.
12260b57cec5SDimitry Andric   if (!m_sections_up) {
12270b57cec5SDimitry Andric     ObjectFile *obj_file = GetObjectFile();
12280b57cec5SDimitry Andric     if (obj_file != nullptr)
12290b57cec5SDimitry Andric       obj_file->CreateSections(*GetUnifiedSectionList());
12300b57cec5SDimitry Andric   }
12310b57cec5SDimitry Andric   return m_sections_up.get();
12320b57cec5SDimitry Andric }
12330b57cec5SDimitry Andric 
12340b57cec5SDimitry Andric void Module::SectionFileAddressesChanged() {
12350b57cec5SDimitry Andric   ObjectFile *obj_file = GetObjectFile();
12360b57cec5SDimitry Andric   if (obj_file)
12370b57cec5SDimitry Andric     obj_file->SectionFileAddressesChanged();
12389dba64beSDimitry Andric   if (SymbolFile *symbols = GetSymbolFile())
12399dba64beSDimitry Andric     symbols->SectionFileAddressesChanged();
12400b57cec5SDimitry Andric }
12410b57cec5SDimitry Andric 
12420b57cec5SDimitry Andric UnwindTable &Module::GetUnwindTable() {
1243bdd1243dSDimitry Andric   if (!m_unwind_table) {
1244bdd1243dSDimitry Andric     if (!m_symfile_spec)
12455f757f3fSDimitry Andric       SymbolLocator::DownloadSymbolFileAsync(GetUUID());
1246*0fca6ea1SDimitry Andric     m_unwind_table.emplace(*this);
1247bdd1243dSDimitry Andric   }
12480b57cec5SDimitry Andric   return *m_unwind_table;
12490b57cec5SDimitry Andric }
12500b57cec5SDimitry Andric 
12510b57cec5SDimitry Andric SectionList *Module::GetUnifiedSectionList() {
12520b57cec5SDimitry Andric   if (!m_sections_up)
12539dba64beSDimitry Andric     m_sections_up = std::make_unique<SectionList>();
12540b57cec5SDimitry Andric   return m_sections_up.get();
12550b57cec5SDimitry Andric }
12560b57cec5SDimitry Andric 
12570b57cec5SDimitry Andric const Symbol *Module::FindFirstSymbolWithNameAndType(ConstString name,
12580b57cec5SDimitry Andric                                                      SymbolType symbol_type) {
1259e8d8bef9SDimitry Andric   LLDB_SCOPED_TIMERF(
1260e8d8bef9SDimitry Andric       "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",
12610b57cec5SDimitry Andric       name.AsCString(), symbol_type);
12629dba64beSDimitry Andric   if (Symtab *symtab = GetSymtab())
12630b57cec5SDimitry Andric     return symtab->FindFirstSymbolWithNameAndType(
12640b57cec5SDimitry Andric         name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);
12650b57cec5SDimitry Andric   return nullptr;
12660b57cec5SDimitry Andric }
12670b57cec5SDimitry Andric void Module::SymbolIndicesToSymbolContextList(
12680b57cec5SDimitry Andric     Symtab *symtab, std::vector<uint32_t> &symbol_indexes,
12690b57cec5SDimitry Andric     SymbolContextList &sc_list) {
12700b57cec5SDimitry Andric   // No need to protect this call using m_mutex all other method calls are
12710b57cec5SDimitry Andric   // already thread safe.
12720b57cec5SDimitry Andric 
12730b57cec5SDimitry Andric   size_t num_indices = symbol_indexes.size();
12740b57cec5SDimitry Andric   if (num_indices > 0) {
12750b57cec5SDimitry Andric     SymbolContext sc;
12760b57cec5SDimitry Andric     CalculateSymbolContext(&sc);
12770b57cec5SDimitry Andric     for (size_t i = 0; i < num_indices; i++) {
12780b57cec5SDimitry Andric       sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
12790b57cec5SDimitry Andric       if (sc.symbol)
12800b57cec5SDimitry Andric         sc_list.Append(sc);
12810b57cec5SDimitry Andric     }
12820b57cec5SDimitry Andric   }
12830b57cec5SDimitry Andric }
12840b57cec5SDimitry Andric 
12850eae32dcSDimitry Andric void Module::FindFunctionSymbols(ConstString name, uint32_t name_type_mask,
12860b57cec5SDimitry Andric                                  SymbolContextList &sc_list) {
1287e8d8bef9SDimitry Andric   LLDB_SCOPED_TIMERF("Module::FindSymbolsFunctions (name = %s, mask = 0x%8.8x)",
12880b57cec5SDimitry Andric                      name.AsCString(), name_type_mask);
12899dba64beSDimitry Andric   if (Symtab *symtab = GetSymtab())
12909dba64beSDimitry Andric     symtab->FindFunctionSymbols(name, name_type_mask, sc_list);
12910b57cec5SDimitry Andric }
12920b57cec5SDimitry Andric 
12939dba64beSDimitry Andric void Module::FindSymbolsWithNameAndType(ConstString name,
12940b57cec5SDimitry Andric                                         SymbolType symbol_type,
12950b57cec5SDimitry Andric                                         SymbolContextList &sc_list) {
12960b57cec5SDimitry Andric   // No need to protect this call using m_mutex all other method calls are
12970b57cec5SDimitry Andric   // already thread safe.
12989dba64beSDimitry Andric   if (Symtab *symtab = GetSymtab()) {
12990b57cec5SDimitry Andric     std::vector<uint32_t> symbol_indexes;
13000b57cec5SDimitry Andric     symtab->FindAllSymbolsWithNameAndType(name, symbol_type, symbol_indexes);
13010b57cec5SDimitry Andric     SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
13020b57cec5SDimitry Andric   }
13030b57cec5SDimitry Andric }
13040b57cec5SDimitry Andric 
1305bdd1243dSDimitry Andric void Module::FindSymbolsMatchingRegExAndType(
1306bdd1243dSDimitry Andric     const RegularExpression &regex, SymbolType symbol_type,
1307bdd1243dSDimitry Andric     SymbolContextList &sc_list, Mangled::NamePreference mangling_preference) {
13080b57cec5SDimitry Andric   // No need to protect this call using m_mutex all other method calls are
13090b57cec5SDimitry Andric   // already thread safe.
1310e8d8bef9SDimitry Andric   LLDB_SCOPED_TIMERF(
13110b57cec5SDimitry Andric       "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",
13120b57cec5SDimitry Andric       regex.GetText().str().c_str(), symbol_type);
13139dba64beSDimitry Andric   if (Symtab *symtab = GetSymtab()) {
13140b57cec5SDimitry Andric     std::vector<uint32_t> symbol_indexes;
13150b57cec5SDimitry Andric     symtab->FindAllSymbolsMatchingRexExAndType(
13160b57cec5SDimitry Andric         regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny,
1317bdd1243dSDimitry Andric         symbol_indexes, mangling_preference);
13180b57cec5SDimitry Andric     SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
13190b57cec5SDimitry Andric   }
13200b57cec5SDimitry Andric }
13210b57cec5SDimitry Andric 
13220b57cec5SDimitry Andric void Module::PreloadSymbols() {
13230b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
13249dba64beSDimitry Andric   SymbolFile *sym_file = GetSymbolFile();
13259dba64beSDimitry Andric   if (!sym_file)
13260b57cec5SDimitry Andric     return;
13279dba64beSDimitry Andric 
13284824e7fdSDimitry Andric   // Load the object file symbol table and any symbols from the SymbolFile that
13294824e7fdSDimitry Andric   // get appended using SymbolFile::AddSymbols(...).
13309dba64beSDimitry Andric   if (Symtab *symtab = sym_file->GetSymtab())
13310b57cec5SDimitry Andric     symtab->PreloadSymbols();
13324824e7fdSDimitry Andric 
13334824e7fdSDimitry Andric   // Now let the symbol file preload its data and the symbol table will be
13344824e7fdSDimitry Andric   // available without needing to take the module lock.
13354824e7fdSDimitry Andric   sym_file->PreloadSymbols();
13360b57cec5SDimitry Andric }
13370b57cec5SDimitry Andric 
13380b57cec5SDimitry Andric void Module::SetSymbolFileFileSpec(const FileSpec &file) {
13390b57cec5SDimitry Andric   if (!FileSystem::Instance().Exists(file))
13400b57cec5SDimitry Andric     return;
13410b57cec5SDimitry Andric   if (m_symfile_up) {
13420b57cec5SDimitry Andric     // Remove any sections in the unified section list that come from the
13430b57cec5SDimitry Andric     // current symbol vendor.
13440b57cec5SDimitry Andric     SectionList *section_list = GetSectionList();
13459dba64beSDimitry Andric     SymbolFile *symbol_file = GetSymbolFile();
13460b57cec5SDimitry Andric     if (section_list && symbol_file) {
13470b57cec5SDimitry Andric       ObjectFile *obj_file = symbol_file->GetObjectFile();
13480b57cec5SDimitry Andric       // Make sure we have an object file and that the symbol vendor's objfile
13490b57cec5SDimitry Andric       // isn't the same as the module's objfile before we remove any sections
13500b57cec5SDimitry Andric       // for it...
13510b57cec5SDimitry Andric       if (obj_file) {
13520b57cec5SDimitry Andric         // Check to make sure we aren't trying to specify the file we already
13530b57cec5SDimitry Andric         // have
13540b57cec5SDimitry Andric         if (obj_file->GetFileSpec() == file) {
13550b57cec5SDimitry Andric           // We are being told to add the exact same file that we already have
13560b57cec5SDimitry Andric           // we don't have to do anything.
13570b57cec5SDimitry Andric           return;
13580b57cec5SDimitry Andric         }
13590b57cec5SDimitry Andric 
13600b57cec5SDimitry Andric         // Cleare the current symtab as we are going to replace it with a new
13610b57cec5SDimitry Andric         // one
13620b57cec5SDimitry Andric         obj_file->ClearSymtab();
13630b57cec5SDimitry Andric 
13640b57cec5SDimitry Andric         // The symbol file might be a directory bundle ("/tmp/a.out.dSYM")
13650b57cec5SDimitry Andric         // instead of a full path to the symbol file within the bundle
13660b57cec5SDimitry Andric         // ("/tmp/a.out.dSYM/Contents/Resources/DWARF/a.out"). So we need to
13670b57cec5SDimitry Andric         // check this
13680b57cec5SDimitry Andric         if (FileSystem::Instance().IsDirectory(file)) {
13690b57cec5SDimitry Andric           std::string new_path(file.GetPath());
13700b57cec5SDimitry Andric           std::string old_path(obj_file->GetFileSpec().GetPath());
13715f757f3fSDimitry Andric           if (llvm::StringRef(old_path).starts_with(new_path)) {
13720b57cec5SDimitry Andric             // We specified the same bundle as the symbol file that we already
13730b57cec5SDimitry Andric             // have
13740b57cec5SDimitry Andric             return;
13750b57cec5SDimitry Andric           }
13760b57cec5SDimitry Andric         }
13770b57cec5SDimitry Andric 
13780b57cec5SDimitry Andric         if (obj_file != m_objfile_sp.get()) {
13790b57cec5SDimitry Andric           size_t num_sections = section_list->GetNumSections(0);
13800b57cec5SDimitry Andric           for (size_t idx = num_sections; idx > 0; --idx) {
13810b57cec5SDimitry Andric             lldb::SectionSP section_sp(
13820b57cec5SDimitry Andric                 section_list->GetSectionAtIndex(idx - 1));
13830b57cec5SDimitry Andric             if (section_sp->GetObjectFile() == obj_file) {
13840b57cec5SDimitry Andric               section_list->DeleteSection(idx - 1);
13850b57cec5SDimitry Andric             }
13860b57cec5SDimitry Andric           }
13870b57cec5SDimitry Andric         }
13880b57cec5SDimitry Andric       }
13890b57cec5SDimitry Andric     }
13900b57cec5SDimitry Andric     // Keep all old symbol files around in case there are any lingering type
13910b57cec5SDimitry Andric     // references in any SBValue objects that might have been handed out.
13920b57cec5SDimitry Andric     m_old_symfiles.push_back(std::move(m_symfile_up));
13930b57cec5SDimitry Andric   }
13940b57cec5SDimitry Andric   m_symfile_spec = file;
13950b57cec5SDimitry Andric   m_symfile_up.reset();
13969dba64beSDimitry Andric   m_did_load_symfile = false;
13970b57cec5SDimitry Andric }
13980b57cec5SDimitry Andric 
13990b57cec5SDimitry Andric bool Module::IsExecutable() {
14000b57cec5SDimitry Andric   if (GetObjectFile() == nullptr)
14010b57cec5SDimitry Andric     return false;
14020b57cec5SDimitry Andric   else
14030b57cec5SDimitry Andric     return GetObjectFile()->IsExecutable();
14040b57cec5SDimitry Andric }
14050b57cec5SDimitry Andric 
14060b57cec5SDimitry Andric bool Module::IsLoadedInTarget(Target *target) {
14070b57cec5SDimitry Andric   ObjectFile *obj_file = GetObjectFile();
14080b57cec5SDimitry Andric   if (obj_file) {
14090b57cec5SDimitry Andric     SectionList *sections = GetSectionList();
14100b57cec5SDimitry Andric     if (sections != nullptr) {
14110b57cec5SDimitry Andric       size_t num_sections = sections->GetSize();
14120b57cec5SDimitry Andric       for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++) {
14130b57cec5SDimitry Andric         SectionSP section_sp = sections->GetSectionAtIndex(sect_idx);
14140b57cec5SDimitry Andric         if (section_sp->GetLoadBaseAddress(target) != LLDB_INVALID_ADDRESS) {
14150b57cec5SDimitry Andric           return true;
14160b57cec5SDimitry Andric         }
14170b57cec5SDimitry Andric       }
14180b57cec5SDimitry Andric     }
14190b57cec5SDimitry Andric   }
14200b57cec5SDimitry Andric   return false;
14210b57cec5SDimitry Andric }
14220b57cec5SDimitry Andric 
14230b57cec5SDimitry Andric bool Module::LoadScriptingResourceInTarget(Target *target, Status &error,
142406c3fb27SDimitry Andric                                            Stream &feedback_stream) {
14250b57cec5SDimitry Andric   if (!target) {
14260b57cec5SDimitry Andric     error.SetErrorString("invalid destination Target");
14270b57cec5SDimitry Andric     return false;
14280b57cec5SDimitry Andric   }
14290b57cec5SDimitry Andric 
14300b57cec5SDimitry Andric   LoadScriptFromSymFile should_load =
14310b57cec5SDimitry Andric       target->TargetProperties::GetLoadScriptFromSymbolFile();
14320b57cec5SDimitry Andric 
14330b57cec5SDimitry Andric   if (should_load == eLoadScriptFromSymFileFalse)
14340b57cec5SDimitry Andric     return false;
14350b57cec5SDimitry Andric 
14360b57cec5SDimitry Andric   Debugger &debugger = target->GetDebugger();
14370b57cec5SDimitry Andric   const ScriptLanguage script_language = debugger.GetScriptLanguage();
14380b57cec5SDimitry Andric   if (script_language != eScriptLanguageNone) {
14390b57cec5SDimitry Andric 
14400b57cec5SDimitry Andric     PlatformSP platform_sp(target->GetPlatform());
14410b57cec5SDimitry Andric 
14420b57cec5SDimitry Andric     if (!platform_sp) {
14430b57cec5SDimitry Andric       error.SetErrorString("invalid Platform");
14440b57cec5SDimitry Andric       return false;
14450b57cec5SDimitry Andric     }
14460b57cec5SDimitry Andric 
14470b57cec5SDimitry Andric     FileSpecList file_specs = platform_sp->LocateExecutableScriptingResources(
14480b57cec5SDimitry Andric         target, *this, feedback_stream);
14490b57cec5SDimitry Andric 
14500b57cec5SDimitry Andric     const uint32_t num_specs = file_specs.GetSize();
14510b57cec5SDimitry Andric     if (num_specs) {
14520b57cec5SDimitry Andric       ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();
14530b57cec5SDimitry Andric       if (script_interpreter) {
14540b57cec5SDimitry Andric         for (uint32_t i = 0; i < num_specs; ++i) {
14550b57cec5SDimitry Andric           FileSpec scripting_fspec(file_specs.GetFileSpecAtIndex(i));
14560b57cec5SDimitry Andric           if (scripting_fspec &&
14570b57cec5SDimitry Andric               FileSystem::Instance().Exists(scripting_fspec)) {
14580b57cec5SDimitry Andric             if (should_load == eLoadScriptFromSymFileWarn) {
145906c3fb27SDimitry Andric               feedback_stream.Printf(
14600b57cec5SDimitry Andric                   "warning: '%s' contains a debug script. To run this script "
14610b57cec5SDimitry Andric                   "in "
14620b57cec5SDimitry Andric                   "this debug session:\n\n    command script import "
14630b57cec5SDimitry Andric                   "\"%s\"\n\n"
14640b57cec5SDimitry Andric                   "To run all discovered debug scripts in this session:\n\n"
14650b57cec5SDimitry Andric                   "    settings set target.load-script-from-symbol-file "
14660b57cec5SDimitry Andric                   "true\n",
14670b57cec5SDimitry Andric                   GetFileSpec().GetFileNameStrippingExtension().GetCString(),
14680b57cec5SDimitry Andric                   scripting_fspec.GetPath().c_str());
14690b57cec5SDimitry Andric               return false;
14700b57cec5SDimitry Andric             }
14710b57cec5SDimitry Andric             StreamString scripting_stream;
1472480093f4SDimitry Andric             scripting_fspec.Dump(scripting_stream.AsRawOstream());
1473fe6060f1SDimitry Andric             LoadScriptOptions options;
14740b57cec5SDimitry Andric             bool did_load = script_interpreter->LoadScriptingModule(
1475fe6060f1SDimitry Andric                 scripting_stream.GetData(), options, error);
14760b57cec5SDimitry Andric             if (!did_load)
14770b57cec5SDimitry Andric               return false;
14780b57cec5SDimitry Andric           }
14790b57cec5SDimitry Andric         }
14800b57cec5SDimitry Andric       } else {
14810b57cec5SDimitry Andric         error.SetErrorString("invalid ScriptInterpreter");
14820b57cec5SDimitry Andric         return false;
14830b57cec5SDimitry Andric       }
14840b57cec5SDimitry Andric     }
14850b57cec5SDimitry Andric   }
14860b57cec5SDimitry Andric   return true;
14870b57cec5SDimitry Andric }
14880b57cec5SDimitry Andric 
14890b57cec5SDimitry Andric bool Module::SetArchitecture(const ArchSpec &new_arch) {
14900b57cec5SDimitry Andric   if (!m_arch.IsValid()) {
14910b57cec5SDimitry Andric     m_arch = new_arch;
14920b57cec5SDimitry Andric     return true;
14930b57cec5SDimitry Andric   }
14940b57cec5SDimitry Andric   return m_arch.IsCompatibleMatch(new_arch);
14950b57cec5SDimitry Andric }
14960b57cec5SDimitry Andric 
14970b57cec5SDimitry Andric bool Module::SetLoadAddress(Target &target, lldb::addr_t value,
14980b57cec5SDimitry Andric                             bool value_is_offset, bool &changed) {
14990b57cec5SDimitry Andric   ObjectFile *object_file = GetObjectFile();
15000b57cec5SDimitry Andric   if (object_file != nullptr) {
15010b57cec5SDimitry Andric     changed = object_file->SetLoadAddress(target, value, value_is_offset);
15020b57cec5SDimitry Andric     return true;
15030b57cec5SDimitry Andric   } else {
15040b57cec5SDimitry Andric     changed = false;
15050b57cec5SDimitry Andric   }
15060b57cec5SDimitry Andric   return false;
15070b57cec5SDimitry Andric }
15080b57cec5SDimitry Andric 
15090b57cec5SDimitry Andric bool Module::MatchesModuleSpec(const ModuleSpec &module_ref) {
15100b57cec5SDimitry Andric   const UUID &uuid = module_ref.GetUUID();
15110b57cec5SDimitry Andric 
15120b57cec5SDimitry Andric   if (uuid.IsValid()) {
15130b57cec5SDimitry Andric     // If the UUID matches, then nothing more needs to match...
15140b57cec5SDimitry Andric     return (uuid == GetUUID());
15150b57cec5SDimitry Andric   }
15160b57cec5SDimitry Andric 
15170b57cec5SDimitry Andric   const FileSpec &file_spec = module_ref.GetFileSpec();
1518480093f4SDimitry Andric   if (!FileSpec::Match(file_spec, m_file) &&
1519480093f4SDimitry Andric       !FileSpec::Match(file_spec, m_platform_file))
15200b57cec5SDimitry Andric     return false;
15210b57cec5SDimitry Andric 
15220b57cec5SDimitry Andric   const FileSpec &platform_file_spec = module_ref.GetPlatformFileSpec();
1523480093f4SDimitry Andric   if (!FileSpec::Match(platform_file_spec, GetPlatformFileSpec()))
15240b57cec5SDimitry Andric     return false;
15250b57cec5SDimitry Andric 
15260b57cec5SDimitry Andric   const ArchSpec &arch = module_ref.GetArchitecture();
15270b57cec5SDimitry Andric   if (arch.IsValid()) {
15280b57cec5SDimitry Andric     if (!m_arch.IsCompatibleMatch(arch))
15290b57cec5SDimitry Andric       return false;
15300b57cec5SDimitry Andric   }
15310b57cec5SDimitry Andric 
15320b57cec5SDimitry Andric   ConstString object_name = module_ref.GetObjectName();
15330b57cec5SDimitry Andric   if (object_name) {
15340b57cec5SDimitry Andric     if (object_name != GetObjectName())
15350b57cec5SDimitry Andric       return false;
15360b57cec5SDimitry Andric   }
15370b57cec5SDimitry Andric   return true;
15380b57cec5SDimitry Andric }
15390b57cec5SDimitry Andric 
15400b57cec5SDimitry Andric bool Module::FindSourceFile(const FileSpec &orig_spec,
15410b57cec5SDimitry Andric                             FileSpec &new_spec) const {
15420b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
1543fe6060f1SDimitry Andric   if (auto remapped = m_source_mappings.FindFile(orig_spec)) {
1544fe6060f1SDimitry Andric     new_spec = *remapped;
1545fe6060f1SDimitry Andric     return true;
1546fe6060f1SDimitry Andric   }
1547fe6060f1SDimitry Andric   return false;
15480b57cec5SDimitry Andric }
15490b57cec5SDimitry Andric 
1550bdd1243dSDimitry Andric std::optional<std::string> Module::RemapSourceFile(llvm::StringRef path) const {
15510b57cec5SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(m_mutex);
1552fe6060f1SDimitry Andric   if (auto remapped = m_source_mappings.RemapPath(path))
1553fe6060f1SDimitry Andric     return remapped->GetPath();
1554fe6060f1SDimitry Andric   return {};
15550b57cec5SDimitry Andric }
15560b57cec5SDimitry Andric 
15570eae32dcSDimitry Andric void Module::RegisterXcodeSDK(llvm::StringRef sdk_name,
15580eae32dcSDimitry Andric                               llvm::StringRef sysroot) {
155906c3fb27SDimitry Andric   auto sdk_path_or_err =
156006c3fb27SDimitry Andric       HostInfo::GetSDKRoot(HostInfo::SDKOptions{sdk_name.str()});
1561bdd1243dSDimitry Andric 
1562bdd1243dSDimitry Andric   if (!sdk_path_or_err) {
1563bdd1243dSDimitry Andric     Debugger::ReportError("Error while searching for Xcode SDK: " +
1564bdd1243dSDimitry Andric                           toString(sdk_path_or_err.takeError()));
1565bdd1243dSDimitry Andric     return;
1566bdd1243dSDimitry Andric   }
1567bdd1243dSDimitry Andric 
1568bdd1243dSDimitry Andric   auto sdk_path = *sdk_path_or_err;
1569349cc55cSDimitry Andric   if (sdk_path.empty())
15705ffd83dbSDimitry Andric     return;
15715ffd83dbSDimitry Andric   // If the SDK changed for a previously registered source path, update it.
15725ffd83dbSDimitry Andric   // This could happend with -fdebug-prefix-map, otherwise it's unlikely.
1573349cc55cSDimitry Andric   if (!m_source_mappings.Replace(sysroot, sdk_path, true))
15745ffd83dbSDimitry Andric     // In the general case, however, append it to the list.
1575349cc55cSDimitry Andric     m_source_mappings.Append(sysroot, sdk_path, false);
15765ffd83dbSDimitry Andric }
15775ffd83dbSDimitry Andric 
15789dba64beSDimitry Andric bool Module::MergeArchitecture(const ArchSpec &arch_spec) {
15799dba64beSDimitry Andric   if (!arch_spec.IsValid())
15809dba64beSDimitry Andric     return false;
158181ad6265SDimitry Andric   LLDB_LOGF(GetLog(LLDBLog::Object | LLDBLog::Modules),
15829dba64beSDimitry Andric             "module has arch %s, merging/replacing with arch %s",
15839dba64beSDimitry Andric             m_arch.GetTriple().getTriple().c_str(),
15849dba64beSDimitry Andric             arch_spec.GetTriple().getTriple().c_str());
15859dba64beSDimitry Andric   if (!m_arch.IsCompatibleMatch(arch_spec)) {
15869dba64beSDimitry Andric     // The new architecture is different, we just need to replace it.
15879dba64beSDimitry Andric     return SetArchitecture(arch_spec);
15889dba64beSDimitry Andric   }
15899dba64beSDimitry Andric 
15909dba64beSDimitry Andric   // Merge bits from arch_spec into "merged_arch" and set our architecture.
15919dba64beSDimitry Andric   ArchSpec merged_arch(m_arch);
15929dba64beSDimitry Andric   merged_arch.MergeFrom(arch_spec);
15939dba64beSDimitry Andric   // SetArchitecture() is a no-op if m_arch is already valid.
15949dba64beSDimitry Andric   m_arch = ArchSpec();
15959dba64beSDimitry Andric   return SetArchitecture(merged_arch);
15969dba64beSDimitry Andric }
15979dba64beSDimitry Andric 
15980b57cec5SDimitry Andric llvm::VersionTuple Module::GetVersion() {
15990b57cec5SDimitry Andric   if (ObjectFile *obj_file = GetObjectFile())
16000b57cec5SDimitry Andric     return obj_file->GetVersion();
16010b57cec5SDimitry Andric   return llvm::VersionTuple();
16020b57cec5SDimitry Andric }
16030b57cec5SDimitry Andric 
16040b57cec5SDimitry Andric bool Module::GetIsDynamicLinkEditor() {
16050b57cec5SDimitry Andric   ObjectFile *obj_file = GetObjectFile();
16060b57cec5SDimitry Andric 
16070b57cec5SDimitry Andric   if (obj_file)
16080b57cec5SDimitry Andric     return obj_file->GetIsDynamicLinkEditor();
16090b57cec5SDimitry Andric 
16100b57cec5SDimitry Andric   return false;
16110b57cec5SDimitry Andric }
16120eae32dcSDimitry Andric 
16130eae32dcSDimitry Andric uint32_t Module::Hash() {
16140eae32dcSDimitry Andric   std::string identifier;
16150eae32dcSDimitry Andric   llvm::raw_string_ostream id_strm(identifier);
16160eae32dcSDimitry Andric   id_strm << m_arch.GetTriple().str() << '-' << m_file.GetPath();
16170eae32dcSDimitry Andric   if (m_object_name)
161806c3fb27SDimitry Andric     id_strm << '(' << m_object_name << ')';
16190eae32dcSDimitry Andric   if (m_object_offset > 0)
16200eae32dcSDimitry Andric     id_strm << m_object_offset;
16210eae32dcSDimitry Andric   const auto mtime = llvm::sys::toTimeT(m_object_mod_time);
16220eae32dcSDimitry Andric   if (mtime > 0)
16230eae32dcSDimitry Andric     id_strm << mtime;
16240eae32dcSDimitry Andric   return llvm::djbHash(id_strm.str());
16250eae32dcSDimitry Andric }
16260eae32dcSDimitry Andric 
16270eae32dcSDimitry Andric std::string Module::GetCacheKey() {
16280eae32dcSDimitry Andric   std::string key;
16290eae32dcSDimitry Andric   llvm::raw_string_ostream strm(key);
16300eae32dcSDimitry Andric   strm << m_arch.GetTriple().str() << '-' << m_file.GetFilename();
16310eae32dcSDimitry Andric   if (m_object_name)
163206c3fb27SDimitry Andric     strm << '(' << m_object_name << ')';
16330eae32dcSDimitry Andric   strm << '-' << llvm::format_hex(Hash(), 10);
16340eae32dcSDimitry Andric   return strm.str();
16350eae32dcSDimitry Andric }
16360eae32dcSDimitry Andric 
16370eae32dcSDimitry Andric DataFileCache *Module::GetIndexCache() {
16380eae32dcSDimitry Andric   if (!ModuleList::GetGlobalModuleListProperties().GetEnableLLDBIndexCache())
16390eae32dcSDimitry Andric     return nullptr;
16400eae32dcSDimitry Andric   // NOTE: intentional leak so we don't crash if global destructor chain gets
16410eae32dcSDimitry Andric   // called as other threads still use the result of this function
164281ad6265SDimitry Andric   static DataFileCache *g_data_file_cache =
164381ad6265SDimitry Andric       new DataFileCache(ModuleList::GetGlobalModuleListProperties()
164481ad6265SDimitry Andric                             .GetLLDBIndexCachePath()
164581ad6265SDimitry Andric                             .GetPath());
16460eae32dcSDimitry Andric   return g_data_file_cache;
16470eae32dcSDimitry Andric }
1648