aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Debuginfod/Debuginfod.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2023-02-11 12:38:11 +0000
commite3b557809604d036af6e00c60f012c2025b59a5e (patch)
tree8a11ba2269a3b669601e2fd41145b174008f4da8 /llvm/lib/Debuginfod/Debuginfod.cpp
parent08e8dd7b9db7bb4a9de26d44c1cbfd24e869c014 (diff)
downloadsrc-e3b557809604d036af6e00c60f012c2025b59a5e.tar.gz
src-e3b557809604d036af6e00c60f012c2025b59a5e.zip
Vendor import of llvm-project main llvmorg-16-init-18548-gb0daacf58f41,vendor/llvm-project/llvmorg-16-init-18548-gb0daacf58f41
the last commit before the upstream release/17.x branch was created.
Diffstat (limited to 'llvm/lib/Debuginfod/Debuginfod.cpp')
-rw-r--r--llvm/lib/Debuginfod/Debuginfod.cpp98
1 files changed, 66 insertions, 32 deletions
diff --git a/llvm/lib/Debuginfod/Debuginfod.cpp b/llvm/lib/Debuginfod/Debuginfod.cpp
index ef4e11ca38e6..026f118bbf5b 100644
--- a/llvm/lib/Debuginfod/Debuginfod.cpp
+++ b/llvm/lib/Debuginfod/Debuginfod.cpp
@@ -22,26 +22,31 @@
//===----------------------------------------------------------------------===//
#include "llvm/Debuginfod/Debuginfod.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/Symbolize/Symbolize.h"
#include "llvm/Debuginfod/HTTPClient.h"
-#include "llvm/Object/Binary.h"
+#include "llvm/Object/BuildID.h"
#include "llvm/Object/ELFObjectFile.h"
-#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/CachePruning.h"
#include "llvm/Support/Caching.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/xxhash.h"
#include <atomic>
+#include <thread>
namespace llvm {
+
+using llvm::object::BuildIDRef;
+
static std::string uniqueKey(llvm::StringRef S) { return utostr(xxHash64(S)); }
// Returns a binary BuildID as a normalized hex string.
@@ -166,6 +171,44 @@ Error StreamedHTTPResponseHandler::handleBodyChunk(StringRef BodyChunk) {
return Error::success();
}
+// An over-accepting simplification of the HTTP RFC 7230 spec.
+static bool isHeader(StringRef S) {
+ StringRef Name;
+ StringRef Value;
+ std::tie(Name, Value) = S.split(':');
+ if (Name.empty() || Value.empty())
+ return false;
+ return all_of(Name, [](char C) { return llvm::isPrint(C) && C != ' '; }) &&
+ all_of(Value, [](char C) { return llvm::isPrint(C) || C == '\t'; });
+}
+
+static SmallVector<std::string, 0> getHeaders() {
+ const char *Filename = getenv("DEBUGINFOD_HEADERS_FILE");
+ if (!Filename)
+ return {};
+ ErrorOr<std::unique_ptr<MemoryBuffer>> HeadersFile =
+ MemoryBuffer::getFile(Filename, /*IsText=*/true);
+ if (!HeadersFile)
+ return {};
+
+ SmallVector<std::string, 0> Headers;
+ uint64_t LineNumber = 0;
+ for (StringRef Line : llvm::split((*HeadersFile)->getBuffer(), '\n')) {
+ LineNumber++;
+ if (!Line.empty() && Line.back() == '\r')
+ Line = Line.drop_back();
+ if (!isHeader(Line)) {
+ if (!all_of(Line, llvm::isSpace))
+ WithColor::warning()
+ << "could not parse debuginfod header: " << Filename << ':'
+ << LineNumber << '\n';
+ continue;
+ }
+ Headers.emplace_back(Line);
+ }
+ return Headers;
+}
+
Expected<std::string> getCachedOrDownloadArtifact(
StringRef UniqueKey, StringRef UrlPath, StringRef CacheDirectoryPath,
ArrayRef<StringRef> DebuginfodUrls, std::chrono::milliseconds Timeout) {
@@ -181,7 +224,7 @@ Expected<std::string> getCachedOrDownloadArtifact(
FileCache Cache = *CacheOrErr;
// We choose an arbitrary Task parameter as we do not make use of it.
unsigned Task = 0;
- Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, UniqueKey);
+ Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, UniqueKey, "");
if (!CacheAddStreamOrErr)
return CacheAddStreamOrErr.takeError();
AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
@@ -208,9 +251,10 @@ Expected<std::string> getCachedOrDownloadArtifact(
// Perform the HTTP request and if successful, write the response body to
// the cache.
- StreamedHTTPResponseHandler Handler([&]() { return CacheAddStream(Task); },
- Client);
+ StreamedHTTPResponseHandler Handler(
+ [&]() { return CacheAddStream(Task, ""); }, Client);
HTTPRequest Request(ArtifactUrl);
+ Request.Headers = getHeaders();
Error Err = Client.perform(Request, Handler);
if (Err)
return std::move(Err);
@@ -300,16 +344,6 @@ Error DebuginfodCollection::updateForever(std::chrono::milliseconds Interval) {
llvm_unreachable("updateForever loop should never end");
}
-static bool isDebugBinary(object::ObjectFile *Object) {
- // TODO: handle PDB debuginfo
- std::unique_ptr<DWARFContext> Context = DWARFContext::create(
- *Object, DWARFContext::ProcessDebugRelocations::Process);
- const DWARFObject &DObj = Context->getDWARFObj();
- unsigned NumSections = 0;
- DObj.forEachInfoSections([&](const DWARFSection &S) { NumSections++; });
- return NumSections;
-}
-
static bool hasELFMagic(StringRef FilePath) {
file_magic Type;
std::error_code EC = identify_magic(FilePath, Type);
@@ -369,17 +403,17 @@ Error DebuginfodCollection::findBinaries(StringRef Path) {
if (!Object)
continue;
- Optional<BuildIDRef> ID = symbolize::getBuildID(Object);
+ std::optional<BuildIDRef> ID = getBuildID(Object);
if (!ID)
continue;
- std::string IDString = buildIDToString(ID.value());
- if (isDebugBinary(Object)) {
+ std::string IDString = buildIDToString(*ID);
+ if (Object->hasDebugInfo()) {
std::lock_guard<sys::RWMutex> DebugBinariesGuard(DebugBinariesMutex);
- DebugBinaries[IDString] = FilePath;
+ (void)DebugBinaries.try_emplace(IDString, std::move(FilePath));
} else {
std::lock_guard<sys::RWMutex> BinariesGuard(BinariesMutex);
- Binaries[IDString] = FilePath;
+ (void)Binaries.try_emplace(IDString, std::move(FilePath));
}
}
});
@@ -391,7 +425,7 @@ Error DebuginfodCollection::findBinaries(StringRef Path) {
return Error::success();
}
-Expected<Optional<std::string>>
+Expected<std::optional<std::string>>
DebuginfodCollection::getBinaryPath(BuildIDRef ID) {
Log.push("getting binary path of ID " + buildIDToString(ID));
std::shared_lock<sys::RWMutex> Guard(BinariesMutex);
@@ -400,10 +434,10 @@ DebuginfodCollection::getBinaryPath(BuildIDRef ID) {
std::string Path = Loc->getValue();
return Path;
}
- return None;
+ return std::nullopt;
}
-Expected<Optional<std::string>>
+Expected<std::optional<std::string>>
DebuginfodCollection::getDebugBinaryPath(BuildIDRef ID) {
Log.push("getting debug binary path of ID " + buildIDToString(ID));
std::shared_lock<sys::RWMutex> Guard(DebugBinariesMutex);
@@ -412,16 +446,16 @@ DebuginfodCollection::getDebugBinaryPath(BuildIDRef ID) {
std::string Path = Loc->getValue();
return Path;
}
- return None;
+ return std::nullopt;
}
Expected<std::string> DebuginfodCollection::findBinaryPath(BuildIDRef ID) {
{
// Check collection; perform on-demand update if stale.
- Expected<Optional<std::string>> PathOrErr = getBinaryPath(ID);
+ Expected<std::optional<std::string>> PathOrErr = getBinaryPath(ID);
if (!PathOrErr)
return PathOrErr.takeError();
- Optional<std::string> Path = *PathOrErr;
+ std::optional<std::string> Path = *PathOrErr;
if (!Path) {
Expected<bool> UpdatedOrErr = updateIfStale();
if (!UpdatedOrErr)
@@ -435,7 +469,7 @@ Expected<std::string> DebuginfodCollection::findBinaryPath(BuildIDRef ID) {
}
}
if (Path)
- return Path.value();
+ return *Path;
}
// Try federation.
@@ -449,10 +483,10 @@ Expected<std::string> DebuginfodCollection::findBinaryPath(BuildIDRef ID) {
Expected<std::string> DebuginfodCollection::findDebugBinaryPath(BuildIDRef ID) {
// Check collection; perform on-demand update if stale.
- Expected<Optional<std::string>> PathOrErr = getDebugBinaryPath(ID);
+ Expected<std::optional<std::string>> PathOrErr = getDebugBinaryPath(ID);
if (!PathOrErr)
return PathOrErr.takeError();
- Optional<std::string> Path = *PathOrErr;
+ std::optional<std::string> Path = *PathOrErr;
if (!Path) {
Expected<bool> UpdatedOrErr = updateIfStale();
if (!UpdatedOrErr)
@@ -466,7 +500,7 @@ Expected<std::string> DebuginfodCollection::findDebugBinaryPath(BuildIDRef ID) {
}
}
if (Path)
- return Path.value();
+ return *Path;
// Try federation.
return getCachedOrDownloadDebuginfo(ID);
@@ -484,7 +518,7 @@ DebuginfodServer::DebuginfodServer(DebuginfodLog &Log,
{404, "text/plain", "Build ID is not a hex string\n"});
return;
}
- BuildID ID(IDString.begin(), IDString.end());
+ object::BuildID ID(IDString.begin(), IDString.end());
Expected<std::string> PathOrErr = Collection.findDebugBinaryPath(ID);
if (Error Err = PathOrErr.takeError()) {
consumeError(std::move(Err));
@@ -502,7 +536,7 @@ DebuginfodServer::DebuginfodServer(DebuginfodLog &Log,
{404, "text/plain", "Build ID is not a hex string\n"});
return;
}
- BuildID ID(IDString.begin(), IDString.end());
+ object::BuildID ID(IDString.begin(), IDString.end());
Expected<std::string> PathOrErr = Collection.findBinaryPath(ID);
if (Error Err = PathOrErr.takeError()) {
consumeError(std::move(Err));