[Lldb-commits] [lldb] [WIP] [lldb] Add fetching of source files used in modules. (PR #141773)
Ebuka Ezike via lldb-commits
lldb-commits at lists.llvm.org
Wed May 28 07:28:17 PDT 2025
https://github.com/da-viper created https://github.com/llvm/llvm-project/pull/141773
Rough implementation of a source locator plugin for LLDB.
>From c8ca502eeed9fe026c39c0f34acdbcca7b3f7f30 Mon Sep 17 00:00:00 2001
From: Ebuka Ezike <yerimyah1 at 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/cmake/modules/LLDBConfig.cmake | 2 +-
lldb/include/lldb/Core/PluginManager.h | 15 ++++-
lldb/include/lldb/Core/SourceLocator.h | 18 +++++
lldb/include/lldb/lldb-private-interfaces.h | 4 ++
lldb/source/Core/CMakeLists.txt | 1 +
lldb/source/Core/PluginManager.cpp | 55 ++++++++++++++++
lldb/source/Core/SourceLocator.cpp | 9 +++
lldb/source/Core/SourceManager.cpp | 26 ++++++++
lldb/source/Plugins/CMakeLists.txt | 1 +
lldb/source/Plugins/SourceFile/CMakeLists.txt | 1 +
.../SourceFile/Debuginfod/CMakeLists.txt | 8 +++
.../Debuginfod/SourceLocatorDebuginfod.cpp | 66 +++++++++++++++++++
.../Debuginfod/SourceLocatorDebuginfod.h | 36 ++++++++++
13 files changed, 240 insertions(+), 2 deletions(-)
create mode 100644 lldb/include/lldb/Core/SourceLocator.h
create mode 100644 lldb/source/Core/SourceLocator.cpp
create mode 100644 lldb/source/Plugins/SourceFile/CMakeLists.txt
create mode 100644 lldb/source/Plugins/SourceFile/Debuginfod/CMakeLists.txt
create mode 100644 lldb/source/Plugins/SourceFile/Debuginfod/SourceLocatorDebuginfod.cpp
create mode 100644 lldb/source/Plugins/SourceFile/Debuginfod/SourceLocatorDebuginfod.h
diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake
index cfd626c9358a1..54d1c67e1b671 100644
--- a/lldb/cmake/modules/LLDBConfig.cmake
+++ b/lldb/cmake/modules/LLDBConfig.cmake
@@ -57,7 +57,7 @@ add_optional_dependency(LLDB_ENABLE_CURSES "Enable curses support in LLDB" Curse
add_optional_dependency(LLDB_ENABLE_LZMA "Enable LZMA compression support in LLDB" LibLZMA LIBLZMA_FOUND)
add_optional_dependency(LLDB_ENABLE_LUA "Enable Lua scripting support in LLDB" LuaAndSwig LUAANDSWIG_FOUND)
add_optional_dependency(LLDB_ENABLE_PYTHON "Enable Python scripting support in LLDB" PythonAndSwig PYTHONANDSWIG_FOUND)
-add_optional_dependency(LLDB_ENABLE_LIBXML2 "Enable Libxml 2 support in LLDB" LibXml2 LIBXML2_FOUND VERSION 2.8)
+add_optional_dependency(LLDB_ENABLE_LIBXML2 "Enable Libxml 2 support in LLDB" LibXml2 LIBXML2_FOUND)
add_optional_dependency(LLDB_ENABLE_FBSDVMCORE "Enable libfbsdvmcore support in LLDB" FBSDVMCore FBSDVMCore_FOUND QUIET)
option(LLDB_USE_ENTITLEMENTS "When codesigning, use entitlements if available" ON)
diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h
index e2f709ecd2ff7..7008dfd26aa9e 100644
--- a/lldb/include/lldb/Core/PluginManager.h
+++ b/lldb/include/lldb/Core/PluginManager.h
@@ -362,6 +362,20 @@ class PluginManager {
static SymbolVendorCreateInstance
GetSymbolVendorCreateCallbackAtIndex(uint32_t idx);
+ // SourceLocator
+ static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description,
+ SourceLocatorCreateInstance create_callback,
+ SourceLocatorLocateSourceFile locate_source_file);
+
+ static bool UnregisterPlugin(SourceLocatorCreateInstance create_callback);
+
+ static std::optional<FileSpec> LocateSourceFile(const ModuleSpec &module_spec,
+ const FileSpec &file_spec);
+
+ static bool CreateSettingForSourceLocatorPlugin(
+ Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
+ llvm::StringRef description, bool is_global_property);
+
// SymbolLocator
static bool RegisterPlugin(
llvm::StringRef name, llvm::StringRef description,
@@ -382,7 +396,6 @@ class PluginManager {
static ModuleSpec LocateExecutableObjectFile(const ModuleSpec &module_spec,
StatisticsMap &map);
-
static FileSpec
LocateExecutableSymbolFile(const ModuleSpec &module_spec,
const FileSpecList &default_search_paths,
diff --git a/lldb/include/lldb/Core/SourceLocator.h b/lldb/include/lldb/Core/SourceLocator.h
new file mode 100644
index 0000000000000..e95dbb999dd12
--- /dev/null
+++ b/lldb/include/lldb/Core/SourceLocator.h
@@ -0,0 +1,18 @@
+//===-- SourceLocationSpec.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_UTILITY_SOURCELOCATIOR_H
+#define LLDB_UTILITY_SOURCELOCATIOR_H
+
+#include "lldb/Core/PluginInterface.h"
+
+namespace lldb_private {
+class SourceLocator : public PluginInterface {};
+} // namespace lldb_private
+
+#endif // LLDB_UTILITY_SOURCELOCATIOR_H
diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h
index d366dbd1d7832..423e9989046f5 100644
--- a/lldb/include/lldb/lldb-private-interfaces.h
+++ b/lldb/include/lldb/lldb-private-interfaces.h
@@ -24,6 +24,7 @@ class Value;
} // namespace llvm
namespace lldb_private {
+class SourceLocator;
class ScriptedInterfaceUsages;
typedef lldb::ABISP (*ABICreateInstance)(lldb::ProcessSP process_sp,
const ArchSpec &arch);
@@ -85,6 +86,9 @@ typedef lldb::RegisterTypeBuilderSP (*RegisterTypeBuilderCreateInstance)(
Target &target);
typedef lldb::ScriptInterpreterSP (*ScriptInterpreterCreateInstance)(
Debugger &debugger);
+typedef SourceLocator *(*SourceLocatorCreateInstance)();
+typedef std::optional<FileSpec> (*SourceLocatorLocateSourceFile)(
+ const ModuleSpec &module_spec, const FileSpec &file_spec);
typedef SymbolFile *(*SymbolFileCreateInstance)(lldb::ObjectFileSP objfile_sp);
typedef SymbolVendor *(*SymbolVendorCreateInstance)(
const lldb::ModuleSP &module_sp,
diff --git a/lldb/source/Core/CMakeLists.txt b/lldb/source/Core/CMakeLists.txt
index c4c442dcb2043..ce8e4f2ac0b9d 100644
--- a/lldb/source/Core/CMakeLists.txt
+++ b/lldb/source/Core/CMakeLists.txt
@@ -51,6 +51,7 @@ add_lldb_library(lldbCore NO_PLUGIN_DEPENDENCIES
SearchFilter.cpp
Section.cpp
SourceLocationSpec.cpp
+ SourceLocator.cpp
SourceManager.cpp
StreamAsynchronousIO.cpp
Telemetry.cpp
diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp
index de815e6308838..f8f558315041b 100644
--- a/lldb/source/Core/PluginManager.cpp
+++ b/lldb/source/Core/PluginManager.cpp
@@ -1162,6 +1162,36 @@ PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
return GetSymbolVendorInstances().GetCallbackAtIndex(idx);
}
+#pragma mark SourceLocator
+
+struct SourceLocatorInstance
+ : public PluginInstance<SourceLocatorCreateInstance> {
+ SourceLocatorInstance(llvm::StringRef name, llvm::StringRef description,
+ CallbackType create_callback,
+ SourceLocatorLocateSourceFile locate_source_file)
+ : PluginInstance(name, description, create_callback),
+ locate_source_file(locate_source_file) {}
+ SourceLocatorLocateSourceFile locate_source_file;
+};
+typedef PluginInstances<SourceLocatorInstance> SourceLocatorInstances;
+
+static SourceLocatorInstances &GetSourceLocatorInstances() {
+ static SourceLocatorInstances g_instances;
+ return g_instances;
+}
+bool PluginManager::RegisterPlugin(
+ llvm::StringRef name, llvm::StringRef description,
+ SourceLocatorCreateInstance create_callback,
+ SourceLocatorLocateSourceFile locate_source_file) {
+ return GetSourceLocatorInstances().RegisterPlugin(
+ name, description, create_callback, locate_source_file);
+}
+
+bool PluginManager::UnregisterPlugin(
+ SourceLocatorCreateInstance create_callback) {
+ return GetSourceLocatorInstances().UnregisterPlugin(create_callback);
+}
+
#pragma mark SymbolLocator
struct SymbolLocatorInstance
@@ -1237,6 +1267,22 @@ PluginManager::LocateExecutableObjectFile(const ModuleSpec &module_spec,
return {};
}
+std::optional<FileSpec>
+PluginManager::LocateSourceFile(const ModuleSpec &module_spec,
+ const FileSpec &file_spec) {
+ auto instances = GetSourceLocatorInstances().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;
+}
FileSpec PluginManager::LocateExecutableSymbolFile(
const ModuleSpec &module_spec, const FileSpecList &default_search_paths,
StatisticsMap &map) {
@@ -1820,6 +1866,7 @@ static constexpr llvm::StringLiteral kPlatformPluginName("platform");
static constexpr llvm::StringLiteral kProcessPluginName("process");
static constexpr llvm::StringLiteral kTracePluginName("trace");
static constexpr llvm::StringLiteral kObjectFilePluginName("object-file");
+static constexpr llvm::StringLiteral kSourceFilePluginName("source-file");
static constexpr llvm::StringLiteral kSymbolFilePluginName("symbol-file");
static constexpr llvm::StringLiteral kSymbolLocatorPluginName("symbol-locator");
static constexpr llvm::StringLiteral kJITLoaderPluginName("jit-loader");
@@ -1885,6 +1932,14 @@ bool PluginManager::CreateSettingForSymbolLocatorPlugin(
properties_sp, description, is_global_property);
}
+bool PluginManager::CreateSettingForSourceLocatorPlugin(
+ Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
+ llvm::StringRef description, bool is_global_property) {
+ return CreateSettingForPlugin(debugger, kSymbolLocatorPluginName,
+ "Settings for source locator plugins",
+ properties_sp, description, is_global_property);
+}
+
bool PluginManager::CreateSettingForTracePlugin(
Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
llvm::StringRef description, bool is_global_property) {
diff --git a/lldb/source/Core/SourceLocator.cpp b/lldb/source/Core/SourceLocator.cpp
new file mode 100644
index 0000000000000..47729ce111b93
--- /dev/null
+++ b/lldb/source/Core/SourceLocator.cpp
@@ -0,0 +1,9 @@
+//===-- SourceLocator.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 "lldb/Core/SourceLocator.h"
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/CMakeLists.txt b/lldb/source/Plugins/CMakeLists.txt
index 854f589f45ae0..91a4cebdff62b 100644
--- a/lldb/source/Plugins/CMakeLists.txt
+++ b/lldb/source/Plugins/CMakeLists.txt
@@ -17,6 +17,7 @@ add_subdirectory(Process)
add_subdirectory(REPL)
add_subdirectory(RegisterTypeBuilder)
add_subdirectory(ScriptInterpreter)
+add_subdirectory(SourceFile)
add_subdirectory(StructuredData)
add_subdirectory(SymbolFile)
add_subdirectory(SystemRuntime)
diff --git a/lldb/source/Plugins/SourceFile/CMakeLists.txt b/lldb/source/Plugins/SourceFile/CMakeLists.txt
new file mode 100644
index 0000000000000..cd3bf188d43db
--- /dev/null
+++ b/lldb/source/Plugins/SourceFile/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(Debuginfod)
\ No newline at end of file
diff --git a/lldb/source/Plugins/SourceFile/Debuginfod/CMakeLists.txt b/lldb/source/Plugins/SourceFile/Debuginfod/CMakeLists.txt
new file mode 100644
index 0000000000000..877dbdb0e330e
--- /dev/null
+++ b/lldb/source/Plugins/SourceFile/Debuginfod/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_lldb_library(lldbPluginSourceLocatorDebuginfod PLUGIN
+ SourceLocatorDebuginfod.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbHost
+ LLVMDebuginfod
+)
diff --git a/lldb/source/Plugins/SourceFile/Debuginfod/SourceLocatorDebuginfod.cpp b/lldb/source/Plugins/SourceFile/Debuginfod/SourceLocatorDebuginfod.cpp
new file mode 100644
index 0000000000000..607e2717e6c58
--- /dev/null
+++ b/lldb/source/Plugins/SourceFile/Debuginfod/SourceLocatorDebuginfod.cpp
@@ -0,0 +1,66 @@
+//
+// Created by da-viper on 26/05/25.
+//
+
+#include "SourceLocatorDebuginfod.h"
+
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Interpreter/OptionValueString.h"
+#include "lldb/Utility/Args.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+#include <lldb/Core/PluginManager.h>
+#include <llvm/Debuginfod/Debuginfod.h>
+#include <llvm/Debuginfod/HTTPClient.h>
+
+LLDB_PLUGIN_DEFINE(SourceLocatorDebuginfod)
+
+namespace lldb_private {
+void SourceLocatorDebuginfod::Initialize() {
+ static llvm::once_flag g_once_flag;
+
+ llvm::call_once(g_once_flag, [] {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance,
+ LocateSourceFile);
+ llvm::HTTPClient::initialize();
+ });
+}
+void SourceLocatorDebuginfod::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+ llvm::HTTPClient::cleanup();
+}
+
+SourceLocator *SourceLocatorDebuginfod::CreateInstance() {
+ return new SourceLocatorDebuginfod();
+}
+std::optional<FileSpec>
+SourceLocatorDebuginfod::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;
+}
+} // namespace lldb_private
\ No newline at end of file
diff --git a/lldb/source/Plugins/SourceFile/Debuginfod/SourceLocatorDebuginfod.h b/lldb/source/Plugins/SourceFile/Debuginfod/SourceLocatorDebuginfod.h
new file mode 100644
index 0000000000000..36e9b7c27e5f3
--- /dev/null
+++ b/lldb/source/Plugins/SourceFile/Debuginfod/SourceLocatorDebuginfod.h
@@ -0,0 +1,36 @@
+//===-- SourceLocatorDebuginfod.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_SOURCELOCATOR_DEBUGINFOD_SOURCELOCATORDEBUGINFOD_H
+#define LLDB_SOURCE_PLUGINS_SOURCELOCATOR_DEBUGINFOD_SOURCELOCATORDEBUGINFOD_H
+
+#include "lldb/Core/SourceLocator.h"
+#include <lldb/Core/Debugger.h>
+namespace lldb_private {
+
+class SourceLocatorDebuginfod : public SourceLocator {
+public:
+ explicit SourceLocatorDebuginfod() = default;
+ static void Initialize();
+ static void Terminate();
+
+ static llvm::StringRef GetPluginNameStatic() { return "debuginfod-source"; };
+ static llvm::StringRef GetPluginDescriptionStatic() {
+ return "Debuginfod source locator";
+ };
+
+ static SourceLocator *CreateInstance();
+ // static SourceLoc
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+
+ static std::optional<FileSpec> LocateSourceFile(const ModuleSpec &module_spec,
+ const FileSpec &file_spec);
+};
+} // namespace lldb_private
+
+#endif // SOURCELOCATORDEBUGINFOD_H
More information about the lldb-commits
mailing list