#ifndef LLVM_DEBUGINFO_SYMBOLIZE_MARKUPFILTER_H
#define LLVM_DEBUGINFO_SYMBOLIZE_MARKUPFILTER_H
-#include "Markup.h"
-
-#include <map>
-
#include "llvm/ADT/DenseMap.h"
+#include "llvm/DebugInfo/Symbolize/Markup.h"
+#include "llvm/Object/BuildID.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
+#include <map>
namespace llvm {
namespace symbolize {
std::optional<uint64_t> parseAddr(StringRef Str) const;
std::optional<uint64_t> parseModuleID(StringRef Str) const;
std::optional<uint64_t> parseSize(StringRef Str) const;
- std::optional<SmallVector<uint8_t>> parseBuildID(StringRef Str) const;
+ object::BuildID parseBuildID(StringRef Str) const;
std::optional<std::string> parseMode(StringRef Str) const;
std::optional<PCType> parsePCType(StringRef Str) const;
std::optional<uint64_t> parseFrameNumber(StringRef Str) const;
class ObjectFile;
+/// Parses a build ID from a hex string.
+BuildID parseBuildID(StringRef Str);
+
/// Returns the build ID, if any, contained in the given object file.
-std::optional<BuildIDRef> getBuildID(const ObjectFile *Obj);
+BuildIDRef getBuildID(const ObjectFile *Obj);
/// BuildIDFetcher searches local cache directories for debug info.
class BuildIDFetcher {
}
if (!checkNumFields(Element, 4))
return std::nullopt;
- ASSIGN_OR_RETURN_NONE(SmallVector<uint8_t>, BuildID,
- parseBuildID(Element.Fields[3]));
+ SmallVector<uint8_t> BuildID = parseBuildID(Element.Fields[3]);
+ if (BuildID.empty())
+ return std::nullopt;
return Module{ID, Name.str(), std::move(BuildID)};
}
}
// Parse a build ID (%x in the spec).
-std::optional<SmallVector<uint8_t>>
-MarkupFilter::parseBuildID(StringRef Str) const {
- std::string Bytes;
- if (Str.empty() || Str.size() % 2 || !tryGetFromHex(Str, Bytes)) {
+object::BuildID MarkupFilter::parseBuildID(StringRef Str) const {
+ object::BuildID BID = llvm::object::parseBuildID(Str);
+ if (BID.empty())
reportTypeError(Str, "build ID");
- return std::nullopt;
- }
- ArrayRef<uint8_t> BuildID(reinterpret_cast<const uint8_t *>(Bytes.data()),
- Bytes.size());
- return SmallVector<uint8_t>(BuildID.begin(), BuildID.end());
+ return BID;
}
// Parses the mode string for an mmap element.
const ELFObjectFileBase *Obj,
const std::string &ArchName) {
auto BuildID = getBuildID(Obj);
- if (!BuildID)
- return nullptr;
- if (BuildID->size() < 2)
+ if (BuildID.size() < 2)
return nullptr;
std::string DebugBinaryPath;
- if (!getOrFindDebugBinary(*BuildID, DebugBinaryPath))
+ if (!getOrFindDebugBinary(BuildID, DebugBinaryPath))
return nullptr;
auto DbgObjOrErr = getOrCreateObject(DebugBinaryPath, ArchName);
if (!DbgObjOrErr) {
if (!Object)
continue;
- std::optional<BuildIDRef> ID = getBuildID(Object);
- if (!ID)
+ BuildIDRef ID = getBuildID(Object);
+ if (ID.empty())
continue;
- std::string IDString = buildIDToString(*ID);
+ std::string IDString = buildIDToString(ID);
if (Object->hasDebugInfo()) {
std::lock_guard<sys::RWMutex> DebugBinariesGuard(DebugBinariesMutex);
(void)DebugBinaries.try_emplace(IDString, std::move(FilePath));
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
-namespace llvm {
-namespace object {
+using namespace llvm;
+using namespace llvm::object;
namespace {
-template <typename ELFT>
-std::optional<BuildIDRef> getBuildID(const ELFFile<ELFT> &Obj) {
+template <typename ELFT> BuildIDRef getBuildID(const ELFFile<ELFT> &Obj) {
auto PhdrsOrErr = Obj.program_headers();
if (!PhdrsOrErr) {
consumeError(PhdrsOrErr.takeError());
} // namespace
-std::optional<BuildIDRef> getBuildID(const ObjectFile *Obj) {
+BuildID llvm::object::parseBuildID(StringRef Str) {
+ std::string Bytes;
+ if (!tryGetFromHex(Str, Bytes))
+ return {};
+ ArrayRef<uint8_t> BuildID(reinterpret_cast<const uint8_t *>(Bytes.data()),
+ Bytes.size());
+ return SmallVector<uint8_t>(BuildID.begin(), BuildID.end());
+}
+
+BuildIDRef llvm::object::getBuildID(const ObjectFile *Obj) {
if (auto *O = dyn_cast<ELFObjectFile<ELF32LE>>(Obj))
- return getBuildID(O->getELFFile());
+ return ::getBuildID(O->getELFFile());
if (auto *O = dyn_cast<ELFObjectFile<ELF32BE>>(Obj))
- return getBuildID(O->getELFFile());
+ return ::getBuildID(O->getELFFile());
if (auto *O = dyn_cast<ELFObjectFile<ELF64LE>>(Obj))
- return getBuildID(O->getELFFile());
+ return ::getBuildID(O->getELFFile());
if (auto *O = dyn_cast<ELFObjectFile<ELF64BE>>(Obj))
- return getBuildID(O->getELFFile());
+ return ::getBuildID(O->getELFFile());
return std::nullopt;
}
}
return std::nullopt;
}
-
-} // namespace object
-} // namespace llvm
static Expected<std::unique_ptr<BinaryCoverageReader>>
loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
StringRef CompilationDir = "",
- std::optional<object::BuildIDRef> *BinaryID = nullptr) {
+ object::BuildIDRef *BinaryID = nullptr) {
std::unique_ptr<ObjectFile> OF;
if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
// If we have a universal binary, try to look up the object for the
return std::move(Readers);
}
- std::optional<object::BuildIDRef> BinaryID;
+ object::BuildIDRef BinaryID;
auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch, CompilationDir,
BinaryIDs ? &BinaryID : nullptr);
if (!ReaderOrErr)
return ReaderOrErr.takeError();
Readers.push_back(std::move(ReaderOrErr.get()));
- if (BinaryID)
- BinaryIDs->push_back(*BinaryID);
+ if (!BinaryID.empty())
+ BinaryIDs->push_back(BinaryID);
return std::move(Readers);
}
Error RawMemProfReader::setupForSymbolization() {
auto *Object = cast<object::ObjectFile>(Binary.getBinary());
- auto BuildIdOr = object::getBuildID(Object);
- if (!BuildIdOr.has_value())
+ object::BuildIDRef BinaryId = object::getBuildID(Object);
+ if (BinaryId.empty())
return make_error<StringError>(Twine("No build id found in binary ") +
Binary.getBinary()->getFileName(),
inconvertibleErrorCode());
- llvm::ArrayRef<uint8_t> BinaryId = BuildIdOr.value();
int NumMatched = 0;
for (const auto &Entry : SegmentInfo) {
RUN: llvm-symbolizer --filter-markup < %t/log 2> %t.err
RUN: FileCheck %s -input-file=%t.err --match-full-lines
-CHECK-NOT: '0x4f'
-CHECK-NOT: '00'
-CHECK: error: expected address; found ''
-CHECK: error: expected address; found '42'
-CHECK: error: expected address; found '0xgg'
+CHECK-NOT: error: expected address; found '0x4f'
+CHECK-NOT: error: expected address; found '00'
+CHECK: error: expected address; found ''
+CHECK: error: expected address; found '42'
+CHECK: error: expected address; found '0xgg'
-CHECK-NOT: '0'
-CHECK: error: expected module ID; found ''
-CHECK: error: expected module ID; found '-1'
-CHECK-NOT: '077'
-CHECK: error: expected module ID; found '079'
-CHECK-NOT: '0xff'
-CHECK: error: expected module ID; found '0xfg'
-CHECK: error: expected module ID; found '0x'
+CHECK-NOT: error: expected module ID; found '0'
+CHECK: error: expected module ID; found ''
+CHECK: error: expected module ID; found '-1'
+CHECK-NOT: error: expected module ID; found '077'
+CHECK: error: expected module ID; found '079'
+CHECK-NOT: error: expected module ID; found '0xff'
+CHECK: error: expected module ID; found '0xfg'
+CHECK: error: expected module ID; found '0x'
-CHECK: error: expected build ID; found ''
-CHECK: error: expected build ID; found '0'
-CHECK-NOT: '0xff'
-CHECK: error: expected build ID; found 'fg'
+CHECK: error: expected build ID; found ''
+CHECK-NOT: error: expected build ID; found '0'
+CHECK-NOT: error: expected build ID; found '0xff'
+CHECK: error: expected build ID; found 'fg'
;--- log
{{{mmap:0x4f:1:unknown}}}
// Build ID. Returns std::nullopt if nothing was found.
static std::optional<OwningBinary<Binary>>
fetchBinaryByBuildID(const ObjectFile &Obj) {
- std::optional<object::BuildIDRef> BuildID = getBuildID(&Obj);
- if (!BuildID)
+ object::BuildIDRef BuildID = getBuildID(&Obj);
+ if (BuildID.empty())
return std::nullopt;
- std::optional<std::string> Path = BIDFetcher->fetch(*BuildID);
+ std::optional<std::string> Path = BIDFetcher->fetch(BuildID);
if (!Path)
return std::nullopt;
Expected<OwningBinary<Binary>> DebugBinary = createBinary(*Path);
static object::BuildID parseBuildIDArg(const opt::Arg *A) {
StringRef V(A->getValue());
- std::string Bytes;
- if (!tryGetFromHex(V, Bytes))
+ object::BuildID BID = parseBuildID(V);
+ if (BID.empty())
reportCmdLineError(A->getSpelling() + ": expected a build ID, but got '" +
V + "'");
- ArrayRef<uint8_t> BuildID(reinterpret_cast<const uint8_t *>(Bytes.data()),
- Bytes.size());
- return object::BuildID(BuildID.begin(), BuildID.end());
+ return BID;
}
void objdump::invalidArgValue(const opt::Arg *A) {
HTTPClient::initialize();
}
-static object::BuildID parseBuildID(StringRef Str) {
- std::string Bytes;
- if (!tryGetFromHex(Str, Bytes))
- return {};
- ArrayRef<uint8_t> BuildID(reinterpret_cast<const uint8_t *>(Bytes.data()),
- Bytes.size());
- return object::BuildID(BuildID.begin(), BuildID.end());
-}
-
static bool parseCommand(StringRef BinaryName, bool IsAddr2Line,
StringRef InputString, Command &Cmd,
std::string &ModuleName, object::BuildID &BuildID,