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"
130b57cec5SDimitry Andric #include "lldb/Core/Debugger.h"
140b57cec5SDimitry Andric #include "lldb/Core/FileSpecList.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"
300b57cec5SDimitry Andric #include "lldb/Symbol/SymbolVendor.h"
310b57cec5SDimitry Andric #include "lldb/Symbol/Symtab.h"
320b57cec5SDimitry Andric #include "lldb/Symbol/Type.h"
330b57cec5SDimitry Andric #include "lldb/Symbol/TypeList.h"
340b57cec5SDimitry Andric #include "lldb/Symbol/TypeMap.h"
350b57cec5SDimitry Andric #include "lldb/Symbol/TypeSystem.h"
360b57cec5SDimitry Andric #include "lldb/Target/Language.h"
370b57cec5SDimitry Andric #include "lldb/Target/Process.h"
380b57cec5SDimitry Andric #include "lldb/Target/Target.h"
390b57cec5SDimitry Andric #include "lldb/Utility/DataBufferHeap.h"
400b57cec5SDimitry Andric #include "lldb/Utility/LLDBAssert.h"
410b57cec5SDimitry Andric #include "lldb/Utility/Log.h"
420b57cec5SDimitry Andric #include "lldb/Utility/Logging.h"
430b57cec5SDimitry Andric #include "lldb/Utility/RegularExpression.h"
440b57cec5SDimitry Andric #include "lldb/Utility/Status.h"
450b57cec5SDimitry Andric #include "lldb/Utility/Stream.h"
460b57cec5SDimitry Andric #include "lldb/Utility/StreamString.h"
470b57cec5SDimitry Andric #include "lldb/Utility/Timer.h"
480b57cec5SDimitry Andric
490b57cec5SDimitry Andric #if defined(_WIN32)
500b57cec5SDimitry Andric #include "lldb/Host/windows/PosixApi.h"
510b57cec5SDimitry Andric #endif
520b57cec5SDimitry Andric
530b57cec5SDimitry Andric #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
540b57cec5SDimitry Andric #include "Plugins/Language/ObjC/ObjCLanguage.h"
550b57cec5SDimitry Andric
560b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
570b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
580b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
590b57cec5SDimitry Andric #include "llvm/Support/Signals.h"
600b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
610b57cec5SDimitry Andric
62*5f7ddb14SDimitry Andric #include <cassert>
63*5f7ddb14SDimitry Andric #include <cinttypes>
64*5f7ddb14SDimitry Andric #include <cstdarg>
650b57cec5SDimitry Andric #include <cstdint>
66*5f7ddb14SDimitry Andric #include <cstring>
670b57cec5SDimitry Andric #include <map>
680b57cec5SDimitry Andric #include <type_traits>
690b57cec5SDimitry Andric #include <utility>
700b57cec5SDimitry Andric
710b57cec5SDimitry Andric namespace lldb_private {
720b57cec5SDimitry Andric class CompilerDeclContext;
730b57cec5SDimitry Andric }
740b57cec5SDimitry Andric namespace lldb_private {
750b57cec5SDimitry Andric class VariableList;
760b57cec5SDimitry Andric }
770b57cec5SDimitry Andric
780b57cec5SDimitry Andric using namespace lldb;
790b57cec5SDimitry Andric using namespace lldb_private;
800b57cec5SDimitry Andric
810b57cec5SDimitry Andric // Shared pointers to modules track module lifetimes in targets and in the
820b57cec5SDimitry Andric // global module, but this collection will track all module objects that are
830b57cec5SDimitry Andric // still alive
840b57cec5SDimitry Andric typedef std::vector<Module *> ModuleCollection;
850b57cec5SDimitry Andric
GetModuleCollection()860b57cec5SDimitry Andric static ModuleCollection &GetModuleCollection() {
870b57cec5SDimitry Andric // This module collection needs to live past any module, so we could either
880b57cec5SDimitry Andric // make it a shared pointer in each module or just leak is. Since it is only
890b57cec5SDimitry Andric // an empty vector by the time all the modules have gone away, we just leak
900b57cec5SDimitry Andric // it for now. If we decide this is a big problem we can introduce a
910b57cec5SDimitry Andric // Finalize method that will tear everything down in a predictable order.
920b57cec5SDimitry Andric
930b57cec5SDimitry Andric static ModuleCollection *g_module_collection = nullptr;
940b57cec5SDimitry Andric if (g_module_collection == nullptr)
950b57cec5SDimitry Andric g_module_collection = new ModuleCollection();
960b57cec5SDimitry Andric
970b57cec5SDimitry Andric return *g_module_collection;
980b57cec5SDimitry Andric }
990b57cec5SDimitry Andric
GetAllocationModuleCollectionMutex()1000b57cec5SDimitry Andric std::recursive_mutex &Module::GetAllocationModuleCollectionMutex() {
1010b57cec5SDimitry Andric // NOTE: The mutex below must be leaked since the global module list in
1020b57cec5SDimitry Andric // the ModuleList class will get torn at some point, and we can't know if it
1030b57cec5SDimitry Andric // will tear itself down before the "g_module_collection_mutex" below will.
1040b57cec5SDimitry Andric // So we leak a Mutex object below to safeguard against that
1050b57cec5SDimitry Andric
1060b57cec5SDimitry Andric static std::recursive_mutex *g_module_collection_mutex = nullptr;
1070b57cec5SDimitry Andric if (g_module_collection_mutex == nullptr)
1080b57cec5SDimitry Andric g_module_collection_mutex = new std::recursive_mutex; // NOTE: known leak
1090b57cec5SDimitry Andric return *g_module_collection_mutex;
1100b57cec5SDimitry Andric }
1110b57cec5SDimitry Andric
GetNumberAllocatedModules()1120b57cec5SDimitry Andric size_t Module::GetNumberAllocatedModules() {
1130b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
1140b57cec5SDimitry Andric GetAllocationModuleCollectionMutex());
1150b57cec5SDimitry Andric return GetModuleCollection().size();
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric
GetAllocatedModuleAtIndex(size_t idx)1180b57cec5SDimitry Andric Module *Module::GetAllocatedModuleAtIndex(size_t idx) {
1190b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
1200b57cec5SDimitry Andric GetAllocationModuleCollectionMutex());
1210b57cec5SDimitry Andric ModuleCollection &modules = GetModuleCollection();
1220b57cec5SDimitry Andric if (idx < modules.size())
1230b57cec5SDimitry Andric return modules[idx];
1240b57cec5SDimitry Andric return nullptr;
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric
Module(const ModuleSpec & module_spec)1270b57cec5SDimitry Andric Module::Module(const ModuleSpec &module_spec)
1280b57cec5SDimitry Andric : m_object_offset(0), m_file_has_changed(false),
1290b57cec5SDimitry Andric m_first_file_changed_log(false) {
1300b57cec5SDimitry Andric // Scope for locker below...
1310b57cec5SDimitry Andric {
1320b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
1330b57cec5SDimitry Andric GetAllocationModuleCollectionMutex());
1340b57cec5SDimitry Andric GetModuleCollection().push_back(this);
1350b57cec5SDimitry Andric }
1360b57cec5SDimitry Andric
1370b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT |
1380b57cec5SDimitry Andric LIBLLDB_LOG_MODULES));
1390b57cec5SDimitry Andric if (log != nullptr)
1409dba64beSDimitry Andric LLDB_LOGF(log, "%p Module::Module((%s) '%s%s%s%s')",
1419dba64beSDimitry Andric static_cast<void *>(this),
1420b57cec5SDimitry Andric module_spec.GetArchitecture().GetArchitectureName(),
1430b57cec5SDimitry Andric module_spec.GetFileSpec().GetPath().c_str(),
1440b57cec5SDimitry Andric module_spec.GetObjectName().IsEmpty() ? "" : "(",
1450b57cec5SDimitry Andric module_spec.GetObjectName().IsEmpty()
1460b57cec5SDimitry Andric ? ""
1470b57cec5SDimitry Andric : module_spec.GetObjectName().AsCString(""),
1480b57cec5SDimitry Andric module_spec.GetObjectName().IsEmpty() ? "" : ")");
1490b57cec5SDimitry Andric
1505ffd83dbSDimitry Andric auto data_sp = module_spec.GetData();
1515ffd83dbSDimitry Andric lldb::offset_t file_size = 0;
1525ffd83dbSDimitry Andric if (data_sp)
1535ffd83dbSDimitry Andric file_size = data_sp->GetByteSize();
1545ffd83dbSDimitry Andric
1550b57cec5SDimitry Andric // First extract all module specifications from the file using the local file
1560b57cec5SDimitry Andric // path. If there are no specifications, then don't fill anything in
1570b57cec5SDimitry Andric ModuleSpecList modules_specs;
1585ffd83dbSDimitry Andric if (ObjectFile::GetModuleSpecifications(
1595ffd83dbSDimitry Andric module_spec.GetFileSpec(), 0, file_size, modules_specs, data_sp) == 0)
1600b57cec5SDimitry Andric return;
1610b57cec5SDimitry Andric
1620b57cec5SDimitry Andric // Now make sure that one of the module specifications matches what we just
1630b57cec5SDimitry Andric // extract. We might have a module specification that specifies a file
1640b57cec5SDimitry Andric // "/usr/lib/dyld" with UUID XXX, but we might have a local version of
1650b57cec5SDimitry Andric // "/usr/lib/dyld" that has
1660b57cec5SDimitry Andric // UUID YYY and we don't want those to match. If they don't match, just don't
1670b57cec5SDimitry Andric // fill any ivars in so we don't accidentally grab the wrong file later since
1680b57cec5SDimitry Andric // they don't match...
1690b57cec5SDimitry Andric ModuleSpec matching_module_spec;
1700b57cec5SDimitry Andric if (!modules_specs.FindMatchingModuleSpec(module_spec,
1710b57cec5SDimitry Andric matching_module_spec)) {
1720b57cec5SDimitry Andric if (log) {
1739dba64beSDimitry Andric LLDB_LOGF(log, "Found local object file but the specs didn't match");
1740b57cec5SDimitry Andric }
1750b57cec5SDimitry Andric return;
1760b57cec5SDimitry Andric }
1770b57cec5SDimitry Andric
1785ffd83dbSDimitry Andric // Set m_data_sp if it was initially provided in the ModuleSpec. Note that
1795ffd83dbSDimitry Andric // we cannot use the data_sp variable here, because it will have been
1805ffd83dbSDimitry Andric // modified by GetModuleSpecifications().
1815ffd83dbSDimitry Andric if (auto module_spec_data_sp = module_spec.GetData()) {
1825ffd83dbSDimitry Andric m_data_sp = module_spec_data_sp;
1835ffd83dbSDimitry Andric m_mod_time = {};
1845ffd83dbSDimitry Andric } else {
1850b57cec5SDimitry Andric if (module_spec.GetFileSpec())
1860b57cec5SDimitry Andric m_mod_time =
1875ffd83dbSDimitry Andric FileSystem::Instance().GetModificationTime(module_spec.GetFileSpec());
1885ffd83dbSDimitry Andric else if (matching_module_spec.GetFileSpec())
1895ffd83dbSDimitry Andric m_mod_time = FileSystem::Instance().GetModificationTime(
1905ffd83dbSDimitry Andric matching_module_spec.GetFileSpec());
1915ffd83dbSDimitry Andric }
1920b57cec5SDimitry Andric
1930b57cec5SDimitry Andric // Copy the architecture from the actual spec if we got one back, else use
1940b57cec5SDimitry Andric // the one that was specified
1950b57cec5SDimitry Andric if (matching_module_spec.GetArchitecture().IsValid())
1960b57cec5SDimitry Andric m_arch = matching_module_spec.GetArchitecture();
1970b57cec5SDimitry Andric else if (module_spec.GetArchitecture().IsValid())
1980b57cec5SDimitry Andric m_arch = module_spec.GetArchitecture();
1990b57cec5SDimitry Andric
2000b57cec5SDimitry Andric // Copy the file spec over and use the specified one (if there was one) so we
2010b57cec5SDimitry Andric // don't use a path that might have gotten resolved a path in
2020b57cec5SDimitry Andric // 'matching_module_spec'
2030b57cec5SDimitry Andric if (module_spec.GetFileSpec())
2040b57cec5SDimitry Andric m_file = module_spec.GetFileSpec();
2050b57cec5SDimitry Andric else if (matching_module_spec.GetFileSpec())
2060b57cec5SDimitry Andric m_file = matching_module_spec.GetFileSpec();
2070b57cec5SDimitry Andric
2080b57cec5SDimitry Andric // Copy the platform file spec over
2090b57cec5SDimitry Andric if (module_spec.GetPlatformFileSpec())
2100b57cec5SDimitry Andric m_platform_file = module_spec.GetPlatformFileSpec();
2110b57cec5SDimitry Andric else if (matching_module_spec.GetPlatformFileSpec())
2120b57cec5SDimitry Andric m_platform_file = matching_module_spec.GetPlatformFileSpec();
2130b57cec5SDimitry Andric
2140b57cec5SDimitry Andric // Copy the symbol file spec over
2150b57cec5SDimitry Andric if (module_spec.GetSymbolFileSpec())
2160b57cec5SDimitry Andric m_symfile_spec = module_spec.GetSymbolFileSpec();
2170b57cec5SDimitry Andric else if (matching_module_spec.GetSymbolFileSpec())
2180b57cec5SDimitry Andric m_symfile_spec = matching_module_spec.GetSymbolFileSpec();
2190b57cec5SDimitry Andric
2200b57cec5SDimitry Andric // Copy the object name over
2210b57cec5SDimitry Andric if (matching_module_spec.GetObjectName())
2220b57cec5SDimitry Andric m_object_name = matching_module_spec.GetObjectName();
2230b57cec5SDimitry Andric else
2240b57cec5SDimitry Andric m_object_name = module_spec.GetObjectName();
2250b57cec5SDimitry Andric
2260b57cec5SDimitry Andric // Always trust the object offset (file offset) and object modification time
2270b57cec5SDimitry Andric // (for mod time in a BSD static archive) of from the matching module
2280b57cec5SDimitry Andric // specification
2290b57cec5SDimitry Andric m_object_offset = matching_module_spec.GetObjectOffset();
2300b57cec5SDimitry Andric m_object_mod_time = matching_module_spec.GetObjectModificationTime();
2310b57cec5SDimitry Andric }
2320b57cec5SDimitry Andric
Module(const FileSpec & file_spec,const ArchSpec & arch,const ConstString * object_name,lldb::offset_t object_offset,const llvm::sys::TimePoint<> & object_mod_time)2330b57cec5SDimitry Andric Module::Module(const FileSpec &file_spec, const ArchSpec &arch,
2340b57cec5SDimitry Andric const ConstString *object_name, lldb::offset_t object_offset,
2350b57cec5SDimitry Andric const llvm::sys::TimePoint<> &object_mod_time)
2360b57cec5SDimitry Andric : m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)), m_arch(arch),
2370b57cec5SDimitry Andric m_file(file_spec), m_object_offset(object_offset),
2380b57cec5SDimitry Andric m_object_mod_time(object_mod_time), m_file_has_changed(false),
2390b57cec5SDimitry Andric m_first_file_changed_log(false) {
2400b57cec5SDimitry Andric // Scope for locker below...
2410b57cec5SDimitry Andric {
2420b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
2430b57cec5SDimitry Andric GetAllocationModuleCollectionMutex());
2440b57cec5SDimitry Andric GetModuleCollection().push_back(this);
2450b57cec5SDimitry Andric }
2460b57cec5SDimitry Andric
2470b57cec5SDimitry Andric if (object_name)
2480b57cec5SDimitry Andric m_object_name = *object_name;
2490b57cec5SDimitry Andric
2500b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT |
2510b57cec5SDimitry Andric LIBLLDB_LOG_MODULES));
2520b57cec5SDimitry Andric if (log != nullptr)
2539dba64beSDimitry Andric LLDB_LOGF(log, "%p Module::Module((%s) '%s%s%s%s')",
2549dba64beSDimitry Andric static_cast<void *>(this), m_arch.GetArchitectureName(),
2559dba64beSDimitry Andric m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",
2560b57cec5SDimitry Andric m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
2570b57cec5SDimitry Andric m_object_name.IsEmpty() ? "" : ")");
2580b57cec5SDimitry Andric }
2590b57cec5SDimitry Andric
Module()260*5f7ddb14SDimitry Andric Module::Module() : m_file_has_changed(false), m_first_file_changed_log(false) {
2610b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
2620b57cec5SDimitry Andric GetAllocationModuleCollectionMutex());
2630b57cec5SDimitry Andric GetModuleCollection().push_back(this);
2640b57cec5SDimitry Andric }
2650b57cec5SDimitry Andric
~Module()2660b57cec5SDimitry Andric Module::~Module() {
2670b57cec5SDimitry Andric // Lock our module down while we tear everything down to make sure we don't
2680b57cec5SDimitry Andric // get any access to the module while it is being destroyed
2690b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_mutex);
2700b57cec5SDimitry Andric // Scope for locker below...
2710b57cec5SDimitry Andric {
2720b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
2730b57cec5SDimitry Andric GetAllocationModuleCollectionMutex());
2740b57cec5SDimitry Andric ModuleCollection &modules = GetModuleCollection();
2750b57cec5SDimitry Andric ModuleCollection::iterator end = modules.end();
2760b57cec5SDimitry Andric ModuleCollection::iterator pos = std::find(modules.begin(), end, this);
2770b57cec5SDimitry Andric assert(pos != end);
2780b57cec5SDimitry Andric modules.erase(pos);
2790b57cec5SDimitry Andric }
2800b57cec5SDimitry Andric Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT |
2810b57cec5SDimitry Andric LIBLLDB_LOG_MODULES));
2820b57cec5SDimitry Andric if (log != nullptr)
2839dba64beSDimitry Andric LLDB_LOGF(log, "%p Module::~Module((%s) '%s%s%s%s')",
2840b57cec5SDimitry Andric static_cast<void *>(this), m_arch.GetArchitectureName(),
2850b57cec5SDimitry Andric m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",
2860b57cec5SDimitry Andric m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
2870b57cec5SDimitry Andric m_object_name.IsEmpty() ? "" : ")");
2880b57cec5SDimitry Andric // Release any auto pointers before we start tearing down our member
2890b57cec5SDimitry Andric // variables since the object file and symbol files might need to make
2900b57cec5SDimitry Andric // function calls back into this module object. The ordering is important
2910b57cec5SDimitry Andric // here because symbol files can require the module object file. So we tear
2920b57cec5SDimitry Andric // down the symbol file first, then the object file.
2930b57cec5SDimitry Andric m_sections_up.reset();
2940b57cec5SDimitry Andric m_symfile_up.reset();
2950b57cec5SDimitry Andric m_objfile_sp.reset();
2960b57cec5SDimitry Andric }
2970b57cec5SDimitry Andric
GetMemoryObjectFile(const lldb::ProcessSP & process_sp,lldb::addr_t header_addr,Status & error,size_t size_to_read)2980b57cec5SDimitry Andric ObjectFile *Module::GetMemoryObjectFile(const lldb::ProcessSP &process_sp,
2990b57cec5SDimitry Andric lldb::addr_t header_addr, Status &error,
3000b57cec5SDimitry Andric size_t size_to_read) {
3010b57cec5SDimitry Andric if (m_objfile_sp) {
3020b57cec5SDimitry Andric error.SetErrorString("object file already exists");
3030b57cec5SDimitry Andric } else {
3040b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_mutex);
3050b57cec5SDimitry Andric if (process_sp) {
3060b57cec5SDimitry Andric m_did_load_objfile = true;
3079dba64beSDimitry Andric auto data_up = std::make_unique<DataBufferHeap>(size_to_read, 0);
3080b57cec5SDimitry Andric Status readmem_error;
3090b57cec5SDimitry Andric const size_t bytes_read =
3100b57cec5SDimitry Andric process_sp->ReadMemory(header_addr, data_up->GetBytes(),
3110b57cec5SDimitry Andric data_up->GetByteSize(), readmem_error);
3125ffd83dbSDimitry Andric if (bytes_read < size_to_read)
3135ffd83dbSDimitry Andric data_up->SetByteSize(bytes_read);
3145ffd83dbSDimitry Andric if (data_up->GetByteSize() > 0) {
3150b57cec5SDimitry Andric DataBufferSP data_sp(data_up.release());
3160b57cec5SDimitry Andric m_objfile_sp = ObjectFile::FindPlugin(shared_from_this(), process_sp,
3170b57cec5SDimitry Andric header_addr, data_sp);
3180b57cec5SDimitry Andric if (m_objfile_sp) {
3190b57cec5SDimitry Andric StreamString s;
3200b57cec5SDimitry Andric s.Printf("0x%16.16" PRIx64, header_addr);
3210b57cec5SDimitry Andric m_object_name.SetString(s.GetString());
3220b57cec5SDimitry Andric
3230b57cec5SDimitry Andric // Once we get the object file, update our module with the object
3240b57cec5SDimitry Andric // file's architecture since it might differ in vendor/os if some
3250b57cec5SDimitry Andric // parts were unknown.
3260b57cec5SDimitry Andric m_arch = m_objfile_sp->GetArchitecture();
3270b57cec5SDimitry Andric
3280b57cec5SDimitry Andric // Augment the arch with the target's information in case
3290b57cec5SDimitry Andric // we are unable to extract the os/environment from memory.
3300b57cec5SDimitry Andric m_arch.MergeFrom(process_sp->GetTarget().GetArchitecture());
3310b57cec5SDimitry Andric } else {
3320b57cec5SDimitry Andric error.SetErrorString("unable to find suitable object file plug-in");
3330b57cec5SDimitry Andric }
3340b57cec5SDimitry Andric } else {
3350b57cec5SDimitry Andric error.SetErrorStringWithFormat("unable to read header from memory: %s",
3360b57cec5SDimitry Andric readmem_error.AsCString());
3370b57cec5SDimitry Andric }
3380b57cec5SDimitry Andric } else {
3390b57cec5SDimitry Andric error.SetErrorString("invalid process");
3400b57cec5SDimitry Andric }
3410b57cec5SDimitry Andric }
3420b57cec5SDimitry Andric return m_objfile_sp.get();
3430b57cec5SDimitry Andric }
3440b57cec5SDimitry Andric
GetUUID()3450b57cec5SDimitry Andric const lldb_private::UUID &Module::GetUUID() {
3460b57cec5SDimitry Andric if (!m_did_set_uuid.load()) {
3470b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_mutex);
3480b57cec5SDimitry Andric if (!m_did_set_uuid.load()) {
3490b57cec5SDimitry Andric ObjectFile *obj_file = GetObjectFile();
3500b57cec5SDimitry Andric
3510b57cec5SDimitry Andric if (obj_file != nullptr) {
3520b57cec5SDimitry Andric m_uuid = obj_file->GetUUID();
3530b57cec5SDimitry Andric m_did_set_uuid = true;
3540b57cec5SDimitry Andric }
3550b57cec5SDimitry Andric }
3560b57cec5SDimitry Andric }
3570b57cec5SDimitry Andric return m_uuid;
3580b57cec5SDimitry Andric }
3590b57cec5SDimitry Andric
SetUUID(const lldb_private::UUID & uuid)3600b57cec5SDimitry Andric void Module::SetUUID(const lldb_private::UUID &uuid) {
3610b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_mutex);
3620b57cec5SDimitry Andric if (!m_did_set_uuid) {
3630b57cec5SDimitry Andric m_uuid = uuid;
3640b57cec5SDimitry Andric m_did_set_uuid = true;
3650b57cec5SDimitry Andric } else {
3660b57cec5SDimitry Andric lldbassert(0 && "Attempting to overwrite the existing module UUID");
3670b57cec5SDimitry Andric }
3680b57cec5SDimitry Andric }
3690b57cec5SDimitry Andric
3709dba64beSDimitry Andric llvm::Expected<TypeSystem &>
GetTypeSystemForLanguage(LanguageType language)3719dba64beSDimitry Andric Module::GetTypeSystemForLanguage(LanguageType language) {
3720b57cec5SDimitry Andric return m_type_system_map.GetTypeSystemForLanguage(language, this, true);
3730b57cec5SDimitry Andric }
3740b57cec5SDimitry Andric
ParseAllDebugSymbols()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
CalculateSymbolContext(SymbolContext * sc)4080b57cec5SDimitry Andric void Module::CalculateSymbolContext(SymbolContext *sc) {
4090b57cec5SDimitry Andric sc->module_sp = shared_from_this();
4100b57cec5SDimitry Andric }
4110b57cec5SDimitry Andric
CalculateSymbolContextModule()4120b57cec5SDimitry Andric ModuleSP Module::CalculateSymbolContextModule() { return shared_from_this(); }
4130b57cec5SDimitry Andric
DumpSymbolContext(Stream * s)4140b57cec5SDimitry Andric void Module::DumpSymbolContext(Stream *s) {
4150b57cec5SDimitry Andric s->Printf(", Module{%p}", static_cast<void *>(this));
4160b57cec5SDimitry Andric }
4170b57cec5SDimitry Andric
GetNumCompileUnits()4180b57cec5SDimitry Andric size_t Module::GetNumCompileUnits() {
4190b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_mutex);
420af732203SDimitry Andric LLDB_SCOPED_TIMERF("Module::GetNumCompileUnits (module = %p)",
4210b57cec5SDimitry Andric static_cast<void *>(this));
4229dba64beSDimitry Andric if (SymbolFile *symbols = GetSymbolFile())
4230b57cec5SDimitry Andric return symbols->GetNumCompileUnits();
4240b57cec5SDimitry Andric return 0;
4250b57cec5SDimitry Andric }
4260b57cec5SDimitry Andric
GetCompileUnitAtIndex(size_t index)4270b57cec5SDimitry Andric CompUnitSP Module::GetCompileUnitAtIndex(size_t index) {
4280b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_mutex);
4290b57cec5SDimitry Andric size_t num_comp_units = GetNumCompileUnits();
4300b57cec5SDimitry Andric CompUnitSP cu_sp;
4310b57cec5SDimitry Andric
4320b57cec5SDimitry Andric if (index < num_comp_units) {
4339dba64beSDimitry Andric if (SymbolFile *symbols = GetSymbolFile())
4340b57cec5SDimitry Andric cu_sp = symbols->GetCompileUnitAtIndex(index);
4350b57cec5SDimitry Andric }
4360b57cec5SDimitry Andric return cu_sp;
4370b57cec5SDimitry Andric }
4380b57cec5SDimitry Andric
ResolveFileAddress(lldb::addr_t vm_addr,Address & so_addr)4390b57cec5SDimitry Andric bool Module::ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) {
4400b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_mutex);
4410b57cec5SDimitry Andric SectionList *section_list = GetSectionList();
4420b57cec5SDimitry Andric if (section_list)
4430b57cec5SDimitry Andric return so_addr.ResolveAddressUsingFileSections(vm_addr, section_list);
4440b57cec5SDimitry Andric return false;
4450b57cec5SDimitry Andric }
4460b57cec5SDimitry Andric
ResolveSymbolContextForAddress(const Address & so_addr,lldb::SymbolContextItem resolve_scope,SymbolContext & sc,bool resolve_tail_call_address)4470b57cec5SDimitry Andric uint32_t Module::ResolveSymbolContextForAddress(
4480b57cec5SDimitry Andric const Address &so_addr, lldb::SymbolContextItem resolve_scope,
4490b57cec5SDimitry Andric SymbolContext &sc, bool resolve_tail_call_address) {
4500b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_mutex);
4510b57cec5SDimitry Andric uint32_t resolved_flags = 0;
4520b57cec5SDimitry Andric
4530b57cec5SDimitry Andric // Clear the result symbol context in case we don't find anything, but don't
4540b57cec5SDimitry Andric // clear the target
4550b57cec5SDimitry Andric sc.Clear(false);
4560b57cec5SDimitry Andric
4570b57cec5SDimitry Andric // Get the section from the section/offset address.
4580b57cec5SDimitry Andric SectionSP section_sp(so_addr.GetSection());
4590b57cec5SDimitry Andric
4600b57cec5SDimitry Andric // Make sure the section matches this module before we try and match anything
4610b57cec5SDimitry Andric if (section_sp && section_sp->GetModule().get() == this) {
4620b57cec5SDimitry Andric // If the section offset based address resolved itself, then this is the
4630b57cec5SDimitry Andric // right module.
4640b57cec5SDimitry Andric sc.module_sp = shared_from_this();
4650b57cec5SDimitry Andric resolved_flags |= eSymbolContextModule;
4660b57cec5SDimitry Andric
4679dba64beSDimitry Andric SymbolFile *symfile = GetSymbolFile();
4689dba64beSDimitry Andric if (!symfile)
4690b57cec5SDimitry Andric return resolved_flags;
4700b57cec5SDimitry Andric
4710b57cec5SDimitry Andric // Resolve the compile unit, function, block, line table or line entry if
4720b57cec5SDimitry Andric // requested.
4730b57cec5SDimitry Andric if (resolve_scope & eSymbolContextCompUnit ||
4740b57cec5SDimitry Andric resolve_scope & eSymbolContextFunction ||
4750b57cec5SDimitry Andric resolve_scope & eSymbolContextBlock ||
4760b57cec5SDimitry Andric resolve_scope & eSymbolContextLineEntry ||
4770b57cec5SDimitry Andric resolve_scope & eSymbolContextVariable) {
4780b57cec5SDimitry Andric resolved_flags |=
4799dba64beSDimitry Andric symfile->ResolveSymbolContext(so_addr, resolve_scope, sc);
4800b57cec5SDimitry Andric }
4810b57cec5SDimitry Andric
4820b57cec5SDimitry Andric // Resolve the symbol if requested, but don't re-look it up if we've
4830b57cec5SDimitry Andric // already found it.
4840b57cec5SDimitry Andric if (resolve_scope & eSymbolContextSymbol &&
4850b57cec5SDimitry Andric !(resolved_flags & eSymbolContextSymbol)) {
4869dba64beSDimitry Andric Symtab *symtab = symfile->GetSymtab();
4870b57cec5SDimitry Andric if (symtab && so_addr.IsSectionOffset()) {
4880b57cec5SDimitry Andric Symbol *matching_symbol = nullptr;
4890b57cec5SDimitry Andric
4900b57cec5SDimitry Andric symtab->ForEachSymbolContainingFileAddress(
4910b57cec5SDimitry Andric so_addr.GetFileAddress(),
4920b57cec5SDimitry Andric [&matching_symbol](Symbol *symbol) -> bool {
4930b57cec5SDimitry Andric if (symbol->GetType() != eSymbolTypeInvalid) {
4940b57cec5SDimitry Andric matching_symbol = symbol;
4950b57cec5SDimitry Andric return false; // Stop iterating
4960b57cec5SDimitry Andric }
4970b57cec5SDimitry Andric return true; // Keep iterating
4980b57cec5SDimitry Andric });
4990b57cec5SDimitry Andric sc.symbol = matching_symbol;
5000b57cec5SDimitry Andric if (!sc.symbol && resolve_scope & eSymbolContextFunction &&
5010b57cec5SDimitry Andric !(resolved_flags & eSymbolContextFunction)) {
5020b57cec5SDimitry Andric bool verify_unique = false; // No need to check again since
5030b57cec5SDimitry Andric // ResolveSymbolContext failed to find a
5040b57cec5SDimitry Andric // symbol at this address.
5050b57cec5SDimitry Andric if (ObjectFile *obj_file = sc.module_sp->GetObjectFile())
5060b57cec5SDimitry Andric sc.symbol =
5070b57cec5SDimitry Andric obj_file->ResolveSymbolForAddress(so_addr, verify_unique);
5080b57cec5SDimitry Andric }
5090b57cec5SDimitry Andric
5100b57cec5SDimitry Andric if (sc.symbol) {
5110b57cec5SDimitry Andric if (sc.symbol->IsSynthetic()) {
5120b57cec5SDimitry Andric // We have a synthetic symbol so lets check if the object file from
5130b57cec5SDimitry Andric // the symbol file in the symbol vendor is different than the
5140b57cec5SDimitry Andric // object file for the module, and if so search its symbol table to
5150b57cec5SDimitry Andric // see if we can come up with a better symbol. For example dSYM
5160b57cec5SDimitry Andric // files on MacOSX have an unstripped symbol table inside of them.
5170b57cec5SDimitry Andric ObjectFile *symtab_objfile = symtab->GetObjectFile();
5180b57cec5SDimitry Andric if (symtab_objfile && symtab_objfile->IsStripped()) {
5190b57cec5SDimitry Andric ObjectFile *symfile_objfile = symfile->GetObjectFile();
5200b57cec5SDimitry Andric if (symfile_objfile != symtab_objfile) {
5210b57cec5SDimitry Andric Symtab *symfile_symtab = symfile_objfile->GetSymtab();
5220b57cec5SDimitry Andric if (symfile_symtab) {
5230b57cec5SDimitry Andric Symbol *symbol =
5240b57cec5SDimitry Andric symfile_symtab->FindSymbolContainingFileAddress(
5250b57cec5SDimitry Andric so_addr.GetFileAddress());
5260b57cec5SDimitry Andric if (symbol && !symbol->IsSynthetic()) {
5270b57cec5SDimitry Andric sc.symbol = symbol;
5280b57cec5SDimitry Andric }
5290b57cec5SDimitry Andric }
5300b57cec5SDimitry Andric }
5310b57cec5SDimitry Andric }
5320b57cec5SDimitry Andric }
5330b57cec5SDimitry Andric resolved_flags |= eSymbolContextSymbol;
5340b57cec5SDimitry Andric }
5350b57cec5SDimitry Andric }
5360b57cec5SDimitry Andric }
5370b57cec5SDimitry Andric
5380b57cec5SDimitry Andric // For function symbols, so_addr may be off by one. This is a convention
5390b57cec5SDimitry Andric // consistent with FDE row indices in eh_frame sections, but requires extra
5400b57cec5SDimitry Andric // logic here to permit symbol lookup for disassembly and unwind.
5410b57cec5SDimitry Andric if (resolve_scope & eSymbolContextSymbol &&
5420b57cec5SDimitry Andric !(resolved_flags & eSymbolContextSymbol) && resolve_tail_call_address &&
5430b57cec5SDimitry Andric so_addr.IsSectionOffset()) {
5440b57cec5SDimitry Andric Address previous_addr = so_addr;
5450b57cec5SDimitry Andric previous_addr.Slide(-1);
5460b57cec5SDimitry Andric
5470b57cec5SDimitry Andric bool do_resolve_tail_call_address = false; // prevent recursion
5480b57cec5SDimitry Andric const uint32_t flags = ResolveSymbolContextForAddress(
5490b57cec5SDimitry Andric previous_addr, resolve_scope, sc, do_resolve_tail_call_address);
5500b57cec5SDimitry Andric if (flags & eSymbolContextSymbol) {
5510b57cec5SDimitry Andric AddressRange addr_range;
5520b57cec5SDimitry Andric if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
5530b57cec5SDimitry Andric false, addr_range)) {
5540b57cec5SDimitry Andric if (addr_range.GetBaseAddress().GetSection() ==
5550b57cec5SDimitry Andric so_addr.GetSection()) {
5560b57cec5SDimitry Andric // If the requested address is one past the address range of a
5570b57cec5SDimitry Andric // function (i.e. a tail call), or the decremented address is the
5580b57cec5SDimitry Andric // start of a function (i.e. some forms of trampoline), indicate
5590b57cec5SDimitry Andric // that the symbol has been resolved.
5600b57cec5SDimitry Andric if (so_addr.GetOffset() ==
5610b57cec5SDimitry Andric addr_range.GetBaseAddress().GetOffset() ||
5620b57cec5SDimitry Andric so_addr.GetOffset() ==
5630b57cec5SDimitry Andric addr_range.GetBaseAddress().GetOffset() +
5640b57cec5SDimitry Andric addr_range.GetByteSize()) {
5650b57cec5SDimitry Andric resolved_flags |= flags;
5660b57cec5SDimitry Andric }
5670b57cec5SDimitry Andric } else {
5680b57cec5SDimitry Andric sc.symbol =
5690b57cec5SDimitry Andric nullptr; // Don't trust the symbol if the sections didn't match.
5700b57cec5SDimitry Andric }
5710b57cec5SDimitry Andric }
5720b57cec5SDimitry Andric }
5730b57cec5SDimitry Andric }
5740b57cec5SDimitry Andric }
5750b57cec5SDimitry Andric return resolved_flags;
5760b57cec5SDimitry Andric }
5770b57cec5SDimitry Andric
ResolveSymbolContextForFilePath(const char * file_path,uint32_t line,bool check_inlines,lldb::SymbolContextItem resolve_scope,SymbolContextList & sc_list)5780b57cec5SDimitry Andric uint32_t Module::ResolveSymbolContextForFilePath(
5790b57cec5SDimitry Andric const char *file_path, uint32_t line, bool check_inlines,
5800b57cec5SDimitry Andric lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
5810b57cec5SDimitry Andric FileSpec file_spec(file_path);
5820b57cec5SDimitry Andric return ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
5830b57cec5SDimitry Andric resolve_scope, sc_list);
5840b57cec5SDimitry Andric }
5850b57cec5SDimitry Andric
ResolveSymbolContextsForFileSpec(const FileSpec & file_spec,uint32_t line,bool check_inlines,lldb::SymbolContextItem resolve_scope,SymbolContextList & sc_list)5860b57cec5SDimitry Andric uint32_t Module::ResolveSymbolContextsForFileSpec(
5870b57cec5SDimitry Andric const FileSpec &file_spec, uint32_t line, bool check_inlines,
5880b57cec5SDimitry Andric lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) {
5890b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_mutex);
590af732203SDimitry Andric LLDB_SCOPED_TIMERF("Module::ResolveSymbolContextForFilePath (%s:%u, "
5910b57cec5SDimitry Andric "check_inlines = %s, resolve_scope = 0x%8.8x)",
5920b57cec5SDimitry Andric file_spec.GetPath().c_str(), line,
5930b57cec5SDimitry Andric check_inlines ? "yes" : "no", resolve_scope);
5940b57cec5SDimitry Andric
5950b57cec5SDimitry Andric const uint32_t initial_count = sc_list.GetSize();
5960b57cec5SDimitry Andric
597*5f7ddb14SDimitry Andric if (SymbolFile *symbols = GetSymbolFile()) {
598*5f7ddb14SDimitry Andric // TODO: Handle SourceLocationSpec column information
599*5f7ddb14SDimitry Andric SourceLocationSpec location_spec(file_spec, line, /*column=*/llvm::None,
600*5f7ddb14SDimitry Andric check_inlines, /*exact_match=*/false);
601*5f7ddb14SDimitry Andric
602*5f7ddb14SDimitry Andric symbols->ResolveSymbolContext(location_spec, resolve_scope, sc_list);
603*5f7ddb14SDimitry Andric }
6040b57cec5SDimitry Andric
6050b57cec5SDimitry Andric return sc_list.GetSize() - initial_count;
6060b57cec5SDimitry Andric }
6070b57cec5SDimitry Andric
FindGlobalVariables(ConstString name,const CompilerDeclContext & parent_decl_ctx,size_t max_matches,VariableList & variables)6089dba64beSDimitry Andric void Module::FindGlobalVariables(ConstString name,
6095ffd83dbSDimitry Andric const CompilerDeclContext &parent_decl_ctx,
6109dba64beSDimitry Andric size_t max_matches, VariableList &variables) {
6119dba64beSDimitry Andric if (SymbolFile *symbols = GetSymbolFile())
6129dba64beSDimitry Andric symbols->FindGlobalVariables(name, parent_decl_ctx, max_matches, variables);
6130b57cec5SDimitry Andric }
6140b57cec5SDimitry Andric
FindGlobalVariables(const RegularExpression & regex,size_t max_matches,VariableList & variables)6159dba64beSDimitry Andric void Module::FindGlobalVariables(const RegularExpression ®ex,
6169dba64beSDimitry Andric size_t max_matches, VariableList &variables) {
6179dba64beSDimitry Andric SymbolFile *symbols = GetSymbolFile();
6180b57cec5SDimitry Andric if (symbols)
6199dba64beSDimitry Andric symbols->FindGlobalVariables(regex, max_matches, variables);
6200b57cec5SDimitry Andric }
6210b57cec5SDimitry Andric
FindCompileUnits(const FileSpec & path,SymbolContextList & sc_list)6229dba64beSDimitry Andric void Module::FindCompileUnits(const FileSpec &path,
6230b57cec5SDimitry Andric SymbolContextList &sc_list) {
6240b57cec5SDimitry Andric const size_t num_compile_units = GetNumCompileUnits();
6250b57cec5SDimitry Andric SymbolContext sc;
6260b57cec5SDimitry Andric sc.module_sp = shared_from_this();
6270b57cec5SDimitry Andric for (size_t i = 0; i < num_compile_units; ++i) {
6280b57cec5SDimitry Andric sc.comp_unit = GetCompileUnitAtIndex(i).get();
6290b57cec5SDimitry Andric if (sc.comp_unit) {
630480093f4SDimitry Andric if (FileSpec::Match(path, sc.comp_unit->GetPrimaryFile()))
6310b57cec5SDimitry Andric sc_list.Append(sc);
6320b57cec5SDimitry Andric }
6330b57cec5SDimitry Andric }
6340b57cec5SDimitry Andric }
6350b57cec5SDimitry Andric
LookupInfo(ConstString name,FunctionNameType name_type_mask,LanguageType language)6360b57cec5SDimitry Andric Module::LookupInfo::LookupInfo(ConstString name,
6370b57cec5SDimitry Andric FunctionNameType name_type_mask,
6380b57cec5SDimitry Andric LanguageType language)
6390b57cec5SDimitry Andric : m_name(name), m_lookup_name(), m_language(language),
6400b57cec5SDimitry Andric m_name_type_mask(eFunctionNameTypeNone),
6410b57cec5SDimitry Andric m_match_name_after_lookup(false) {
6420b57cec5SDimitry Andric const char *name_cstr = name.GetCString();
6430b57cec5SDimitry Andric llvm::StringRef basename;
6440b57cec5SDimitry Andric llvm::StringRef context;
6450b57cec5SDimitry Andric
6460b57cec5SDimitry Andric if (name_type_mask & eFunctionNameTypeAuto) {
6470b57cec5SDimitry Andric if (CPlusPlusLanguage::IsCPPMangledName(name_cstr))
6480b57cec5SDimitry Andric m_name_type_mask = eFunctionNameTypeFull;
6490b57cec5SDimitry Andric else if ((language == eLanguageTypeUnknown ||
6500b57cec5SDimitry Andric Language::LanguageIsObjC(language)) &&
6510b57cec5SDimitry Andric ObjCLanguage::IsPossibleObjCMethodName(name_cstr))
6520b57cec5SDimitry Andric m_name_type_mask = eFunctionNameTypeFull;
6530b57cec5SDimitry Andric else if (Language::LanguageIsC(language)) {
6540b57cec5SDimitry Andric m_name_type_mask = eFunctionNameTypeFull;
6550b57cec5SDimitry Andric } else {
6560b57cec5SDimitry Andric if ((language == eLanguageTypeUnknown ||
6570b57cec5SDimitry Andric Language::LanguageIsObjC(language)) &&
6580b57cec5SDimitry Andric ObjCLanguage::IsPossibleObjCSelector(name_cstr))
6590b57cec5SDimitry Andric m_name_type_mask |= eFunctionNameTypeSelector;
6600b57cec5SDimitry Andric
6610b57cec5SDimitry Andric CPlusPlusLanguage::MethodName cpp_method(name);
6620b57cec5SDimitry Andric basename = cpp_method.GetBasename();
6630b57cec5SDimitry Andric if (basename.empty()) {
6640b57cec5SDimitry Andric if (CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
6650b57cec5SDimitry Andric basename))
6660b57cec5SDimitry Andric m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
6670b57cec5SDimitry Andric else
6680b57cec5SDimitry Andric m_name_type_mask |= eFunctionNameTypeFull;
6690b57cec5SDimitry Andric } else {
6700b57cec5SDimitry Andric m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
6710b57cec5SDimitry Andric }
6720b57cec5SDimitry Andric }
6730b57cec5SDimitry Andric } else {
6740b57cec5SDimitry Andric m_name_type_mask = name_type_mask;
6750b57cec5SDimitry Andric if (name_type_mask & eFunctionNameTypeMethod ||
6760b57cec5SDimitry Andric name_type_mask & eFunctionNameTypeBase) {
6770b57cec5SDimitry Andric // If they've asked for a CPP method or function name and it can't be
6780b57cec5SDimitry Andric // that, we don't even need to search for CPP methods or names.
6790b57cec5SDimitry Andric CPlusPlusLanguage::MethodName cpp_method(name);
6800b57cec5SDimitry Andric if (cpp_method.IsValid()) {
6810b57cec5SDimitry Andric basename = cpp_method.GetBasename();
6820b57cec5SDimitry Andric
6830b57cec5SDimitry Andric if (!cpp_method.GetQualifiers().empty()) {
6840b57cec5SDimitry Andric // There is a "const" or other qualifier following the end of the
6850b57cec5SDimitry Andric // function parens, this can't be a eFunctionNameTypeBase
6860b57cec5SDimitry Andric m_name_type_mask &= ~(eFunctionNameTypeBase);
6870b57cec5SDimitry Andric if (m_name_type_mask == eFunctionNameTypeNone)
6880b57cec5SDimitry Andric return;
6890b57cec5SDimitry Andric }
6900b57cec5SDimitry Andric } else {
6910b57cec5SDimitry Andric // If the CPP method parser didn't manage to chop this up, try to fill
6920b57cec5SDimitry Andric // in the base name if we can. If a::b::c is passed in, we need to just
6930b57cec5SDimitry Andric // look up "c", and then we'll filter the result later.
6940b57cec5SDimitry Andric CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
6950b57cec5SDimitry Andric basename);
6960b57cec5SDimitry Andric }
6970b57cec5SDimitry Andric }
6980b57cec5SDimitry Andric
6990b57cec5SDimitry Andric if (name_type_mask & eFunctionNameTypeSelector) {
7000b57cec5SDimitry Andric if (!ObjCLanguage::IsPossibleObjCSelector(name_cstr)) {
7010b57cec5SDimitry Andric m_name_type_mask &= ~(eFunctionNameTypeSelector);
7020b57cec5SDimitry Andric if (m_name_type_mask == eFunctionNameTypeNone)
7030b57cec5SDimitry Andric return;
7040b57cec5SDimitry Andric }
7050b57cec5SDimitry Andric }
7060b57cec5SDimitry Andric
7070b57cec5SDimitry Andric // Still try and get a basename in case someone specifies a name type mask
7080b57cec5SDimitry Andric // of eFunctionNameTypeFull and a name like "A::func"
7090b57cec5SDimitry Andric if (basename.empty()) {
7100b57cec5SDimitry Andric if (name_type_mask & eFunctionNameTypeFull &&
7110b57cec5SDimitry Andric !CPlusPlusLanguage::IsCPPMangledName(name_cstr)) {
7120b57cec5SDimitry Andric CPlusPlusLanguage::MethodName cpp_method(name);
7130b57cec5SDimitry Andric basename = cpp_method.GetBasename();
7140b57cec5SDimitry Andric if (basename.empty())
7150b57cec5SDimitry Andric CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
7160b57cec5SDimitry Andric basename);
7170b57cec5SDimitry Andric }
7180b57cec5SDimitry Andric }
7190b57cec5SDimitry Andric }
7200b57cec5SDimitry Andric
7210b57cec5SDimitry Andric if (!basename.empty()) {
7220b57cec5SDimitry Andric // The name supplied was a partial C++ path like "a::count". In this case
7230b57cec5SDimitry Andric // we want to do a lookup on the basename "count" and then make sure any
7240b57cec5SDimitry Andric // matching results contain "a::count" so that it would match "b::a::count"
7250b57cec5SDimitry Andric // and "a::count". This is why we set "match_name_after_lookup" to true
7260b57cec5SDimitry Andric m_lookup_name.SetString(basename);
7270b57cec5SDimitry Andric m_match_name_after_lookup = true;
7280b57cec5SDimitry Andric } else {
7290b57cec5SDimitry Andric // The name is already correct, just use the exact name as supplied, and we
7300b57cec5SDimitry Andric // won't need to check if any matches contain "name"
7310b57cec5SDimitry Andric m_lookup_name = name;
7320b57cec5SDimitry Andric m_match_name_after_lookup = false;
7330b57cec5SDimitry Andric }
7340b57cec5SDimitry Andric }
7350b57cec5SDimitry Andric
Prune(SymbolContextList & sc_list,size_t start_idx) const7360b57cec5SDimitry Andric void Module::LookupInfo::Prune(SymbolContextList &sc_list,
7370b57cec5SDimitry Andric size_t start_idx) const {
7380b57cec5SDimitry Andric if (m_match_name_after_lookup && m_name) {
7390b57cec5SDimitry Andric SymbolContext sc;
7400b57cec5SDimitry Andric size_t i = start_idx;
7410b57cec5SDimitry Andric while (i < sc_list.GetSize()) {
7420b57cec5SDimitry Andric if (!sc_list.GetContextAtIndex(i, sc))
7430b57cec5SDimitry Andric break;
7440b57cec5SDimitry Andric ConstString full_name(sc.GetFunctionName());
7450b57cec5SDimitry Andric if (full_name &&
7460b57cec5SDimitry Andric ::strstr(full_name.GetCString(), m_name.GetCString()) == nullptr) {
7470b57cec5SDimitry Andric sc_list.RemoveContextAtIndex(i);
7480b57cec5SDimitry Andric } else {
7490b57cec5SDimitry Andric ++i;
7500b57cec5SDimitry Andric }
7510b57cec5SDimitry Andric }
7520b57cec5SDimitry Andric }
7530b57cec5SDimitry Andric
7540b57cec5SDimitry Andric // If we have only full name matches we might have tried to set breakpoint on
7550b57cec5SDimitry Andric // "func" and specified eFunctionNameTypeFull, but we might have found
7560b57cec5SDimitry Andric // "a::func()", "a::b::func()", "c::func()", "func()" and "func". Only
7570b57cec5SDimitry Andric // "func()" and "func" should end up matching.
7580b57cec5SDimitry Andric if (m_name_type_mask == eFunctionNameTypeFull) {
7590b57cec5SDimitry Andric SymbolContext sc;
7600b57cec5SDimitry Andric size_t i = start_idx;
7610b57cec5SDimitry Andric while (i < sc_list.GetSize()) {
7620b57cec5SDimitry Andric if (!sc_list.GetContextAtIndex(i, sc))
7630b57cec5SDimitry Andric break;
7640b57cec5SDimitry Andric // Make sure the mangled and demangled names don't match before we try to
7650b57cec5SDimitry Andric // pull anything out
7660b57cec5SDimitry Andric ConstString mangled_name(sc.GetFunctionName(Mangled::ePreferMangled));
7670b57cec5SDimitry Andric ConstString full_name(sc.GetFunctionName());
7680b57cec5SDimitry Andric if (mangled_name != m_name && full_name != m_name)
7690b57cec5SDimitry Andric {
7700b57cec5SDimitry Andric CPlusPlusLanguage::MethodName cpp_method(full_name);
7710b57cec5SDimitry Andric if (cpp_method.IsValid()) {
7720b57cec5SDimitry Andric if (cpp_method.GetContext().empty()) {
7730b57cec5SDimitry Andric if (cpp_method.GetBasename().compare(m_name.GetStringRef()) != 0) {
7740b57cec5SDimitry Andric sc_list.RemoveContextAtIndex(i);
7750b57cec5SDimitry Andric continue;
7760b57cec5SDimitry Andric }
7770b57cec5SDimitry Andric } else {
7780b57cec5SDimitry Andric std::string qualified_name;
7790b57cec5SDimitry Andric llvm::StringRef anon_prefix("(anonymous namespace)");
7800b57cec5SDimitry Andric if (cpp_method.GetContext() == anon_prefix)
7810b57cec5SDimitry Andric qualified_name = cpp_method.GetBasename().str();
7820b57cec5SDimitry Andric else
7830b57cec5SDimitry Andric qualified_name = cpp_method.GetScopeQualifiedName();
7840b57cec5SDimitry Andric if (qualified_name != m_name.GetCString()) {
7850b57cec5SDimitry Andric sc_list.RemoveContextAtIndex(i);
7860b57cec5SDimitry Andric continue;
7870b57cec5SDimitry Andric }
7880b57cec5SDimitry Andric }
7890b57cec5SDimitry Andric }
7900b57cec5SDimitry Andric }
7910b57cec5SDimitry Andric ++i;
7920b57cec5SDimitry Andric }
7930b57cec5SDimitry Andric }
7940b57cec5SDimitry Andric }
7950b57cec5SDimitry Andric
FindFunctions(ConstString name,const CompilerDeclContext & parent_decl_ctx,FunctionNameType name_type_mask,bool include_symbols,bool include_inlines,SymbolContextList & sc_list)7969dba64beSDimitry Andric void Module::FindFunctions(ConstString name,
7975ffd83dbSDimitry Andric const CompilerDeclContext &parent_decl_ctx,
7980b57cec5SDimitry Andric FunctionNameType name_type_mask,
7990b57cec5SDimitry Andric bool include_symbols, bool include_inlines,
8009dba64beSDimitry Andric SymbolContextList &sc_list) {
8010b57cec5SDimitry Andric const size_t old_size = sc_list.GetSize();
8020b57cec5SDimitry Andric
8030b57cec5SDimitry Andric // Find all the functions (not symbols, but debug information functions...
8049dba64beSDimitry Andric SymbolFile *symbols = GetSymbolFile();
8050b57cec5SDimitry Andric
8060b57cec5SDimitry Andric if (name_type_mask & eFunctionNameTypeAuto) {
8070b57cec5SDimitry Andric LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
8080b57cec5SDimitry Andric
8090b57cec5SDimitry Andric if (symbols) {
8100b57cec5SDimitry Andric symbols->FindFunctions(lookup_info.GetLookupName(), parent_decl_ctx,
8110b57cec5SDimitry Andric lookup_info.GetNameTypeMask(), include_inlines,
8129dba64beSDimitry Andric sc_list);
8130b57cec5SDimitry Andric
8140b57cec5SDimitry Andric // Now check our symbol table for symbols that are code symbols if
8150b57cec5SDimitry Andric // requested
8160b57cec5SDimitry Andric if (include_symbols) {
8170b57cec5SDimitry Andric Symtab *symtab = symbols->GetSymtab();
8180b57cec5SDimitry Andric if (symtab)
8190b57cec5SDimitry Andric symtab->FindFunctionSymbols(lookup_info.GetLookupName(),
8200b57cec5SDimitry Andric lookup_info.GetNameTypeMask(), sc_list);
8210b57cec5SDimitry Andric }
8220b57cec5SDimitry Andric }
8230b57cec5SDimitry Andric
8240b57cec5SDimitry Andric const size_t new_size = sc_list.GetSize();
8250b57cec5SDimitry Andric
8260b57cec5SDimitry Andric if (old_size < new_size)
8270b57cec5SDimitry Andric lookup_info.Prune(sc_list, old_size);
8280b57cec5SDimitry Andric } else {
8290b57cec5SDimitry Andric if (symbols) {
8300b57cec5SDimitry Andric symbols->FindFunctions(name, parent_decl_ctx, name_type_mask,
8319dba64beSDimitry Andric include_inlines, sc_list);
8320b57cec5SDimitry Andric
8330b57cec5SDimitry Andric // Now check our symbol table for symbols that are code symbols if
8340b57cec5SDimitry Andric // requested
8350b57cec5SDimitry Andric if (include_symbols) {
8360b57cec5SDimitry Andric Symtab *symtab = symbols->GetSymtab();
8370b57cec5SDimitry Andric if (symtab)
8380b57cec5SDimitry Andric symtab->FindFunctionSymbols(name, name_type_mask, sc_list);
8390b57cec5SDimitry Andric }
8400b57cec5SDimitry Andric }
8410b57cec5SDimitry Andric }
8420b57cec5SDimitry Andric }
8430b57cec5SDimitry Andric
FindFunctions(const RegularExpression & regex,bool include_symbols,bool include_inlines,SymbolContextList & sc_list)8449dba64beSDimitry Andric void Module::FindFunctions(const RegularExpression ®ex, bool include_symbols,
8459dba64beSDimitry Andric bool include_inlines,
8469dba64beSDimitry Andric SymbolContextList &sc_list) {
8470b57cec5SDimitry Andric const size_t start_size = sc_list.GetSize();
8480b57cec5SDimitry Andric
8499dba64beSDimitry Andric if (SymbolFile *symbols = GetSymbolFile()) {
8509dba64beSDimitry Andric symbols->FindFunctions(regex, include_inlines, sc_list);
8510b57cec5SDimitry Andric
8520b57cec5SDimitry Andric // Now check our symbol table for symbols that are code symbols if
8530b57cec5SDimitry Andric // requested
8540b57cec5SDimitry Andric if (include_symbols) {
8550b57cec5SDimitry Andric Symtab *symtab = symbols->GetSymtab();
8560b57cec5SDimitry Andric if (symtab) {
8570b57cec5SDimitry Andric std::vector<uint32_t> symbol_indexes;
8580b57cec5SDimitry Andric symtab->AppendSymbolIndexesMatchingRegExAndType(
8590b57cec5SDimitry Andric regex, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny,
8600b57cec5SDimitry Andric symbol_indexes);
8610b57cec5SDimitry Andric const size_t num_matches = symbol_indexes.size();
8620b57cec5SDimitry Andric if (num_matches) {
8630b57cec5SDimitry Andric SymbolContext sc(this);
8640b57cec5SDimitry Andric const size_t end_functions_added_index = sc_list.GetSize();
8650b57cec5SDimitry Andric size_t num_functions_added_to_sc_list =
8660b57cec5SDimitry Andric end_functions_added_index - start_size;
8670b57cec5SDimitry Andric if (num_functions_added_to_sc_list == 0) {
8680b57cec5SDimitry Andric // No functions were added, just symbols, so we can just append
8690b57cec5SDimitry Andric // them
8700b57cec5SDimitry Andric for (size_t i = 0; i < num_matches; ++i) {
8710b57cec5SDimitry Andric sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
8720b57cec5SDimitry Andric SymbolType sym_type = sc.symbol->GetType();
8730b57cec5SDimitry Andric if (sc.symbol && (sym_type == eSymbolTypeCode ||
8740b57cec5SDimitry Andric sym_type == eSymbolTypeResolver))
8750b57cec5SDimitry Andric sc_list.Append(sc);
8760b57cec5SDimitry Andric }
8770b57cec5SDimitry Andric } else {
8780b57cec5SDimitry Andric typedef std::map<lldb::addr_t, uint32_t> FileAddrToIndexMap;
8790b57cec5SDimitry Andric FileAddrToIndexMap file_addr_to_index;
8800b57cec5SDimitry Andric for (size_t i = start_size; i < end_functions_added_index; ++i) {
8810b57cec5SDimitry Andric const SymbolContext &sc = sc_list[i];
8820b57cec5SDimitry Andric if (sc.block)
8830b57cec5SDimitry Andric continue;
8840b57cec5SDimitry Andric file_addr_to_index[sc.function->GetAddressRange()
8850b57cec5SDimitry Andric .GetBaseAddress()
8860b57cec5SDimitry Andric .GetFileAddress()] = i;
8870b57cec5SDimitry Andric }
8880b57cec5SDimitry Andric
8890b57cec5SDimitry Andric FileAddrToIndexMap::const_iterator end = file_addr_to_index.end();
8900b57cec5SDimitry Andric // Functions were added so we need to merge symbols into any
8910b57cec5SDimitry Andric // existing function symbol contexts
8920b57cec5SDimitry Andric for (size_t i = start_size; i < num_matches; ++i) {
8930b57cec5SDimitry Andric sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
8940b57cec5SDimitry Andric SymbolType sym_type = sc.symbol->GetType();
8950b57cec5SDimitry Andric if (sc.symbol && sc.symbol->ValueIsAddress() &&
8960b57cec5SDimitry Andric (sym_type == eSymbolTypeCode ||
8970b57cec5SDimitry Andric sym_type == eSymbolTypeResolver)) {
8980b57cec5SDimitry Andric FileAddrToIndexMap::const_iterator pos =
8990b57cec5SDimitry Andric file_addr_to_index.find(
9000b57cec5SDimitry Andric sc.symbol->GetAddressRef().GetFileAddress());
9010b57cec5SDimitry Andric if (pos == end)
9020b57cec5SDimitry Andric sc_list.Append(sc);
9030b57cec5SDimitry Andric else
9040b57cec5SDimitry Andric sc_list[pos->second].symbol = sc.symbol;
9050b57cec5SDimitry Andric }
9060b57cec5SDimitry Andric }
9070b57cec5SDimitry Andric }
9080b57cec5SDimitry Andric }
9090b57cec5SDimitry Andric }
9100b57cec5SDimitry Andric }
9110b57cec5SDimitry Andric }
9120b57cec5SDimitry Andric }
9130b57cec5SDimitry Andric
FindAddressesForLine(const lldb::TargetSP target_sp,const FileSpec & file,uint32_t line,Function * function,std::vector<Address> & output_local,std::vector<Address> & output_extern)9140b57cec5SDimitry Andric void Module::FindAddressesForLine(const lldb::TargetSP target_sp,
9150b57cec5SDimitry Andric const FileSpec &file, uint32_t line,
9160b57cec5SDimitry Andric Function *function,
9170b57cec5SDimitry Andric std::vector<Address> &output_local,
9180b57cec5SDimitry Andric std::vector<Address> &output_extern) {
9190b57cec5SDimitry Andric SearchFilterByModule filter(target_sp, m_file);
920*5f7ddb14SDimitry Andric
921*5f7ddb14SDimitry Andric // TODO: Handle SourceLocationSpec column information
922*5f7ddb14SDimitry Andric SourceLocationSpec location_spec(file, line, /*column=*/llvm::None,
923*5f7ddb14SDimitry Andric /*check_inlines=*/true,
924*5f7ddb14SDimitry Andric /*exact_match=*/false);
925*5f7ddb14SDimitry Andric AddressResolverFileLine resolver(location_spec);
9260b57cec5SDimitry Andric resolver.ResolveAddress(filter);
9270b57cec5SDimitry Andric
9280b57cec5SDimitry Andric for (size_t n = 0; n < resolver.GetNumberOfAddresses(); n++) {
9290b57cec5SDimitry Andric Address addr = resolver.GetAddressRangeAtIndex(n).GetBaseAddress();
9300b57cec5SDimitry Andric Function *f = addr.CalculateSymbolContextFunction();
9310b57cec5SDimitry Andric if (f && f == function)
9320b57cec5SDimitry Andric output_local.push_back(addr);
9330b57cec5SDimitry Andric else
9340b57cec5SDimitry Andric output_extern.push_back(addr);
9350b57cec5SDimitry Andric }
9360b57cec5SDimitry Andric }
9370b57cec5SDimitry Andric
FindTypes_Impl(ConstString name,const CompilerDeclContext & parent_decl_ctx,size_t max_matches,llvm::DenseSet<lldb_private::SymbolFile * > & searched_symbol_files,TypeMap & types)9389dba64beSDimitry Andric void Module::FindTypes_Impl(
9395ffd83dbSDimitry Andric ConstString name, const CompilerDeclContext &parent_decl_ctx,
9409dba64beSDimitry Andric size_t max_matches,
9410b57cec5SDimitry Andric llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
9420b57cec5SDimitry Andric TypeMap &types) {
943af732203SDimitry Andric LLDB_SCOPED_TIMER();
9449dba64beSDimitry Andric if (SymbolFile *symbols = GetSymbolFile())
9459dba64beSDimitry Andric symbols->FindTypes(name, parent_decl_ctx, max_matches,
9460b57cec5SDimitry Andric searched_symbol_files, types);
9470b57cec5SDimitry Andric }
9480b57cec5SDimitry Andric
FindTypesInNamespace(ConstString type_name,const CompilerDeclContext & parent_decl_ctx,size_t max_matches,TypeList & type_list)9499dba64beSDimitry Andric void Module::FindTypesInNamespace(ConstString type_name,
9505ffd83dbSDimitry Andric const CompilerDeclContext &parent_decl_ctx,
9510b57cec5SDimitry Andric size_t max_matches, TypeList &type_list) {
9520b57cec5SDimitry Andric TypeMap types_map;
9530b57cec5SDimitry Andric llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
9549dba64beSDimitry Andric FindTypes_Impl(type_name, parent_decl_ctx, max_matches, searched_symbol_files,
9559dba64beSDimitry Andric types_map);
9569dba64beSDimitry Andric if (types_map.GetSize()) {
9570b57cec5SDimitry Andric SymbolContext sc;
9580b57cec5SDimitry Andric sc.module_sp = shared_from_this();
9590b57cec5SDimitry Andric sc.SortTypeList(types_map, type_list);
9600b57cec5SDimitry Andric }
9610b57cec5SDimitry Andric }
9620b57cec5SDimitry Andric
FindFirstType(const SymbolContext & sc,ConstString name,bool exact_match)9630b57cec5SDimitry Andric lldb::TypeSP Module::FindFirstType(const SymbolContext &sc,
9640b57cec5SDimitry Andric ConstString name, bool exact_match) {
9650b57cec5SDimitry Andric TypeList type_list;
9660b57cec5SDimitry Andric llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
9670b57cec5SDimitry Andric FindTypes(name, exact_match, 1, searched_symbol_files, type_list);
9689dba64beSDimitry Andric if (type_list.GetSize())
9690b57cec5SDimitry Andric return type_list.GetTypeAtIndex(0);
9700b57cec5SDimitry Andric return TypeSP();
9710b57cec5SDimitry Andric }
9720b57cec5SDimitry Andric
FindTypes(ConstString name,bool exact_match,size_t max_matches,llvm::DenseSet<lldb_private::SymbolFile * > & searched_symbol_files,TypeList & types)9739dba64beSDimitry Andric void Module::FindTypes(
9740b57cec5SDimitry Andric ConstString name, bool exact_match, size_t max_matches,
9750b57cec5SDimitry Andric llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
9760b57cec5SDimitry Andric TypeList &types) {
9770b57cec5SDimitry Andric const char *type_name_cstr = name.GetCString();
9780b57cec5SDimitry Andric llvm::StringRef type_scope;
9790b57cec5SDimitry Andric llvm::StringRef type_basename;
9800b57cec5SDimitry Andric TypeClass type_class = eTypeClassAny;
9810b57cec5SDimitry Andric TypeMap typesmap;
9820b57cec5SDimitry Andric
9830b57cec5SDimitry Andric if (Type::GetTypeScopeAndBasename(type_name_cstr, type_scope, type_basename,
9840b57cec5SDimitry Andric type_class)) {
9850b57cec5SDimitry Andric // Check if "name" starts with "::" which means the qualified type starts
9860b57cec5SDimitry Andric // from the root namespace and implies and exact match. The typenames we
9870b57cec5SDimitry Andric // get back from clang do not start with "::" so we need to strip this off
9880b57cec5SDimitry Andric // in order to get the qualified names to match
9890b57cec5SDimitry Andric exact_match = type_scope.consume_front("::");
9900b57cec5SDimitry Andric
9910b57cec5SDimitry Andric ConstString type_basename_const_str(type_basename);
9925ffd83dbSDimitry Andric FindTypes_Impl(type_basename_const_str, CompilerDeclContext(), max_matches,
9939dba64beSDimitry Andric searched_symbol_files, typesmap);
9949dba64beSDimitry Andric if (typesmap.GetSize())
9955ffd83dbSDimitry Andric typesmap.RemoveMismatchedTypes(std::string(type_scope),
9965ffd83dbSDimitry Andric std::string(type_basename), type_class,
9970b57cec5SDimitry Andric exact_match);
9980b57cec5SDimitry Andric } else {
9990b57cec5SDimitry Andric // The type is not in a namespace/class scope, just search for it by
10000b57cec5SDimitry Andric // basename
10010b57cec5SDimitry Andric if (type_class != eTypeClassAny && !type_basename.empty()) {
10020b57cec5SDimitry Andric // The "type_name_cstr" will have been modified if we have a valid type
10030b57cec5SDimitry Andric // class prefix (like "struct", "class", "union", "typedef" etc).
10045ffd83dbSDimitry Andric FindTypes_Impl(ConstString(type_basename), CompilerDeclContext(),
10055ffd83dbSDimitry Andric UINT_MAX, searched_symbol_files, typesmap);
10065ffd83dbSDimitry Andric typesmap.RemoveMismatchedTypes(std::string(type_scope),
10075ffd83dbSDimitry Andric std::string(type_basename), type_class,
10080b57cec5SDimitry Andric exact_match);
10090b57cec5SDimitry Andric } else {
10105ffd83dbSDimitry Andric FindTypes_Impl(name, CompilerDeclContext(), UINT_MAX,
10115ffd83dbSDimitry Andric searched_symbol_files, typesmap);
10120b57cec5SDimitry Andric if (exact_match) {
10130b57cec5SDimitry Andric std::string name_str(name.AsCString(""));
10145ffd83dbSDimitry Andric typesmap.RemoveMismatchedTypes(std::string(type_scope), name_str,
10155ffd83dbSDimitry Andric type_class, exact_match);
10160b57cec5SDimitry Andric }
10170b57cec5SDimitry Andric }
10180b57cec5SDimitry Andric }
10199dba64beSDimitry Andric if (typesmap.GetSize()) {
10200b57cec5SDimitry Andric SymbolContext sc;
10210b57cec5SDimitry Andric sc.module_sp = shared_from_this();
10220b57cec5SDimitry Andric sc.SortTypeList(typesmap, types);
10230b57cec5SDimitry Andric }
10240b57cec5SDimitry Andric }
10250b57cec5SDimitry Andric
FindTypes(llvm::ArrayRef<CompilerContext> pattern,LanguageSet languages,llvm::DenseSet<lldb_private::SymbolFile * > & searched_symbol_files,TypeMap & types)1026480093f4SDimitry Andric void Module::FindTypes(
1027480093f4SDimitry Andric llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
1028480093f4SDimitry Andric llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
1029480093f4SDimitry Andric TypeMap &types) {
1030af732203SDimitry Andric LLDB_SCOPED_TIMER();
10319dba64beSDimitry Andric if (SymbolFile *symbols = GetSymbolFile())
1032480093f4SDimitry Andric symbols->FindTypes(pattern, languages, searched_symbol_files, types);
10339dba64beSDimitry Andric }
10349dba64beSDimitry Andric
GetSymbolFile(bool can_create,Stream * feedback_strm)10359dba64beSDimitry Andric SymbolFile *Module::GetSymbolFile(bool can_create, Stream *feedback_strm) {
10369dba64beSDimitry Andric if (!m_did_load_symfile.load()) {
10370b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_mutex);
10389dba64beSDimitry Andric if (!m_did_load_symfile.load() && can_create) {
10390b57cec5SDimitry Andric ObjectFile *obj_file = GetObjectFile();
10400b57cec5SDimitry Andric if (obj_file != nullptr) {
1041af732203SDimitry Andric LLDB_SCOPED_TIMER();
10420b57cec5SDimitry Andric m_symfile_up.reset(
10430b57cec5SDimitry Andric SymbolVendor::FindPlugin(shared_from_this(), feedback_strm));
10449dba64beSDimitry Andric m_did_load_symfile = true;
10450b57cec5SDimitry Andric }
10460b57cec5SDimitry Andric }
10470b57cec5SDimitry Andric }
10489dba64beSDimitry Andric return m_symfile_up ? m_symfile_up->GetSymbolFile() : nullptr;
10499dba64beSDimitry Andric }
10509dba64beSDimitry Andric
GetSymtab()10519dba64beSDimitry Andric Symtab *Module::GetSymtab() {
10529dba64beSDimitry Andric if (SymbolFile *symbols = GetSymbolFile())
10539dba64beSDimitry Andric return symbols->GetSymtab();
10549dba64beSDimitry Andric return nullptr;
10550b57cec5SDimitry Andric }
10560b57cec5SDimitry Andric
SetFileSpecAndObjectName(const FileSpec & file,ConstString object_name)10570b57cec5SDimitry Andric void Module::SetFileSpecAndObjectName(const FileSpec &file,
10580b57cec5SDimitry Andric ConstString object_name) {
10590b57cec5SDimitry Andric // Container objects whose paths do not specify a file directly can call this
10600b57cec5SDimitry Andric // function to correct the file and object names.
10610b57cec5SDimitry Andric m_file = file;
10620b57cec5SDimitry Andric m_mod_time = FileSystem::Instance().GetModificationTime(file);
10630b57cec5SDimitry Andric m_object_name = object_name;
10640b57cec5SDimitry Andric }
10650b57cec5SDimitry Andric
GetArchitecture() const10660b57cec5SDimitry Andric const ArchSpec &Module::GetArchitecture() const { return m_arch; }
10670b57cec5SDimitry Andric
GetSpecificationDescription() const10680b57cec5SDimitry Andric std::string Module::GetSpecificationDescription() const {
10690b57cec5SDimitry Andric std::string spec(GetFileSpec().GetPath());
10700b57cec5SDimitry Andric if (m_object_name) {
10710b57cec5SDimitry Andric spec += '(';
10720b57cec5SDimitry Andric spec += m_object_name.GetCString();
10730b57cec5SDimitry Andric spec += ')';
10740b57cec5SDimitry Andric }
10750b57cec5SDimitry Andric return spec;
10760b57cec5SDimitry Andric }
10770b57cec5SDimitry Andric
GetDescription(llvm::raw_ostream & s,lldb::DescriptionLevel level)1078480093f4SDimitry Andric void Module::GetDescription(llvm::raw_ostream &s,
1079480093f4SDimitry Andric lldb::DescriptionLevel level) {
10800b57cec5SDimitry Andric if (level >= eDescriptionLevelFull) {
10810b57cec5SDimitry Andric if (m_arch.IsValid())
1082480093f4SDimitry Andric s << llvm::formatv("({0}) ", m_arch.GetArchitectureName());
10830b57cec5SDimitry Andric }
10840b57cec5SDimitry Andric
10850b57cec5SDimitry Andric if (level == eDescriptionLevelBrief) {
10860b57cec5SDimitry Andric const char *filename = m_file.GetFilename().GetCString();
10870b57cec5SDimitry Andric if (filename)
1088480093f4SDimitry Andric s << filename;
10890b57cec5SDimitry Andric } else {
10900b57cec5SDimitry Andric char path[PATH_MAX];
10910b57cec5SDimitry Andric if (m_file.GetPath(path, sizeof(path)))
1092480093f4SDimitry Andric s << path;
10930b57cec5SDimitry Andric }
10940b57cec5SDimitry Andric
10950b57cec5SDimitry Andric const char *object_name = m_object_name.GetCString();
10960b57cec5SDimitry Andric if (object_name)
1097480093f4SDimitry Andric s << llvm::formatv("({0})", object_name);
10980b57cec5SDimitry Andric }
10990b57cec5SDimitry Andric
ReportError(const char * format,...)11000b57cec5SDimitry Andric void Module::ReportError(const char *format, ...) {
11010b57cec5SDimitry Andric if (format && format[0]) {
11020b57cec5SDimitry Andric StreamString strm;
11030b57cec5SDimitry Andric strm.PutCString("error: ");
1104480093f4SDimitry Andric GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelBrief);
11050b57cec5SDimitry Andric strm.PutChar(' ');
11060b57cec5SDimitry Andric va_list args;
11070b57cec5SDimitry Andric va_start(args, format);
11080b57cec5SDimitry Andric strm.PrintfVarArg(format, args);
11090b57cec5SDimitry Andric va_end(args);
11100b57cec5SDimitry Andric
11110b57cec5SDimitry Andric const int format_len = strlen(format);
11120b57cec5SDimitry Andric if (format_len > 0) {
11130b57cec5SDimitry Andric const char last_char = format[format_len - 1];
11140b57cec5SDimitry Andric if (last_char != '\n' && last_char != '\r')
11150b57cec5SDimitry Andric strm.EOL();
11160b57cec5SDimitry Andric }
11170b57cec5SDimitry Andric Host::SystemLog(Host::eSystemLogError, "%s", strm.GetData());
11180b57cec5SDimitry Andric }
11190b57cec5SDimitry Andric }
11200b57cec5SDimitry Andric
FileHasChanged() const11210b57cec5SDimitry Andric bool Module::FileHasChanged() const {
11225ffd83dbSDimitry Andric // We have provided the DataBuffer for this module to avoid accessing the
11235ffd83dbSDimitry Andric // filesystem. We never want to reload those files.
11245ffd83dbSDimitry Andric if (m_data_sp)
11255ffd83dbSDimitry Andric return false;
11260b57cec5SDimitry Andric if (!m_file_has_changed)
11270b57cec5SDimitry Andric m_file_has_changed =
11280b57cec5SDimitry Andric (FileSystem::Instance().GetModificationTime(m_file) != m_mod_time);
11290b57cec5SDimitry Andric return m_file_has_changed;
11300b57cec5SDimitry Andric }
11310b57cec5SDimitry Andric
ReportErrorIfModifyDetected(const char * format,...)11320b57cec5SDimitry Andric void Module::ReportErrorIfModifyDetected(const char *format, ...) {
11330b57cec5SDimitry Andric if (!m_first_file_changed_log) {
11340b57cec5SDimitry Andric if (FileHasChanged()) {
11350b57cec5SDimitry Andric m_first_file_changed_log = true;
11360b57cec5SDimitry Andric if (format) {
11370b57cec5SDimitry Andric StreamString strm;
11380b57cec5SDimitry Andric strm.PutCString("error: the object file ");
1139480093f4SDimitry Andric GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelFull);
11400b57cec5SDimitry Andric strm.PutCString(" has been modified\n");
11410b57cec5SDimitry Andric
11420b57cec5SDimitry Andric va_list args;
11430b57cec5SDimitry Andric va_start(args, format);
11440b57cec5SDimitry Andric strm.PrintfVarArg(format, args);
11450b57cec5SDimitry Andric va_end(args);
11460b57cec5SDimitry Andric
11470b57cec5SDimitry Andric const int format_len = strlen(format);
11480b57cec5SDimitry Andric if (format_len > 0) {
11490b57cec5SDimitry Andric const char last_char = format[format_len - 1];
11500b57cec5SDimitry Andric if (last_char != '\n' && last_char != '\r')
11510b57cec5SDimitry Andric strm.EOL();
11520b57cec5SDimitry Andric }
11530b57cec5SDimitry Andric strm.PutCString("The debug session should be aborted as the original "
11540b57cec5SDimitry Andric "debug information has been overwritten.\n");
11550b57cec5SDimitry Andric Host::SystemLog(Host::eSystemLogError, "%s", strm.GetData());
11560b57cec5SDimitry Andric }
11570b57cec5SDimitry Andric }
11580b57cec5SDimitry Andric }
11590b57cec5SDimitry Andric }
11600b57cec5SDimitry Andric
ReportWarning(const char * format,...)11610b57cec5SDimitry Andric void Module::ReportWarning(const char *format, ...) {
11620b57cec5SDimitry Andric if (format && format[0]) {
11630b57cec5SDimitry Andric StreamString strm;
11640b57cec5SDimitry Andric strm.PutCString("warning: ");
1165480093f4SDimitry Andric GetDescription(strm.AsRawOstream(), lldb::eDescriptionLevelFull);
11660b57cec5SDimitry Andric strm.PutChar(' ');
11670b57cec5SDimitry Andric
11680b57cec5SDimitry Andric va_list args;
11690b57cec5SDimitry Andric va_start(args, format);
11700b57cec5SDimitry Andric strm.PrintfVarArg(format, args);
11710b57cec5SDimitry Andric va_end(args);
11720b57cec5SDimitry Andric
11730b57cec5SDimitry Andric const int format_len = strlen(format);
11740b57cec5SDimitry Andric if (format_len > 0) {
11750b57cec5SDimitry Andric const char last_char = format[format_len - 1];
11760b57cec5SDimitry Andric if (last_char != '\n' && last_char != '\r')
11770b57cec5SDimitry Andric strm.EOL();
11780b57cec5SDimitry Andric }
11790b57cec5SDimitry Andric Host::SystemLog(Host::eSystemLogWarning, "%s", strm.GetData());
11800b57cec5SDimitry Andric }
11810b57cec5SDimitry Andric }
11820b57cec5SDimitry Andric
LogMessage(Log * log,const char * format,...)11830b57cec5SDimitry Andric void Module::LogMessage(Log *log, const char *format, ...) {
11840b57cec5SDimitry Andric if (log != nullptr) {
11850b57cec5SDimitry Andric StreamString log_message;
1186480093f4SDimitry Andric GetDescription(log_message.AsRawOstream(), lldb::eDescriptionLevelFull);
11870b57cec5SDimitry Andric log_message.PutCString(": ");
11880b57cec5SDimitry Andric va_list args;
11890b57cec5SDimitry Andric va_start(args, format);
11900b57cec5SDimitry Andric log_message.PrintfVarArg(format, args);
11910b57cec5SDimitry Andric va_end(args);
11920b57cec5SDimitry Andric log->PutCString(log_message.GetData());
11930b57cec5SDimitry Andric }
11940b57cec5SDimitry Andric }
11950b57cec5SDimitry Andric
LogMessageVerboseBacktrace(Log * log,const char * format,...)11960b57cec5SDimitry Andric void Module::LogMessageVerboseBacktrace(Log *log, const char *format, ...) {
11970b57cec5SDimitry Andric if (log != nullptr) {
11980b57cec5SDimitry Andric StreamString log_message;
1199480093f4SDimitry Andric GetDescription(log_message.AsRawOstream(), lldb::eDescriptionLevelFull);
12000b57cec5SDimitry Andric log_message.PutCString(": ");
12010b57cec5SDimitry Andric va_list args;
12020b57cec5SDimitry Andric va_start(args, format);
12030b57cec5SDimitry Andric log_message.PrintfVarArg(format, args);
12040b57cec5SDimitry Andric va_end(args);
12050b57cec5SDimitry Andric if (log->GetVerbose()) {
12060b57cec5SDimitry Andric std::string back_trace;
12070b57cec5SDimitry Andric llvm::raw_string_ostream stream(back_trace);
12080b57cec5SDimitry Andric llvm::sys::PrintStackTrace(stream);
12090b57cec5SDimitry Andric log_message.PutCString(back_trace);
12100b57cec5SDimitry Andric }
12110b57cec5SDimitry Andric log->PutCString(log_message.GetData());
12120b57cec5SDimitry Andric }
12130b57cec5SDimitry Andric }
12140b57cec5SDimitry Andric
Dump(Stream * s)12150b57cec5SDimitry Andric void Module::Dump(Stream *s) {
12160b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_mutex);
12170b57cec5SDimitry Andric // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
12180b57cec5SDimitry Andric s->Indent();
12190b57cec5SDimitry Andric s->Printf("Module %s%s%s%s\n", m_file.GetPath().c_str(),
12200b57cec5SDimitry Andric m_object_name ? "(" : "",
12210b57cec5SDimitry Andric m_object_name ? m_object_name.GetCString() : "",
12220b57cec5SDimitry Andric m_object_name ? ")" : "");
12230b57cec5SDimitry Andric
12240b57cec5SDimitry Andric s->IndentMore();
12250b57cec5SDimitry Andric
12260b57cec5SDimitry Andric ObjectFile *objfile = GetObjectFile();
12270b57cec5SDimitry Andric if (objfile)
12280b57cec5SDimitry Andric objfile->Dump(s);
12290b57cec5SDimitry Andric
12309dba64beSDimitry Andric if (SymbolFile *symbols = GetSymbolFile())
12319dba64beSDimitry Andric symbols->Dump(*s);
12320b57cec5SDimitry Andric
12330b57cec5SDimitry Andric s->IndentLess();
12340b57cec5SDimitry Andric }
12350b57cec5SDimitry Andric
GetObjectName() const12360b57cec5SDimitry Andric ConstString Module::GetObjectName() const { return m_object_name; }
12370b57cec5SDimitry Andric
GetObjectFile()12380b57cec5SDimitry Andric ObjectFile *Module::GetObjectFile() {
12390b57cec5SDimitry Andric if (!m_did_load_objfile.load()) {
12400b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_mutex);
12410b57cec5SDimitry Andric if (!m_did_load_objfile.load()) {
1242af732203SDimitry Andric LLDB_SCOPED_TIMERF("Module::GetObjectFile () module = %s",
12430b57cec5SDimitry Andric GetFileSpec().GetFilename().AsCString(""));
12440b57cec5SDimitry Andric lldb::offset_t data_offset = 0;
12455ffd83dbSDimitry Andric lldb::offset_t file_size = 0;
12465ffd83dbSDimitry Andric
12475ffd83dbSDimitry Andric if (m_data_sp)
12485ffd83dbSDimitry Andric file_size = m_data_sp->GetByteSize();
12495ffd83dbSDimitry Andric else if (m_file)
12505ffd83dbSDimitry Andric file_size = FileSystem::Instance().GetByteSize(m_file);
12515ffd83dbSDimitry Andric
12520b57cec5SDimitry Andric if (file_size > m_object_offset) {
12530b57cec5SDimitry Andric m_did_load_objfile = true;
12545ffd83dbSDimitry Andric // FindPlugin will modify its data_sp argument. Do not let it
12555ffd83dbSDimitry Andric // modify our m_data_sp member.
12565ffd83dbSDimitry Andric auto data_sp = m_data_sp;
12570b57cec5SDimitry Andric m_objfile_sp = ObjectFile::FindPlugin(
12580b57cec5SDimitry Andric shared_from_this(), &m_file, m_object_offset,
12590b57cec5SDimitry Andric file_size - m_object_offset, data_sp, data_offset);
12600b57cec5SDimitry Andric if (m_objfile_sp) {
12610b57cec5SDimitry Andric // Once we get the object file, update our module with the object
12620b57cec5SDimitry Andric // file's architecture since it might differ in vendor/os if some
12630b57cec5SDimitry Andric // parts were unknown. But since the matching arch might already be
12640b57cec5SDimitry Andric // more specific than the generic COFF architecture, only merge in
12650b57cec5SDimitry Andric // those values that overwrite unspecified unknown values.
12660b57cec5SDimitry Andric m_arch.MergeFrom(m_objfile_sp->GetArchitecture());
12670b57cec5SDimitry Andric } else {
12680b57cec5SDimitry Andric ReportError("failed to load objfile for %s",
12690b57cec5SDimitry Andric GetFileSpec().GetPath().c_str());
12700b57cec5SDimitry Andric }
12710b57cec5SDimitry Andric }
12720b57cec5SDimitry Andric }
12730b57cec5SDimitry Andric }
12740b57cec5SDimitry Andric return m_objfile_sp.get();
12750b57cec5SDimitry Andric }
12760b57cec5SDimitry Andric
GetSectionList()12770b57cec5SDimitry Andric SectionList *Module::GetSectionList() {
12780b57cec5SDimitry Andric // Populate m_sections_up with sections from objfile.
12790b57cec5SDimitry Andric if (!m_sections_up) {
12800b57cec5SDimitry Andric ObjectFile *obj_file = GetObjectFile();
12810b57cec5SDimitry Andric if (obj_file != nullptr)
12820b57cec5SDimitry Andric obj_file->CreateSections(*GetUnifiedSectionList());
12830b57cec5SDimitry Andric }
12840b57cec5SDimitry Andric return m_sections_up.get();
12850b57cec5SDimitry Andric }
12860b57cec5SDimitry Andric
SectionFileAddressesChanged()12870b57cec5SDimitry Andric void Module::SectionFileAddressesChanged() {
12880b57cec5SDimitry Andric ObjectFile *obj_file = GetObjectFile();
12890b57cec5SDimitry Andric if (obj_file)
12900b57cec5SDimitry Andric obj_file->SectionFileAddressesChanged();
12919dba64beSDimitry Andric if (SymbolFile *symbols = GetSymbolFile())
12929dba64beSDimitry Andric symbols->SectionFileAddressesChanged();
12930b57cec5SDimitry Andric }
12940b57cec5SDimitry Andric
GetUnwindTable()12950b57cec5SDimitry Andric UnwindTable &Module::GetUnwindTable() {
12960b57cec5SDimitry Andric if (!m_unwind_table)
12970b57cec5SDimitry Andric m_unwind_table.emplace(*this);
12980b57cec5SDimitry Andric return *m_unwind_table;
12990b57cec5SDimitry Andric }
13000b57cec5SDimitry Andric
GetUnifiedSectionList()13010b57cec5SDimitry Andric SectionList *Module::GetUnifiedSectionList() {
13020b57cec5SDimitry Andric if (!m_sections_up)
13039dba64beSDimitry Andric m_sections_up = std::make_unique<SectionList>();
13040b57cec5SDimitry Andric return m_sections_up.get();
13050b57cec5SDimitry Andric }
13060b57cec5SDimitry Andric
FindFirstSymbolWithNameAndType(ConstString name,SymbolType symbol_type)13070b57cec5SDimitry Andric const Symbol *Module::FindFirstSymbolWithNameAndType(ConstString name,
13080b57cec5SDimitry Andric SymbolType symbol_type) {
1309af732203SDimitry Andric LLDB_SCOPED_TIMERF(
1310af732203SDimitry Andric "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",
13110b57cec5SDimitry Andric name.AsCString(), symbol_type);
13129dba64beSDimitry Andric if (Symtab *symtab = GetSymtab())
13130b57cec5SDimitry Andric return symtab->FindFirstSymbolWithNameAndType(
13140b57cec5SDimitry Andric name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);
13150b57cec5SDimitry Andric return nullptr;
13160b57cec5SDimitry Andric }
SymbolIndicesToSymbolContextList(Symtab * symtab,std::vector<uint32_t> & symbol_indexes,SymbolContextList & sc_list)13170b57cec5SDimitry Andric void Module::SymbolIndicesToSymbolContextList(
13180b57cec5SDimitry Andric Symtab *symtab, std::vector<uint32_t> &symbol_indexes,
13190b57cec5SDimitry Andric SymbolContextList &sc_list) {
13200b57cec5SDimitry Andric // No need to protect this call using m_mutex all other method calls are
13210b57cec5SDimitry Andric // already thread safe.
13220b57cec5SDimitry Andric
13230b57cec5SDimitry Andric size_t num_indices = symbol_indexes.size();
13240b57cec5SDimitry Andric if (num_indices > 0) {
13250b57cec5SDimitry Andric SymbolContext sc;
13260b57cec5SDimitry Andric CalculateSymbolContext(&sc);
13270b57cec5SDimitry Andric for (size_t i = 0; i < num_indices; i++) {
13280b57cec5SDimitry Andric sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
13290b57cec5SDimitry Andric if (sc.symbol)
13300b57cec5SDimitry Andric sc_list.Append(sc);
13310b57cec5SDimitry Andric }
13320b57cec5SDimitry Andric }
13330b57cec5SDimitry Andric }
13340b57cec5SDimitry Andric
FindFunctionSymbols(ConstString name,uint32_t name_type_mask,SymbolContextList & sc_list)13359dba64beSDimitry Andric void Module::FindFunctionSymbols(ConstString name,
13360b57cec5SDimitry Andric uint32_t name_type_mask,
13370b57cec5SDimitry Andric SymbolContextList &sc_list) {
1338af732203SDimitry Andric LLDB_SCOPED_TIMERF("Module::FindSymbolsFunctions (name = %s, mask = 0x%8.8x)",
13390b57cec5SDimitry Andric name.AsCString(), name_type_mask);
13409dba64beSDimitry Andric if (Symtab *symtab = GetSymtab())
13419dba64beSDimitry Andric symtab->FindFunctionSymbols(name, name_type_mask, sc_list);
13420b57cec5SDimitry Andric }
13430b57cec5SDimitry Andric
FindSymbolsWithNameAndType(ConstString name,SymbolType symbol_type,SymbolContextList & sc_list)13449dba64beSDimitry Andric void Module::FindSymbolsWithNameAndType(ConstString name,
13450b57cec5SDimitry Andric SymbolType symbol_type,
13460b57cec5SDimitry Andric SymbolContextList &sc_list) {
13470b57cec5SDimitry Andric // No need to protect this call using m_mutex all other method calls are
13480b57cec5SDimitry Andric // already thread safe.
1349af732203SDimitry Andric LLDB_SCOPED_TIMERF(
1350af732203SDimitry Andric "Module::FindSymbolsWithNameAndType (name = %s, type = %i)",
13510b57cec5SDimitry Andric name.AsCString(), symbol_type);
13529dba64beSDimitry Andric if (Symtab *symtab = GetSymtab()) {
13530b57cec5SDimitry Andric std::vector<uint32_t> symbol_indexes;
13540b57cec5SDimitry Andric symtab->FindAllSymbolsWithNameAndType(name, symbol_type, symbol_indexes);
13550b57cec5SDimitry Andric SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
13560b57cec5SDimitry Andric }
13570b57cec5SDimitry Andric }
13580b57cec5SDimitry Andric
FindSymbolsMatchingRegExAndType(const RegularExpression & regex,SymbolType symbol_type,SymbolContextList & sc_list)13599dba64beSDimitry Andric void Module::FindSymbolsMatchingRegExAndType(const RegularExpression ®ex,
13600b57cec5SDimitry Andric SymbolType symbol_type,
13610b57cec5SDimitry Andric SymbolContextList &sc_list) {
13620b57cec5SDimitry Andric // No need to protect this call using m_mutex all other method calls are
13630b57cec5SDimitry Andric // already thread safe.
1364af732203SDimitry Andric LLDB_SCOPED_TIMERF(
13650b57cec5SDimitry Andric "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",
13660b57cec5SDimitry Andric regex.GetText().str().c_str(), symbol_type);
13679dba64beSDimitry Andric if (Symtab *symtab = GetSymtab()) {
13680b57cec5SDimitry Andric std::vector<uint32_t> symbol_indexes;
13690b57cec5SDimitry Andric symtab->FindAllSymbolsMatchingRexExAndType(
13700b57cec5SDimitry Andric regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny,
13710b57cec5SDimitry Andric symbol_indexes);
13720b57cec5SDimitry Andric SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
13730b57cec5SDimitry Andric }
13740b57cec5SDimitry Andric }
13750b57cec5SDimitry Andric
PreloadSymbols()13760b57cec5SDimitry Andric void Module::PreloadSymbols() {
13770b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_mutex);
13789dba64beSDimitry Andric SymbolFile *sym_file = GetSymbolFile();
13799dba64beSDimitry Andric if (!sym_file)
13800b57cec5SDimitry Andric return;
13819dba64beSDimitry Andric
13820b57cec5SDimitry Andric // Prime the symbol file first, since it adds symbols to the symbol table.
13839dba64beSDimitry Andric sym_file->PreloadSymbols();
13849dba64beSDimitry Andric
13850b57cec5SDimitry Andric // Now we can prime the symbol table.
13869dba64beSDimitry Andric if (Symtab *symtab = sym_file->GetSymtab())
13870b57cec5SDimitry Andric symtab->PreloadSymbols();
13880b57cec5SDimitry Andric }
13890b57cec5SDimitry Andric
SetSymbolFileFileSpec(const FileSpec & file)13900b57cec5SDimitry Andric void Module::SetSymbolFileFileSpec(const FileSpec &file) {
13910b57cec5SDimitry Andric if (!FileSystem::Instance().Exists(file))
13920b57cec5SDimitry Andric return;
13930b57cec5SDimitry Andric if (m_symfile_up) {
13940b57cec5SDimitry Andric // Remove any sections in the unified section list that come from the
13950b57cec5SDimitry Andric // current symbol vendor.
13960b57cec5SDimitry Andric SectionList *section_list = GetSectionList();
13979dba64beSDimitry Andric SymbolFile *symbol_file = GetSymbolFile();
13980b57cec5SDimitry Andric if (section_list && symbol_file) {
13990b57cec5SDimitry Andric ObjectFile *obj_file = symbol_file->GetObjectFile();
14000b57cec5SDimitry Andric // Make sure we have an object file and that the symbol vendor's objfile
14010b57cec5SDimitry Andric // isn't the same as the module's objfile before we remove any sections
14020b57cec5SDimitry Andric // for it...
14030b57cec5SDimitry Andric if (obj_file) {
14040b57cec5SDimitry Andric // Check to make sure we aren't trying to specify the file we already
14050b57cec5SDimitry Andric // have
14060b57cec5SDimitry Andric if (obj_file->GetFileSpec() == file) {
14070b57cec5SDimitry Andric // We are being told to add the exact same file that we already have
14080b57cec5SDimitry Andric // we don't have to do anything.
14090b57cec5SDimitry Andric return;
14100b57cec5SDimitry Andric }
14110b57cec5SDimitry Andric
14120b57cec5SDimitry Andric // Cleare the current symtab as we are going to replace it with a new
14130b57cec5SDimitry Andric // one
14140b57cec5SDimitry Andric obj_file->ClearSymtab();
14150b57cec5SDimitry Andric
14160b57cec5SDimitry Andric // Clear the unwind table too, as that may also be affected by the
14170b57cec5SDimitry Andric // symbol file information.
14180b57cec5SDimitry Andric m_unwind_table.reset();
14190b57cec5SDimitry Andric
14200b57cec5SDimitry Andric // The symbol file might be a directory bundle ("/tmp/a.out.dSYM")
14210b57cec5SDimitry Andric // instead of a full path to the symbol file within the bundle
14220b57cec5SDimitry Andric // ("/tmp/a.out.dSYM/Contents/Resources/DWARF/a.out"). So we need to
14230b57cec5SDimitry Andric // check this
14240b57cec5SDimitry Andric
14250b57cec5SDimitry Andric if (FileSystem::Instance().IsDirectory(file)) {
14260b57cec5SDimitry Andric std::string new_path(file.GetPath());
14270b57cec5SDimitry Andric std::string old_path(obj_file->GetFileSpec().GetPath());
14285ffd83dbSDimitry Andric if (llvm::StringRef(old_path).startswith(new_path)) {
14290b57cec5SDimitry Andric // We specified the same bundle as the symbol file that we already
14300b57cec5SDimitry Andric // have
14310b57cec5SDimitry Andric return;
14320b57cec5SDimitry Andric }
14330b57cec5SDimitry Andric }
14340b57cec5SDimitry Andric
14350b57cec5SDimitry Andric if (obj_file != m_objfile_sp.get()) {
14360b57cec5SDimitry Andric size_t num_sections = section_list->GetNumSections(0);
14370b57cec5SDimitry Andric for (size_t idx = num_sections; idx > 0; --idx) {
14380b57cec5SDimitry Andric lldb::SectionSP section_sp(
14390b57cec5SDimitry Andric section_list->GetSectionAtIndex(idx - 1));
14400b57cec5SDimitry Andric if (section_sp->GetObjectFile() == obj_file) {
14410b57cec5SDimitry Andric section_list->DeleteSection(idx - 1);
14420b57cec5SDimitry Andric }
14430b57cec5SDimitry Andric }
14440b57cec5SDimitry Andric }
14450b57cec5SDimitry Andric }
14460b57cec5SDimitry Andric }
14470b57cec5SDimitry Andric // Keep all old symbol files around in case there are any lingering type
14480b57cec5SDimitry Andric // references in any SBValue objects that might have been handed out.
14490b57cec5SDimitry Andric m_old_symfiles.push_back(std::move(m_symfile_up));
14500b57cec5SDimitry Andric }
14510b57cec5SDimitry Andric m_symfile_spec = file;
14520b57cec5SDimitry Andric m_symfile_up.reset();
14539dba64beSDimitry Andric m_did_load_symfile = false;
14540b57cec5SDimitry Andric }
14550b57cec5SDimitry Andric
IsExecutable()14560b57cec5SDimitry Andric bool Module::IsExecutable() {
14570b57cec5SDimitry Andric if (GetObjectFile() == nullptr)
14580b57cec5SDimitry Andric return false;
14590b57cec5SDimitry Andric else
14600b57cec5SDimitry Andric return GetObjectFile()->IsExecutable();
14610b57cec5SDimitry Andric }
14620b57cec5SDimitry Andric
IsLoadedInTarget(Target * target)14630b57cec5SDimitry Andric bool Module::IsLoadedInTarget(Target *target) {
14640b57cec5SDimitry Andric ObjectFile *obj_file = GetObjectFile();
14650b57cec5SDimitry Andric if (obj_file) {
14660b57cec5SDimitry Andric SectionList *sections = GetSectionList();
14670b57cec5SDimitry Andric if (sections != nullptr) {
14680b57cec5SDimitry Andric size_t num_sections = sections->GetSize();
14690b57cec5SDimitry Andric for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++) {
14700b57cec5SDimitry Andric SectionSP section_sp = sections->GetSectionAtIndex(sect_idx);
14710b57cec5SDimitry Andric if (section_sp->GetLoadBaseAddress(target) != LLDB_INVALID_ADDRESS) {
14720b57cec5SDimitry Andric return true;
14730b57cec5SDimitry Andric }
14740b57cec5SDimitry Andric }
14750b57cec5SDimitry Andric }
14760b57cec5SDimitry Andric }
14770b57cec5SDimitry Andric return false;
14780b57cec5SDimitry Andric }
14790b57cec5SDimitry Andric
LoadScriptingResourceInTarget(Target * target,Status & error,Stream * feedback_stream)14800b57cec5SDimitry Andric bool Module::LoadScriptingResourceInTarget(Target *target, Status &error,
14810b57cec5SDimitry Andric Stream *feedback_stream) {
14820b57cec5SDimitry Andric if (!target) {
14830b57cec5SDimitry Andric error.SetErrorString("invalid destination Target");
14840b57cec5SDimitry Andric return false;
14850b57cec5SDimitry Andric }
14860b57cec5SDimitry Andric
14870b57cec5SDimitry Andric LoadScriptFromSymFile should_load =
14880b57cec5SDimitry Andric target->TargetProperties::GetLoadScriptFromSymbolFile();
14890b57cec5SDimitry Andric
14900b57cec5SDimitry Andric if (should_load == eLoadScriptFromSymFileFalse)
14910b57cec5SDimitry Andric return false;
14920b57cec5SDimitry Andric
14930b57cec5SDimitry Andric Debugger &debugger = target->GetDebugger();
14940b57cec5SDimitry Andric const ScriptLanguage script_language = debugger.GetScriptLanguage();
14950b57cec5SDimitry Andric if (script_language != eScriptLanguageNone) {
14960b57cec5SDimitry Andric
14970b57cec5SDimitry Andric PlatformSP platform_sp(target->GetPlatform());
14980b57cec5SDimitry Andric
14990b57cec5SDimitry Andric if (!platform_sp) {
15000b57cec5SDimitry Andric error.SetErrorString("invalid Platform");
15010b57cec5SDimitry Andric return false;
15020b57cec5SDimitry Andric }
15030b57cec5SDimitry Andric
15040b57cec5SDimitry Andric FileSpecList file_specs = platform_sp->LocateExecutableScriptingResources(
15050b57cec5SDimitry Andric target, *this, feedback_stream);
15060b57cec5SDimitry Andric
15070b57cec5SDimitry Andric const uint32_t num_specs = file_specs.GetSize();
15080b57cec5SDimitry Andric if (num_specs) {
15090b57cec5SDimitry Andric ScriptInterpreter *script_interpreter = debugger.GetScriptInterpreter();
15100b57cec5SDimitry Andric if (script_interpreter) {
15110b57cec5SDimitry Andric for (uint32_t i = 0; i < num_specs; ++i) {
15120b57cec5SDimitry Andric FileSpec scripting_fspec(file_specs.GetFileSpecAtIndex(i));
15130b57cec5SDimitry Andric if (scripting_fspec &&
15140b57cec5SDimitry Andric FileSystem::Instance().Exists(scripting_fspec)) {
15150b57cec5SDimitry Andric if (should_load == eLoadScriptFromSymFileWarn) {
15160b57cec5SDimitry Andric if (feedback_stream)
15170b57cec5SDimitry Andric feedback_stream->Printf(
15180b57cec5SDimitry Andric "warning: '%s' contains a debug script. To run this script "
15190b57cec5SDimitry Andric "in "
15200b57cec5SDimitry Andric "this debug session:\n\n command script import "
15210b57cec5SDimitry Andric "\"%s\"\n\n"
15220b57cec5SDimitry Andric "To run all discovered debug scripts in this session:\n\n"
15230b57cec5SDimitry Andric " settings set target.load-script-from-symbol-file "
15240b57cec5SDimitry Andric "true\n",
15250b57cec5SDimitry Andric GetFileSpec().GetFileNameStrippingExtension().GetCString(),
15260b57cec5SDimitry Andric scripting_fspec.GetPath().c_str());
15270b57cec5SDimitry Andric return false;
15280b57cec5SDimitry Andric }
15290b57cec5SDimitry Andric StreamString scripting_stream;
1530480093f4SDimitry Andric scripting_fspec.Dump(scripting_stream.AsRawOstream());
1531*5f7ddb14SDimitry Andric LoadScriptOptions options;
15320b57cec5SDimitry Andric bool did_load = script_interpreter->LoadScriptingModule(
1533*5f7ddb14SDimitry Andric scripting_stream.GetData(), options, error);
15340b57cec5SDimitry Andric if (!did_load)
15350b57cec5SDimitry Andric return false;
15360b57cec5SDimitry Andric }
15370b57cec5SDimitry Andric }
15380b57cec5SDimitry Andric } else {
15390b57cec5SDimitry Andric error.SetErrorString("invalid ScriptInterpreter");
15400b57cec5SDimitry Andric return false;
15410b57cec5SDimitry Andric }
15420b57cec5SDimitry Andric }
15430b57cec5SDimitry Andric }
15440b57cec5SDimitry Andric return true;
15450b57cec5SDimitry Andric }
15460b57cec5SDimitry Andric
SetArchitecture(const ArchSpec & new_arch)15470b57cec5SDimitry Andric bool Module::SetArchitecture(const ArchSpec &new_arch) {
15480b57cec5SDimitry Andric if (!m_arch.IsValid()) {
15490b57cec5SDimitry Andric m_arch = new_arch;
15500b57cec5SDimitry Andric return true;
15510b57cec5SDimitry Andric }
15520b57cec5SDimitry Andric return m_arch.IsCompatibleMatch(new_arch);
15530b57cec5SDimitry Andric }
15540b57cec5SDimitry Andric
SetLoadAddress(Target & target,lldb::addr_t value,bool value_is_offset,bool & changed)15550b57cec5SDimitry Andric bool Module::SetLoadAddress(Target &target, lldb::addr_t value,
15560b57cec5SDimitry Andric bool value_is_offset, bool &changed) {
15570b57cec5SDimitry Andric ObjectFile *object_file = GetObjectFile();
15580b57cec5SDimitry Andric if (object_file != nullptr) {
15590b57cec5SDimitry Andric changed = object_file->SetLoadAddress(target, value, value_is_offset);
15600b57cec5SDimitry Andric return true;
15610b57cec5SDimitry Andric } else {
15620b57cec5SDimitry Andric changed = false;
15630b57cec5SDimitry Andric }
15640b57cec5SDimitry Andric return false;
15650b57cec5SDimitry Andric }
15660b57cec5SDimitry Andric
MatchesModuleSpec(const ModuleSpec & module_ref)15670b57cec5SDimitry Andric bool Module::MatchesModuleSpec(const ModuleSpec &module_ref) {
15680b57cec5SDimitry Andric const UUID &uuid = module_ref.GetUUID();
15690b57cec5SDimitry Andric
15700b57cec5SDimitry Andric if (uuid.IsValid()) {
15710b57cec5SDimitry Andric // If the UUID matches, then nothing more needs to match...
15720b57cec5SDimitry Andric return (uuid == GetUUID());
15730b57cec5SDimitry Andric }
15740b57cec5SDimitry Andric
15750b57cec5SDimitry Andric const FileSpec &file_spec = module_ref.GetFileSpec();
1576480093f4SDimitry Andric if (!FileSpec::Match(file_spec, m_file) &&
1577480093f4SDimitry Andric !FileSpec::Match(file_spec, m_platform_file))
15780b57cec5SDimitry Andric return false;
15790b57cec5SDimitry Andric
15800b57cec5SDimitry Andric const FileSpec &platform_file_spec = module_ref.GetPlatformFileSpec();
1581480093f4SDimitry Andric if (!FileSpec::Match(platform_file_spec, GetPlatformFileSpec()))
15820b57cec5SDimitry Andric return false;
15830b57cec5SDimitry Andric
15840b57cec5SDimitry Andric const ArchSpec &arch = module_ref.GetArchitecture();
15850b57cec5SDimitry Andric if (arch.IsValid()) {
15860b57cec5SDimitry Andric if (!m_arch.IsCompatibleMatch(arch))
15870b57cec5SDimitry Andric return false;
15880b57cec5SDimitry Andric }
15890b57cec5SDimitry Andric
15900b57cec5SDimitry Andric ConstString object_name = module_ref.GetObjectName();
15910b57cec5SDimitry Andric if (object_name) {
15920b57cec5SDimitry Andric if (object_name != GetObjectName())
15930b57cec5SDimitry Andric return false;
15940b57cec5SDimitry Andric }
15950b57cec5SDimitry Andric return true;
15960b57cec5SDimitry Andric }
15970b57cec5SDimitry Andric
FindSourceFile(const FileSpec & orig_spec,FileSpec & new_spec) const15980b57cec5SDimitry Andric bool Module::FindSourceFile(const FileSpec &orig_spec,
15990b57cec5SDimitry Andric FileSpec &new_spec) const {
16000b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_mutex);
1601*5f7ddb14SDimitry Andric if (auto remapped = m_source_mappings.FindFile(orig_spec)) {
1602*5f7ddb14SDimitry Andric new_spec = *remapped;
1603*5f7ddb14SDimitry Andric return true;
1604*5f7ddb14SDimitry Andric }
1605*5f7ddb14SDimitry Andric return false;
16060b57cec5SDimitry Andric }
16070b57cec5SDimitry Andric
RemapSourceFile(llvm::StringRef path) const1608*5f7ddb14SDimitry Andric llvm::Optional<std::string> Module::RemapSourceFile(llvm::StringRef path) const {
16090b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(m_mutex);
1610*5f7ddb14SDimitry Andric if (auto remapped = m_source_mappings.RemapPath(path))
1611*5f7ddb14SDimitry Andric return remapped->GetPath();
1612*5f7ddb14SDimitry Andric return {};
16130b57cec5SDimitry Andric }
16140b57cec5SDimitry Andric
RegisterXcodeSDK(llvm::StringRef sdk_name,llvm::StringRef sysroot)16155ffd83dbSDimitry Andric void Module::RegisterXcodeSDK(llvm::StringRef sdk_name, llvm::StringRef sysroot) {
16165ffd83dbSDimitry Andric XcodeSDK sdk(sdk_name.str());
16175ffd83dbSDimitry Andric ConstString sdk_path(HostInfo::GetXcodeSDKPath(sdk));
16185ffd83dbSDimitry Andric if (!sdk_path)
16195ffd83dbSDimitry Andric return;
16205ffd83dbSDimitry Andric // If the SDK changed for a previously registered source path, update it.
16215ffd83dbSDimitry Andric // This could happend with -fdebug-prefix-map, otherwise it's unlikely.
16225ffd83dbSDimitry Andric ConstString sysroot_cs(sysroot);
16235ffd83dbSDimitry Andric if (!m_source_mappings.Replace(sysroot_cs, sdk_path, true))
16245ffd83dbSDimitry Andric // In the general case, however, append it to the list.
16255ffd83dbSDimitry Andric m_source_mappings.Append(sysroot_cs, sdk_path, false);
16265ffd83dbSDimitry Andric }
16275ffd83dbSDimitry Andric
MergeArchitecture(const ArchSpec & arch_spec)16289dba64beSDimitry Andric bool Module::MergeArchitecture(const ArchSpec &arch_spec) {
16299dba64beSDimitry Andric if (!arch_spec.IsValid())
16309dba64beSDimitry Andric return false;
16319dba64beSDimitry Andric LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_MODULES),
16329dba64beSDimitry Andric "module has arch %s, merging/replacing with arch %s",
16339dba64beSDimitry Andric m_arch.GetTriple().getTriple().c_str(),
16349dba64beSDimitry Andric arch_spec.GetTriple().getTriple().c_str());
16359dba64beSDimitry Andric if (!m_arch.IsCompatibleMatch(arch_spec)) {
16369dba64beSDimitry Andric // The new architecture is different, we just need to replace it.
16379dba64beSDimitry Andric return SetArchitecture(arch_spec);
16389dba64beSDimitry Andric }
16399dba64beSDimitry Andric
16409dba64beSDimitry Andric // Merge bits from arch_spec into "merged_arch" and set our architecture.
16419dba64beSDimitry Andric ArchSpec merged_arch(m_arch);
16429dba64beSDimitry Andric merged_arch.MergeFrom(arch_spec);
16439dba64beSDimitry Andric // SetArchitecture() is a no-op if m_arch is already valid.
16449dba64beSDimitry Andric m_arch = ArchSpec();
16459dba64beSDimitry Andric return SetArchitecture(merged_arch);
16469dba64beSDimitry Andric }
16479dba64beSDimitry Andric
GetVersion()16480b57cec5SDimitry Andric llvm::VersionTuple Module::GetVersion() {
16490b57cec5SDimitry Andric if (ObjectFile *obj_file = GetObjectFile())
16500b57cec5SDimitry Andric return obj_file->GetVersion();
16510b57cec5SDimitry Andric return llvm::VersionTuple();
16520b57cec5SDimitry Andric }
16530b57cec5SDimitry Andric
GetIsDynamicLinkEditor()16540b57cec5SDimitry Andric bool Module::GetIsDynamicLinkEditor() {
16550b57cec5SDimitry Andric ObjectFile *obj_file = GetObjectFile();
16560b57cec5SDimitry Andric
16570b57cec5SDimitry Andric if (obj_file)
16580b57cec5SDimitry Andric return obj_file->GetIsDynamicLinkEditor();
16590b57cec5SDimitry Andric
16600b57cec5SDimitry Andric return false;
16610b57cec5SDimitry Andric }
1662