diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h index 24d8e28cf686e..feaa351b71fa2 100644 --- a/lldb/include/lldb/Core/PluginManager.h +++ b/lldb/include/lldb/Core/PluginManager.h @@ -345,6 +345,19 @@ class PluginManager { static SymbolVendorCreateInstance GetSymbolVendorCreateCallbackAtIndex(uint32_t idx); + // SymbolLocator + static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, + SymbolLocatorCreateInstance create_callback, + SymbolLocatorLocateExecutableObjectFile + locate_executable_object_file = nullptr); + + static bool UnregisterPlugin(SymbolLocatorCreateInstance create_callback); + + static SymbolLocatorCreateInstance + GetSymbolLocatorCreateCallbackAtIndex(uint32_t idx); + + static ModuleSpec LocateExecutableObjectFile(const ModuleSpec &module_spec); + // Trace static bool RegisterPlugin( llvm::StringRef name, llvm::StringRef description, diff --git a/lldb/include/lldb/Symbol/LocateSymbolFile.h b/lldb/include/lldb/Symbol/LocateSymbolFile.h index 0bf6555909676..8cd62cd3f73e7 100644 --- a/lldb/include/lldb/Symbol/LocateSymbolFile.h +++ b/lldb/include/lldb/Symbol/LocateSymbolFile.h @@ -24,12 +24,6 @@ class UUID; class Symbols { public: - // Locate the executable file given a module specification. - // - // Locating the file should happen only on the local computer or using the - // current computers global settings. - static ModuleSpec LocateExecutableObjectFile(const ModuleSpec &module_spec); - // Locate the symbol file given a module specification. // // Locating the file should happen only on the local computer or using the diff --git a/lldb/include/lldb/Symbol/SymbolLocator.h b/lldb/include/lldb/Symbol/SymbolLocator.h new file mode 100644 index 0000000000000..e8376ff756880 --- /dev/null +++ b/lldb/include/lldb/Symbol/SymbolLocator.h @@ -0,0 +1,23 @@ +//===-- SymbolLocator.h -----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SYMBOL_SYMBOLLOCATOR_H +#define LLDB_SYMBOL_SYMBOLLOCATOR_H + +#include "lldb/Core/PluginInterface.h" + +namespace lldb_private { + +class SymbolLocator : public PluginInterface { +public: + SymbolLocator() = default; +}; + +} // namespace lldb_private + +#endif // LLDB_SYMBOL_SYMBOLFILELOCATOR_H diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index aa099d4abc3b0..f66b2ad4362f9 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -217,6 +217,7 @@ class SymbolContextScope; class SymbolContextSpecifier; class SymbolFile; class SymbolFileType; +class SymbolLocator; class SymbolVendor; class Symtab; class SyntheticChildren; diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h index 2313723b16782..a22a3e9792b31 100644 --- a/lldb/include/lldb/lldb-private-interfaces.h +++ b/lldb/include/lldb/lldb-private-interfaces.h @@ -89,6 +89,9 @@ typedef SymbolVendor *(*SymbolVendorCreateInstance)( const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm); // Module can be NULL for default system symbol vendor +typedef SymbolLocator *(*SymbolLocatorCreateInstance)(); +typedef std::optional<ModuleSpec> (*SymbolLocatorLocateExecutableObjectFile)( + const ModuleSpec &module_spec); typedef bool (*BreakpointHitCallback)(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, diff --git a/lldb/source/Core/DynamicLoader.cpp b/lldb/source/Core/DynamicLoader.cpp index ce6a84e4e0226..7751fd70dedd7 100644 --- a/lldb/source/Core/DynamicLoader.cpp +++ b/lldb/source/Core/DynamicLoader.cpp @@ -221,7 +221,7 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress( module_spec.GetSymbolFileSpec() = Symbols::LocateExecutableSymbolFile(module_spec, search_paths); ModuleSpec objfile_module_spec = - Symbols::LocateExecutableObjectFile(module_spec); + PluginManager::LocateExecutableObjectFile(module_spec); module_spec.GetFileSpec() = objfile_module_spec.GetFileSpec(); if (FileSystem::Instance().Exists(module_spec.GetFileSpec()) && FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec())) { diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 3650df762231d..519145bba4955 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -9,6 +9,7 @@ #include "lldb/Core/ModuleList.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" #include "lldb/Host/FileSystem.h" #include "lldb/Interpreter/OptionValueFileSpec.h" #include "lldb/Interpreter/OptionValueFileSpecList.h" @@ -906,7 +907,7 @@ ModuleList::GetSharedModule(const ModuleSpec &module_spec, ModuleSP &module_sp, // Fixup the incoming path in case the path points to a valid file, yet the // arch or UUID (if one was passed in) don't match. ModuleSpec located_binary_modulespec = - Symbols::LocateExecutableObjectFile(module_spec); + PluginManager::LocateExecutableObjectFile(module_spec); // Don't look for the file if it appears to be the same one we already // checked for above... diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp index ac274112e53df..85e3f1cdcf124 100644 --- a/lldb/source/Core/PluginManager.cpp +++ b/lldb/source/Core/PluginManager.cpp @@ -1081,6 +1081,59 @@ PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) { return GetSymbolVendorInstances().GetCallbackAtIndex(idx); } +#pragma mark SymbolLocator + +struct SymbolLocatorInstance + : public PluginInstance<SymbolLocatorCreateInstance> { + SymbolLocatorInstance( + llvm::StringRef name, llvm::StringRef description, + CallbackType create_callback, + SymbolLocatorLocateExecutableObjectFile locate_executable_object_file) + : PluginInstance<SymbolLocatorCreateInstance>(name, description, + create_callback), + locate_executable_object_file(locate_executable_object_file) {} + + SymbolLocatorLocateExecutableObjectFile locate_executable_object_file; +}; +typedef PluginInstances<SymbolLocatorInstance> SymbolLocatorInstances; + +static SymbolLocatorInstances &GetSymbolLocatorInstances() { + static SymbolLocatorInstances g_instances; + return g_instances; +} + +bool PluginManager::RegisterPlugin( + llvm::StringRef name, llvm::StringRef description, + SymbolLocatorCreateInstance create_callback, + SymbolLocatorLocateExecutableObjectFile locate_executable_object_file) { + return GetSymbolLocatorInstances().RegisterPlugin( + name, description, create_callback, locate_executable_object_file); +} + +bool PluginManager::UnregisterPlugin( + SymbolLocatorCreateInstance create_callback) { + return GetSymbolLocatorInstances().UnregisterPlugin(create_callback); +} + +SymbolLocatorCreateInstance +PluginManager::GetSymbolLocatorCreateCallbackAtIndex(uint32_t idx) { + return GetSymbolLocatorInstances().GetCallbackAtIndex(idx); +} + +ModuleSpec +PluginManager::LocateExecutableObjectFile(const ModuleSpec &module_spec) { + auto &instances = GetSymbolLocatorInstances().GetInstances(); + for (auto &instance : instances) { + if (instance.locate_executable_object_file) { + std::optional<ModuleSpec> result = + instance.locate_executable_object_file(module_spec); + if (result) + return *result; + } + } + return {}; +} + #pragma mark Trace struct TraceInstance diff --git a/lldb/source/Plugins/CMakeLists.txt b/lldb/source/Plugins/CMakeLists.txt index 63f2c5b685a89..854f589f45ae0 100644 --- a/lldb/source/Plugins/CMakeLists.txt +++ b/lldb/source/Plugins/CMakeLists.txt @@ -20,6 +20,7 @@ add_subdirectory(ScriptInterpreter) add_subdirectory(StructuredData) add_subdirectory(SymbolFile) add_subdirectory(SystemRuntime) +add_subdirectory(SymbolLocator) add_subdirectory(SymbolVendor) add_subdirectory(Trace) add_subdirectory(TraceExporter) diff --git a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp index 0d1caf4d7318b..93d8e9bf75f52 100644 --- a/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp +++ b/lldb/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp @@ -282,7 +282,7 @@ Status ProcessKDP::DoConnectRemote(llvm::StringRef remote_url) { search_paths); if (module_spec.GetSymbolFileSpec()) { ModuleSpec executable_module_spec = - Symbols::LocateExecutableObjectFile(module_spec); + PluginManager::LocateExecutableObjectFile(module_spec); if (FileSystem::Instance().Exists( executable_module_spec.GetFileSpec())) { module_spec.GetFileSpec() = diff --git a/lldb/source/Plugins/SymbolLocator/CMakeLists.txt b/lldb/source/Plugins/SymbolLocator/CMakeLists.txt new file mode 100644 index 0000000000000..74abecd796949 --- /dev/null +++ b/lldb/source/Plugins/SymbolLocator/CMakeLists.txt @@ -0,0 +1,4 @@ +add_subdirectory(Default) +if (CMAKE_SYSTEM_NAME MATCHES "Darwin") + add_subdirectory(DebugSymbols) +endif() diff --git a/lldb/source/Plugins/SymbolLocator/DebugSymbols/CMakeLists.txt b/lldb/source/Plugins/SymbolLocator/DebugSymbols/CMakeLists.txt new file mode 100644 index 0000000000000..40f9cc1d44e2d --- /dev/null +++ b/lldb/source/Plugins/SymbolLocator/DebugSymbols/CMakeLists.txt @@ -0,0 +1,8 @@ +add_lldb_library(lldbPluginSymbolLocatorDebugSymbols PLUGIN + SymbolLocatorDebugSymbols.cpp + + LINK_LIBS + lldbCore + lldbHost + lldbSymbol + ) diff --git a/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp b/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp new file mode 100644 index 0000000000000..ef19507e87e5d --- /dev/null +++ b/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.cpp @@ -0,0 +1,327 @@ +//===-- SymbolLocatorDebugSymbols.cpp -------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "SymbolLocatorDebugSymbols.h" + +#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Progress.h" +#include "lldb/Core/Section.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Symbol/LocateSymbolFile.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/DataBuffer.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/Timer.h" +#include "lldb/Utility/UUID.h" + +#include "llvm/ADT/SmallSet.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/ThreadPool.h" + +#include "Host/macosx/cfcpp/CFCBundle.h" +#include "Host/macosx/cfcpp/CFCData.h" +#include "Host/macosx/cfcpp/CFCReleaser.h" +#include "Host/macosx/cfcpp/CFCString.h" + +#include "mach/machine.h" + +#include <CoreFoundation/CoreFoundation.h> + +#include <cstring> +#include <dirent.h> +#include <dlfcn.h> +#include <optional> +#include <pwd.h> + +using namespace lldb; +using namespace lldb_private; + +static CFURLRef (*g_dlsym_DBGCopyFullDSYMURLForUUID)( + CFUUIDRef uuid, CFURLRef exec_url) = nullptr; +static CFDictionaryRef (*g_dlsym_DBGCopyDSYMPropertyLists)(CFURLRef dsym_url) = + nullptr; + +LLDB_PLUGIN_DEFINE(SymbolLocatorDebugSymbols) + +SymbolLocatorDebugSymbols::SymbolLocatorDebugSymbols() : SymbolLocator() {} + +void SymbolLocatorDebugSymbols::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance, + LocateExecutableObjectFile); +} + +void SymbolLocatorDebugSymbols::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +llvm::StringRef SymbolLocatorDebugSymbols::GetPluginDescriptionStatic() { + return "DebugSymbols symbol locator."; +} + +SymbolLocator *SymbolLocatorDebugSymbols::CreateInstance() { + return new SymbolLocatorDebugSymbols(); +} + +std::optional<ModuleSpec> SymbolLocatorDebugSymbols::LocateExecutableObjectFile( + const ModuleSpec &module_spec) { + Log *log = GetLog(LLDBLog::Host); + if (!ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) { + LLDB_LOGF(log, "Spotlight lookup for .dSYM bundles is disabled."); + return {}; + } + ModuleSpec return_module_spec; + return_module_spec = module_spec; + return_module_spec.GetFileSpec().Clear(); + return_module_spec.GetSymbolFileSpec().Clear(); + + const UUID *uuid = module_spec.GetUUIDPtr(); + const ArchSpec *arch = module_spec.GetArchitecturePtr(); + + int items_found = 0; + + if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr || + g_dlsym_DBGCopyDSYMPropertyLists == nullptr) { + void *handle = dlopen( + "/System/Library/PrivateFrameworks/DebugSymbols.framework/DebugSymbols", + RTLD_LAZY | RTLD_LOCAL); + if (handle) { + g_dlsym_DBGCopyFullDSYMURLForUUID = + (CFURLRef(*)(CFUUIDRef, CFURLRef))dlsym(handle, + "DBGCopyFullDSYMURLForUUID"); + g_dlsym_DBGCopyDSYMPropertyLists = (CFDictionaryRef(*)(CFURLRef))dlsym( + handle, "DBGCopyDSYMPropertyLists"); + } + } + + if (g_dlsym_DBGCopyFullDSYMURLForUUID == nullptr || + g_dlsym_DBGCopyDSYMPropertyLists == nullptr) { + return {}; + } + + if (uuid && uuid->IsValid()) { + // Try and locate the dSYM file using DebugSymbols first + llvm::ArrayRef<uint8_t> module_uuid = uuid->GetBytes(); + if (module_uuid.size() == 16) { + CFCReleaser<CFUUIDRef> module_uuid_ref(::CFUUIDCreateWithBytes( + NULL, module_uuid[0], module_uuid[1], module_uuid[2], module_uuid[3], + module_uuid[4], module_uuid[5], module_uuid[6], module_uuid[7], + module_uuid[8], module_uuid[9], module_uuid[10], module_uuid[11], + module_uuid[12], module_uuid[13], module_uuid[14], module_uuid[15])); + + if (module_uuid_ref.get()) { + CFCReleaser<CFURLRef> exec_url; + const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); + if (exec_fspec) { + char exec_cf_path[PATH_MAX]; + if (exec_fspec->GetPath(exec_cf_path, sizeof(exec_cf_path))) + exec_url.reset(::CFURLCreateFromFileSystemRepresentation( + NULL, (const UInt8 *)exec_cf_path, strlen(exec_cf_path), + FALSE)); + } + + CFCReleaser<CFURLRef> dsym_url(g_dlsym_DBGCopyFullDSYMURLForUUID( + module_uuid_ref.get(), exec_url.get())); + char path[PATH_MAX]; + + if (dsym_url.get()) { + if (::CFURLGetFileSystemRepresentation( + dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) { + LLDB_LOGF(log, + "DebugSymbols framework returned dSYM path of %s for " + "UUID %s -- looking for the dSYM", + path, uuid->GetAsString().c_str()); + FileSpec dsym_filespec(path); + if (path[0] == '~') + FileSystem::Instance().Resolve(dsym_filespec); + + if (FileSystem::Instance().IsDirectory(dsym_filespec)) { + dsym_filespec = + Symbols::FindSymbolFileInBundle(dsym_filespec, uuid, arch); + ++items_found; + } else { + ++items_found; + } + return_module_spec.GetSymbolFileSpec() = dsym_filespec; + } + + bool success = false; + if (log) { + if (::CFURLGetFileSystemRepresentation( + dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) { + LLDB_LOGF(log, + "DebugSymbols framework returned dSYM path of %s for " + "UUID %s -- looking for an exec file", + path, uuid->GetAsString().c_str()); + } + } + + CFCReleaser<CFDictionaryRef> dict( + g_dlsym_DBGCopyDSYMPropertyLists(dsym_url.get())); + CFDictionaryRef uuid_dict = NULL; + if (dict.get()) { + CFCString uuid_cfstr(uuid->GetAsString().c_str()); + uuid_dict = static_cast<CFDictionaryRef>( + ::CFDictionaryGetValue(dict.get(), uuid_cfstr.get())); + } + + // Check to see if we have the file on the local filesystem. + if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) { + ModuleSpec exe_spec; + exe_spec.GetFileSpec() = module_spec.GetFileSpec(); + exe_spec.GetUUID() = module_spec.GetUUID(); + ModuleSP module_sp; + module_sp.reset(new Module(exe_spec)); + if (module_sp && module_sp->GetObjectFile() && + module_sp->MatchesModuleSpec(exe_spec)) { + success = true; + return_module_spec.GetFileSpec() = module_spec.GetFileSpec(); + LLDB_LOGF(log, "using original binary filepath %s for UUID %s", + module_spec.GetFileSpec().GetPath().c_str(), + uuid->GetAsString().c_str()); + ++items_found; + } + } + + // Check if the requested image is in our shared cache. + if (!success) { + SharedCacheImageInfo image_info = HostInfo::GetSharedCacheImageInfo( + module_spec.GetFileSpec().GetPath()); + + // If we found it and it has the correct UUID, let's proceed with + // creating a module from the memory contents. + if (image_info.uuid && (!module_spec.GetUUID() || + module_spec.GetUUID() == image_info.uuid)) { + success = true; + return_module_spec.GetFileSpec() = module_spec.GetFileSpec(); + LLDB_LOGF(log, + "using binary from shared cache for filepath %s for " + "UUID %s", + module_spec.GetFileSpec().GetPath().c_str(), + uuid->GetAsString().c_str()); + ++items_found; + } + } + + // Use the DBGSymbolRichExecutable filepath if present + if (!success && uuid_dict) { + CFStringRef exec_cf_path = + static_cast<CFStringRef>(::CFDictionaryGetValue( + uuid_dict, CFSTR("DBGSymbolRichExecutable"))); + if (exec_cf_path && ::CFStringGetFileSystemRepresentation( + exec_cf_path, path, sizeof(path))) { + LLDB_LOGF(log, "plist bundle has exec path of %s for UUID %s", + path, uuid->GetAsString().c_str()); + ++items_found; + FileSpec exec_filespec(path); + if (path[0] == '~') + FileSystem::Instance().Resolve(exec_filespec); + if (FileSystem::Instance().Exists(exec_filespec)) { + success = true; + return_module_spec.GetFileSpec() = exec_filespec; + } + } + } + + // Look next to the dSYM for the binary file. + if (!success) { + if (::CFURLGetFileSystemRepresentation( + dsym_url.get(), true, (UInt8 *)path, sizeof(path) - 1)) { + char *dsym_extension_pos = ::strstr(path, ".dSYM"); + if (dsym_extension_pos) { + *dsym_extension_pos = '\0'; + LLDB_LOGF(log, + "Looking for executable binary next to dSYM " + "bundle with name with name %s", + path); + FileSpec file_spec(path); + FileSystem::Instance().Resolve(file_spec); + ModuleSpecList module_specs; + ModuleSpec matched_module_spec; + using namespace llvm::sys::fs; + switch (get_file_type(file_spec.GetPath())) { + + case file_type::directory_file: // Bundle directory? + { + CFCBundle bundle(path); + CFCReleaser<CFURLRef> bundle_exe_url( + bundle.CopyExecutableURL()); + if (bundle_exe_url.get()) { + if (::CFURLGetFileSystemRepresentation(bundle_exe_url.get(), + true, (UInt8 *)path, + sizeof(path) - 1)) { + FileSpec bundle_exe_file_spec(path); + FileSystem::Instance().Resolve(bundle_exe_file_spec); + if (ObjectFile::GetModuleSpecifications( + bundle_exe_file_spec, 0, 0, module_specs) && + module_specs.FindMatchingModuleSpec( + module_spec, matched_module_spec)) + + { + ++items_found; + return_module_spec.GetFileSpec() = bundle_exe_file_spec; + LLDB_LOGF(log, + "Executable binary %s next to dSYM is " + "compatible; using", + path); + } + } + } + } break; + + case file_type::fifo_file: // Forget pipes + case file_type::socket_file: // We can't process socket files + case file_type::file_not_found: // File doesn't exist... + case file_type::status_error: + break; + + case file_type::type_unknown: + case file_type::regular_file: + case file_type::symlink_file: + case file_type::block_file: + case file_type::character_file: + if (ObjectFile::GetModuleSpecifications(file_spec, 0, 0, + module_specs) && + module_specs.FindMatchingModuleSpec(module_spec, + matched_module_spec)) + + { + ++items_found; + return_module_spec.GetFileSpec() = file_spec; + LLDB_LOGF(log, + "Executable binary %s next to dSYM is " + "compatible; using", + path); + } + break; + } + } + } + } + } + } + } + } + + if (items_found) + return return_module_spec; + + return {}; +} diff --git a/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.h b/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.h new file mode 100644 index 0000000000000..a7641b28c0dc8 --- /dev/null +++ b/lldb/source/Plugins/SymbolLocator/DebugSymbols/SymbolLocatorDebugSymbols.h @@ -0,0 +1,44 @@ +//===-- SymbolLocatorDebugSymbols.h -----------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEBUGSYMBOLS_SYMBOLLOCATORDEBUGSYMBOLS_H +#define LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEBUGSYMBOLS_SYMBOLLOCATORDEBUGSYMBOLS_H + +#include "lldb/Symbol/SymbolLocator.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class SymbolLocatorDebugSymbols : public SymbolLocator { +public: + SymbolLocatorDebugSymbols(); + + static void Initialize(); + static void Terminate(); + + static llvm::StringRef GetPluginNameStatic() { return "DebugSymbols"; } + static llvm::StringRef GetPluginDescriptionStatic(); + + static lldb_private::SymbolLocator *CreateInstance(); + + /// PluginInterface protocol. + /// \{ + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + /// \} + + // Locate the executable file given a module specification. + // + // Locating the file should happen only on the local computer or using the + // current computers global settings. + static std::optional<ModuleSpec> + LocateExecutableObjectFile(const ModuleSpec &module_spec); +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEBUGSYMBOLS_SYMBOLLOCATORDEBUGSYMBOLS_H diff --git a/lldb/source/Plugins/SymbolLocator/Default/CMakeLists.txt b/lldb/source/Plugins/SymbolLocator/Default/CMakeLists.txt new file mode 100644 index 0000000000000..6d1d300d0ca9d --- /dev/null +++ b/lldb/source/Plugins/SymbolLocator/Default/CMakeLists.txt @@ -0,0 +1,8 @@ +add_lldb_library(lldbPluginSymbolLocatorDefault PLUGIN + SymbolLocatorDefault.cpp + + LINK_LIBS + lldbCore + lldbHost + lldbSymbol + ) diff --git a/lldb/source/Plugins/SymbolLocator/Default/SymbolLocatorDefault.cpp b/lldb/source/Plugins/SymbolLocator/Default/SymbolLocatorDefault.cpp new file mode 100644 index 0000000000000..4ccca5ca0f6a1 --- /dev/null +++ b/lldb/source/Plugins/SymbolLocator/Default/SymbolLocatorDefault.cpp @@ -0,0 +1,90 @@ +//===-- SymbolLocatorDefault.cpp ------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "SymbolLocatorDefault.h" + +#include <cstring> +#include <optional> + +#include "Plugins/ObjectFile/wasm/ObjectFileWasm.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Progress.h" +#include "lldb/Core/Section.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/Host.h" +#include "lldb/Symbol/LocateSymbolFile.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/DataBuffer.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/Timer.h" +#include "lldb/Utility/UUID.h" + +#include "llvm/ADT/SmallSet.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/ThreadPool.h" + +// From MacOSX system header "mach/machine.h" +typedef int cpu_type_t; +typedef int cpu_subtype_t; + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(SymbolLocatorDefault) + +SymbolLocatorDefault::SymbolLocatorDefault() : SymbolLocator() {} + +void SymbolLocatorDefault::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance, + LocateExecutableObjectFile); +} + +void SymbolLocatorDefault::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +llvm::StringRef SymbolLocatorDefault::GetPluginDescriptionStatic() { + return "Default symbol locator."; +} + +SymbolLocator *SymbolLocatorDefault::CreateInstance() { + return new SymbolLocatorDefault(); +} + +std::optional<ModuleSpec> SymbolLocatorDefault::LocateExecutableObjectFile( + const ModuleSpec &module_spec) { + const FileSpec &exec_fspec = module_spec.GetFileSpec(); + const ArchSpec *arch = module_spec.GetArchitecturePtr(); + const UUID *uuid = module_spec.GetUUIDPtr(); + LLDB_SCOPED_TIMERF( + "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)", + exec_fspec ? exec_fspec.GetFilename().AsCString("<NULL>") : "<NULL>", + arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid); + + ModuleSpecList module_specs; + ModuleSpec matched_module_spec; + if (exec_fspec && + ObjectFile::GetModuleSpecifications(exec_fspec, 0, 0, module_specs) && + module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) { + ModuleSpec result; + result.GetFileSpec() = exec_fspec; + return result; + } + + return {}; +} diff --git a/lldb/source/Plugins/SymbolLocator/Default/SymbolLocatorDefault.h b/lldb/source/Plugins/SymbolLocator/Default/SymbolLocatorDefault.h new file mode 100644 index 0000000000000..b1bb58ec29804 --- /dev/null +++ b/lldb/source/Plugins/SymbolLocator/Default/SymbolLocatorDefault.h @@ -0,0 +1,44 @@ +//===-- SymbolLocatorDefault.h ----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEFAULT_SYMBOLLOCATORDEFAULT_H +#define LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEFAULT_SYMBOLLOCATORDEFAULT_H + +#include "lldb/Symbol/SymbolLocator.h" +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class SymbolLocatorDefault : public SymbolLocator { +public: + SymbolLocatorDefault(); + + static void Initialize(); + static void Terminate(); + + static llvm::StringRef GetPluginNameStatic() { return "Default"; } + static llvm::StringRef GetPluginDescriptionStatic(); + + static lldb_private::SymbolLocator *CreateInstance(); + + /// PluginInterface protocol. + /// \{ + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + /// \} + + // Locate the executable file given a module specification. + // + // Locating the file should happen only on the local computer or using the + // current computers global settings. + static std::optional<ModuleSpec> + LocateExecutableObjectFile(const ModuleSpec &module_spec); +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_SYMBOLLOCATOR_DEFAULT_SYMBOLLOCATORDEFAULT_H diff --git a/lldb/source/Symbol/LocateSymbolFile.cpp b/lldb/source/Symbol/LocateSymbolFile.cpp index 66ee7589ac604..b23b53230a4ff 100644 --- a/lldb/source/Symbol/LocateSymbolFile.cpp +++ b/lldb/source/Symbol/LocateSymbolFile.cpp @@ -234,29 +234,6 @@ static FileSpec LocateExecutableSymbolFileDsym(const ModuleSpec &module_spec) { return dsym_module_spec.GetSymbolFileSpec(); } -ModuleSpec Symbols::LocateExecutableObjectFile(const ModuleSpec &module_spec) { - ModuleSpec result; - const FileSpec &exec_fspec = module_spec.GetFileSpec(); - const ArchSpec *arch = module_spec.GetArchitecturePtr(); - const UUID *uuid = module_spec.GetUUIDPtr(); - LLDB_SCOPED_TIMERF( - "LocateExecutableObjectFile (file = %s, arch = %s, uuid = %p)", - exec_fspec ? exec_fspec.GetFilename().AsCString("<NULL>") : "<NULL>", - arch ? arch->GetArchitectureName() : "<NULL>", (const void *)uuid); - - ModuleSpecList module_specs; - ModuleSpec matched_module_spec; - if (exec_fspec && - ObjectFile::GetModuleSpecifications(exec_fspec, 0, 0, module_specs) && - module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) { - result.GetFileSpec() = exec_fspec; - } else { - LocateMacOSXFilesUsingDebugSymbols(module_spec, result); - } - - return result; -} - // Keep "symbols.enable-external-lookup" description in sync with this function. FileSpec