================ @@ -0,0 +1,142 @@ +//===-- SymbolLocatorDebuginfod.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 "SymbolLocatorDebuginfod.h" + +#include "lldb/Core/PluginManager.h" +#include "lldb/Utility/Args.h" + +#include "llvm/Debuginfod/Debuginfod.h" +#include "llvm/Debuginfod/HTTPClient.h" + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(SymbolLocatorDebuginfod) + +namespace { + +#define LLDB_PROPERTIES_symbollocatordebuginfod +#include "SymbolLocatorDebuginfodProperties.inc" + +enum { +#define LLDB_PROPERTIES_symbollocatordebuginfod +#include "SymbolLocatorDebuginfodPropertiesEnum.inc" +}; + +class PluginProperties : public Properties { +public: + static llvm::StringRef GetSettingName() { + return SymbolLocatorDebuginfod::GetPluginNameStatic(); + } + + PluginProperties() { + m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName()); + m_collection_sp->Initialize(g_symbollocatordebuginfod_properties); + + // We need to read the default value first to read the environment variable. + llvm::SmallVector<llvm::StringRef> urls = llvm::getDefaultDebuginfodUrls(); + Args arg_urls{urls}; + m_collection_sp->SetPropertyAtIndexFromArgs(ePropertyServerURLs, arg_urls); + + m_collection_sp->SetValueChangedCallback( + ePropertyServerURLs, [this] { ServerURLsChangedCallback(); }); + } + + Args GetDebugInfoDURLs() const { + Args urls; + m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyServerURLs, urls); + return urls; + } + +private: + void ServerURLsChangedCallback() { + Args urls = GetDebugInfoDURLs(); + llvm::SmallVector<llvm::StringRef> dbginfod_urls; + llvm::transform(urls, dbginfod_urls.end(), + [](const auto &obj) { return obj.ref(); }); + llvm::setDefaultDebuginfodUrls(dbginfod_urls); + } +}; + +} // namespace + +static PluginProperties &GetGlobalPluginProperties() { + static PluginProperties g_settings; + return g_settings; +} + +SymbolLocatorDebuginfod::SymbolLocatorDebuginfod() : SymbolLocator() {} + +void SymbolLocatorDebuginfod::Initialize() { + static llvm::once_flag g_once_flag; + + llvm::call_once(g_once_flag, []() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance, + LocateExecutableObjectFile, LocateExecutableSymbolFile, nullptr, + nullptr, SymbolLocatorDebuginfod::DebuggerInitialize); + llvm::HTTPClient::initialize(); + }); +} + +void SymbolLocatorDebuginfod::DebuggerInitialize(Debugger &debugger) { + if (!PluginManager::GetSettingForSymbolLocatorPlugin( + debugger, PluginProperties::GetSettingName())) { + const bool is_global_setting = true; + PluginManager::CreateSettingForSymbolLocatorPlugin( + debugger, GetGlobalPluginProperties().GetValueProperties(), + "Properties for the Debuginfod Symbol Locator plug-in.", + is_global_setting); + } +} + +void SymbolLocatorDebuginfod::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); + llvm::HTTPClient::cleanup(); +} + +llvm::StringRef SymbolLocatorDebuginfod::GetPluginDescriptionStatic() { + return "Debuginfod symbol locator."; +} + +SymbolLocator *SymbolLocatorDebuginfod::CreateInstance() { + return new SymbolLocatorDebuginfod(); +} + +std::optional<ModuleSpec> SymbolLocatorDebuginfod::LocateExecutableObjectFile( + const ModuleSpec &module_spec) { + const UUID &module_uuid = module_spec.GetUUID(); + if (module_uuid.IsValid() && llvm::canUseDebuginfod()) { + llvm::object::BuildID build_id(module_uuid.GetBytes()); + llvm::Expected<std::string> result = + llvm::getCachedOrDownloadExecutable(build_id); + if (result) + return FileSpec(*result); + // An error here should be logged as a failure in the Debuginfod library, + // so just consume it here + consumeError(result.takeError()); + } + return {}; +} + +std::optional<FileSpec> SymbolLocatorDebuginfod::LocateExecutableSymbolFile( + const ModuleSpec &module_spec, const FileSpecList &default_search_paths) { + const UUID &module_uuid = module_spec.GetUUID(); + if (module_uuid.IsValid() && llvm::canUseDebuginfod()) { + llvm::object::BuildID build_id(module_uuid.GetBytes()); + llvm::Expected<std::string> result = + llvm::getCachedOrDownloadDebuginfo(build_id); + if (result) + return FileSpec(*result); + // An error here should be logged as a failure in the Debuginfod library, + // so just consume it here + consumeError(result.takeError()); + } ---------------- kevinfrei wrote:
Not quite: They're calling different functions (llvm::getCachedOrDownloadDebugInfo vs. llvm::getCachedOrDownloadExecutable) but I could factor that out and pass the function pointers instead. https://github.com/llvm/llvm-project/pull/70996 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits