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 ®ex, 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 ®ex, 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 ®ex, 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