https://github.com/da-viper updated https://github.com/llvm/llvm-project/pull/141773
>From 429c656be7e8176c1c4d6f7c4339b7c6d76fa56c Mon Sep 17 00:00:00 2001 From: Ebuka Ezike <yerimy...@gmail.com> Date: Wed, 28 May 2025 09:04:08 +0100 Subject: [PATCH] [lldb] Inital implementation of fetching source files used in modules. Rough implementation of a source locator plugin for LLDB. --- lldb/include/lldb/Core/PluginManager.h | 4 +++ lldb/include/lldb/lldb-private-interfaces.h | 2 ++ lldb/source/Core/PluginManager.cpp | 25 +++++++++++++-- lldb/source/Core/SourceManager.cpp | 26 +++++++++++++++ .../Debuginfod/SymbolLocatorDebuginfod.cpp | 32 ++++++++++++++++++- .../Debuginfod/SymbolLocatorDebuginfod.h | 7 ++++ 6 files changed, 93 insertions(+), 3 deletions(-) diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h index e2f709ecd2ff7..1cff17e8146a2 100644 --- a/lldb/include/lldb/Core/PluginManager.h +++ b/lldb/include/lldb/Core/PluginManager.h @@ -373,6 +373,7 @@ class PluginManager { SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file = nullptr, SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle = nullptr, + SymbolLocatorLocateSourceFile locate_source_file = nullptr, DebuggerInitializeCallback debugger_init_callback = nullptr); static bool UnregisterPlugin(SymbolLocatorCreateInstance create_callback); @@ -388,6 +389,9 @@ class PluginManager { const FileSpecList &default_search_paths, StatisticsMap &map); + static std::optional<FileSpec> LocateSourceFile(const ModuleSpec &module_spec, + const FileSpec &file_spec); + static bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, Status &error, bool force_lookup = true, diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h index d366dbd1d7832..7860d1ab639ed 100644 --- a/lldb/include/lldb/lldb-private-interfaces.h +++ b/lldb/include/lldb/lldb-private-interfaces.h @@ -97,6 +97,8 @@ typedef std::optional<FileSpec> (*SymbolLocatorFindSymbolFileInBundle)( const FileSpec &dsym_bundle_fspec, const UUID *uuid, const ArchSpec *arch); typedef std::optional<FileSpec> (*SymbolLocatorLocateExecutableSymbolFile)( const ModuleSpec &module_spec, const FileSpecList &default_search_paths); +typedef std::optional<FileSpec> (*SymbolLocatorLocateSourceFile)( + const ModuleSpec &module_spec, const FileSpec &file_spec); typedef bool (*SymbolLocatorDownloadObjectAndSymbolFile)( ModuleSpec &module_spec, Status &error, bool force_lookup, bool copy_executable); diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp index de815e6308838..5b4044f3c208c 100644 --- a/lldb/source/Core/PluginManager.cpp +++ b/lldb/source/Core/PluginManager.cpp @@ -1173,18 +1173,21 @@ struct SymbolLocatorInstance SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file, SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file, SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle, + SymbolLocatorLocateSourceFile locate_source_file, DebuggerInitializeCallback debugger_init_callback) : PluginInstance<SymbolLocatorCreateInstance>( name, description, create_callback, debugger_init_callback), locate_executable_object_file(locate_executable_object_file), locate_executable_symbol_file(locate_executable_symbol_file), download_object_symbol_file(download_object_symbol_file), - find_symbol_file_in_bundle(find_symbol_file_in_bundle) {} + find_symbol_file_in_bundle(find_symbol_file_in_bundle), + locate_source_file(locate_source_file) {} SymbolLocatorLocateExecutableObjectFile locate_executable_object_file; SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file; SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file; SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle; + SymbolLocatorLocateSourceFile locate_source_file; }; typedef PluginInstances<SymbolLocatorInstance> SymbolLocatorInstances; @@ -1200,11 +1203,12 @@ bool PluginManager::RegisterPlugin( SymbolLocatorLocateExecutableSymbolFile locate_executable_symbol_file, SymbolLocatorDownloadObjectAndSymbolFile download_object_symbol_file, SymbolLocatorFindSymbolFileInBundle find_symbol_file_in_bundle, + SymbolLocatorLocateSourceFile locate_source_file, DebuggerInitializeCallback debugger_init_callback) { return GetSymbolLocatorInstances().RegisterPlugin( name, description, create_callback, locate_executable_object_file, locate_executable_symbol_file, download_object_symbol_file, - find_symbol_file_in_bundle, debugger_init_callback); + find_symbol_file_in_bundle, locate_source_file, debugger_init_callback); } bool PluginManager::UnregisterPlugin( @@ -1258,6 +1262,23 @@ FileSpec PluginManager::LocateExecutableSymbolFile( return {}; } +std::optional<FileSpec> +PluginManager::LocateSourceFile(const ModuleSpec &module_spec, + const FileSpec &file_spec) { + auto instances = GetSymbolLocatorInstances().GetSnapshot(); + for (auto &instance : instances) { + if (instance.locate_source_file) { + std::optional<FileSpec> result; + { + result = instance.locate_source_file(module_spec, file_spec); + } + if (result) + return *result; + } + } + return std::nullopt; +} + bool PluginManager::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, Status &error, bool force_lookup, diff --git a/lldb/source/Core/SourceManager.cpp b/lldb/source/Core/SourceManager.cpp index f786866a18137..48e2b30911323 100644 --- a/lldb/source/Core/SourceManager.cpp +++ b/lldb/source/Core/SourceManager.cpp @@ -15,6 +15,7 @@ #include "lldb/Core/Highlighter.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" +#include "lldb/Core/PluginManager.h" #include "lldb/Host/FileSystem.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" @@ -542,6 +543,31 @@ void SourceManager::File::CommonInitializer(SupportFileSP support_file_sp, *remapped, support_file_sp->GetChecksum())); } } + // Try Plugins + { + FileSpec file_spec = GetSupportFile()->GetSpecOnly(); + if (!FileSystem::Instance().Exists(file_spec)) { + + bool check_inlines = false; + SymbolContextList sc_list; + size_t num_matches = + target_sp->GetImages().ResolveSymbolContextForFilePath( + file_spec.GetFilename().AsCString(), 0, check_inlines, + eSymbolContextModule | eSymbolContextCompUnit, sc_list); + if (num_matches > 0) { + SymbolContext sc; + sc_list.GetContextAtIndex(0, sc); + ModuleSpec module_spec; + module_spec.GetUUID() = sc.module_sp->GetUUID(); + const std::optional<FileSpec> result = + PluginManager::LocateSourceFile(module_spec, file_spec); + if (result.has_value()) { + SetSupportFile(std::make_shared<SupportFile>( + *result, support_file_sp->GetChecksum())); + } + } + } + } } } diff --git a/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp b/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp index f9aa6b1a98765..6aca8a4e052c8 100644 --- a/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp +++ b/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.cpp @@ -112,7 +112,7 @@ void SymbolLocatorDebuginfod::Initialize() { PluginManager::RegisterPlugin( GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, LocateExecutableObjectFile, LocateExecutableSymbolFile, nullptr, - nullptr, SymbolLocatorDebuginfod::DebuggerInitialize); + nullptr, LocateSourceFile, SymbolLocatorDebuginfod::DebuggerInitialize); llvm::HTTPClient::initialize(); }); } @@ -210,3 +210,33 @@ std::optional<FileSpec> SymbolLocatorDebuginfod::LocateExecutableSymbolFile( const ModuleSpec &module_spec, const FileSpecList &default_search_paths) { return GetFileForModule(module_spec, llvm::getDebuginfodDebuginfoUrlPath); } + +std::optional<FileSpec> +SymbolLocatorDebuginfod::LocateSourceFile(const ModuleSpec &module_spec, + const FileSpec &file_spec) { + + const UUID &module_uuid = module_spec.GetUUID(); + const std::string file_path = file_spec.GetPath(); + // Don't bother if we don't have a path or valid UUID, Debuginfod isn't + // available, or if the 'symbols.enable-external-lookup' setting is false. + if (file_path.empty() || !module_uuid.IsValid() || + !llvm::canUseDebuginfod() || + !ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) + return {}; + + llvm::SmallVector<llvm::StringRef> debuginfod_urls = + llvm::getDefaultDebuginfodUrls(); + + llvm::object::BuildID build_id(module_uuid.GetBytes()); + + llvm::Expected<std::string> result = + llvm::getCachedOrDownloadSource(build_id, file_path); + if (result) + return FileSpec(*result); + + Log *log = GetLog(LLDBLog::Source); + auto err_message = llvm::toString(result.takeError()); + LLDB_LOGV(log, "Debuginfod failed to download source file {0} with error {1}", + file_path, err_message); + return std::nullopt; +} diff --git a/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.h b/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.h index 0ea79fa1df2a5..a4ea798a8af6b 100644 --- a/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.h +++ b/lldb/source/Plugins/SymbolLocator/Debuginfod/SymbolLocatorDebuginfod.h @@ -47,6 +47,13 @@ class SymbolLocatorDebuginfod : public SymbolLocator { static std::optional<FileSpec> LocateExecutableSymbolFile(const ModuleSpec &module_spec, const FileSpecList &default_search_paths); + + // Locate the source file given a module specification and file specification. + // + // Locating the file should happen only on the local computer or using the + // current computers global settings. + static std::optional<FileSpec> LocateSourceFile(const ModuleSpec &module_spec, + const FileSpec &file_spec); }; } // namespace lldb_private _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits