https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/215392
>From 7b008e6ff59e1711bb231e401f17117586b4d2f8 Mon Sep 17 00:00:00 2001 From: Jonas Devlieghere <[email protected]> Date: Mon, 10 Aug 2026 12:42:19 -0700 Subject: [PATCH] [lldb] Consult the platform before the symbol locator plugins (NFC) A symbol locator plugin has no Platform to consult, so a platform that knows where its binaries live cannot take part in a search. The only way to reach one is Platform::GetSharedModule, which also creates the module and registers it, so the lookup cannot be reused by a caller that wants to search for many binaries before creating any. Add a hook that only answers where the files are. An answer ends the search, so an override owns what the plugins would otherwise have been asked for. No platform overrides it yet. A follow-up moves PlatformDarwinKernel's kext and kernel index lookups behind it. Assisted-by: Claude --- lldb/include/lldb/Symbol/SymbolLocator.h | 4 ++ lldb/include/lldb/Target/Platform.h | 18 ++++++ lldb/source/Core/DynamicLoader.cpp | 1 + lldb/source/Symbol/SymbolLocator.cpp | 10 +++ lldb/unittests/Symbol/SymbolLocatorTest.cpp | 70 +++++++++++++++++++++ 5 files changed, 103 insertions(+) diff --git a/lldb/include/lldb/Symbol/SymbolLocator.h b/lldb/include/lldb/Symbol/SymbolLocator.h index b1e01710cb1c3..5fc9c161af50a 100644 --- a/lldb/include/lldb/Symbol/SymbolLocator.h +++ b/lldb/include/lldb/Symbol/SymbolLocator.h @@ -42,6 +42,10 @@ class SymbolLocator : public PluginInterface { /// What to look for. ModuleSpec module_spec; + /// A platform that may know where the binary is. The locator plugins have + /// no Platform of their own to consult. + lldb::PlatformSP platform; + /// Allow contacting an external symbol server when the local searches come /// up empty. bool external_lookup = false; diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h index ea54a3c20d588..ede478fb9affd 100644 --- a/lldb/include/lldb/Target/Platform.h +++ b/lldb/include/lldb/Target/Platform.h @@ -329,6 +329,24 @@ class Platform : public PluginInterface { const ModuleSpec &module_spec, Target &target, lldb::ModuleSP &module_sp, llvm::SmallVectorImpl<lldb::ModuleSP> *old_modules, bool *did_create_ptr); + /// Find a module's files on this host. + /// + /// The symbol locator plugins have no Platform to consult, so a platform + /// that knows where its binaries live answers here instead. + /// + /// An answer ends the search, so an override owns what the plugins would + /// otherwise have been asked for: the files it names have to exist, and have + /// to be the ones \a module_spec describes. + /// + /// \return + /// Where the files are, or std::nullopt if this platform has nothing to + /// say about this module. + virtual std::optional<ModuleSpec> + FindModuleFiles(const ModuleSpec &module_spec, + const FileSpecList &search_paths, StatisticsMap &statistics) { + return std::nullopt; + } + void CallLocateModuleCallbackIfSet(const ModuleSpec &module_spec, lldb::ModuleSP &module_sp, FileSpec &symbol_file_spec, diff --git a/lldb/source/Core/DynamicLoader.cpp b/lldb/source/Core/DynamicLoader.cpp index 4f9023976b95a..a948fefa4c83e 100644 --- a/lldb/source/Core/DynamicLoader.cpp +++ b/lldb/source/Core/DynamicLoader.cpp @@ -271,6 +271,7 @@ static void SearchForBinary(Target &target, DynamicLoader::BinarySpec &bin_spec, // Search for the binary and its symbols. SymbolLocator::Request request; request.module_spec = module_spec; + request.platform = target.GetPlatform(); request.external_lookup = bin_spec.force_symbol_search; llvm::Expected<SymbolLocator::Result> located = diff --git a/lldb/source/Symbol/SymbolLocator.cpp b/lldb/source/Symbol/SymbolLocator.cpp index 3b3e531e14521..4b8bc7405fdbb 100644 --- a/lldb/source/Symbol/SymbolLocator.cpp +++ b/lldb/source/Symbol/SymbolLocator.cpp @@ -12,6 +12,7 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" +#include "lldb/Target/Platform.h" #include "llvm/ADT/SmallSet.h" #include "llvm/Support/ThreadPool.h" @@ -37,6 +38,15 @@ SymbolLocator::Locate(const Request &request, ModuleSpec &module_spec = result.module_spec; module_spec = request.module_spec; + // The locator plugins have no Platform to consult, so ask it here. + if (request.platform) { + if (std::optional<ModuleSpec> found = request.platform->FindModuleFiles( + module_spec, search_paths, result.statistics)) { + result.module_spec = *found; + return result; + } + } + // Can lldb's symbol and executable location schemes find them locally? module_spec.GetSymbolFileSpec() = PluginManager::LocateExecutableSymbolFile( module_spec, search_paths, result.statistics); diff --git a/lldb/unittests/Symbol/SymbolLocatorTest.cpp b/lldb/unittests/Symbol/SymbolLocatorTest.cpp index 58a84b30fadbf..d86808702da5e 100644 --- a/lldb/unittests/Symbol/SymbolLocatorTest.cpp +++ b/lldb/unittests/Symbol/SymbolLocatorTest.cpp @@ -10,6 +10,7 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" +#include "lldb/Target/Platform.h" #include "lldb/Utility/FileSpecList.h" #include "llvm/Support/VirtualFileSystem.h" @@ -70,6 +71,41 @@ bool DownloadObjectAndSymbolFile(ModuleSpec &, Status &error, bool force_lookup, SymbolLocator *CreateSymbolLocator() { return nullptr; } +/// A platform that answers out of an index of its own, the way +/// PlatformDarwinKernel answers for kexts. +class IndexedPlatform : public Platform { +public: + IndexedPlatform() : Platform(/*is_host_platform=*/false) {} + + llvm::StringRef GetPluginName() override { return "indexed"; } + llvm::StringRef GetDescription() override { return "test platform"; } + std::vector<ArchSpec> GetSupportedArchitectures(const ArchSpec &) override { + return {}; + } + lldb::ProcessSP Attach(ProcessAttachInfo &, Debugger &, Target *, + Status &) override { + return nullptr; + } + void CalculateTrapHandlerSymbolNames() override {} + UserIDResolver &GetUserIDResolver() override { + return UserIDResolver::GetNoopResolver(); + } + + std::optional<ModuleSpec> FindModuleFiles(const ModuleSpec &spec, + const FileSpecList &, + StatisticsMap &) override { + ++find_module_files_calls; + if (!m_answer) + return {}; + ModuleSpec found(spec); + found.GetFileSpec() = *m_answer; + return found; + } + + std::optional<FileSpec> m_answer; + unsigned find_module_files_calls = 0; +}; + class SymbolLocatorTest : public testing::Test { public: SymbolLocatorTest() @@ -199,3 +235,37 @@ TEST_F(SymbolLocatorTest, AnErrnoFromTheSymbolServerIsNotAPlainMiss) { EXPECT_FALSE(error.isA<SymbolLocator::NotFound>()); llvm::consumeError(std::move(error)); } + +TEST_F(SymbolLocatorTest, ThePlatformAnswersBeforeThePlugins) { + auto platform = std::make_shared<IndexedPlatform>(); + platform->m_answer = m_binary; + + SymbolLocator::Request request; + request.platform = platform; + + llvm::Expected<SymbolLocator::Result> result = + SymbolLocator::Locate(request, FileSpecList()); + + ASSERT_THAT_EXPECTED(result, llvm::Succeeded()); + EXPECT_EQ(1u, platform->find_module_files_calls); + EXPECT_EQ(m_binary, result->module_spec.GetFileSpec()); + EXPECT_FALSE(g_calls.located_symbol_file); + EXPECT_FALSE(g_calls.located_object_file); + EXPECT_FALSE(g_calls.downloaded); +} + +TEST_F(SymbolLocatorTest, ThePluginsRunWhenThePlatformHasNothingToSay) { + auto platform = std::make_shared<IndexedPlatform>(); + platform->m_answer = std::nullopt; + g_object_file = m_binary; + + SymbolLocator::Request request; + request.platform = platform; + + llvm::Expected<SymbolLocator::Result> result = + SymbolLocator::Locate(request, FileSpecList()); + + ASSERT_THAT_EXPECTED(result, llvm::Succeeded()); + EXPECT_EQ(1u, platform->find_module_files_calls); + EXPECT_TRUE(g_calls.located_object_file); +} _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
