Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Object/BuildID.cpp
35232 views
1
//===- llvm/Object/BuildID.cpp - Build ID ---------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
///
9
/// \file
10
/// This file defines a library for handling Build IDs and using them to find
11
/// debug info.
12
///
13
//===----------------------------------------------------------------------===//
14
15
#include "llvm/Object/BuildID.h"
16
17
#include "llvm/Object/ELFObjectFile.h"
18
#include "llvm/Support/FileSystem.h"
19
#include "llvm/Support/Path.h"
20
21
using namespace llvm;
22
using namespace llvm::object;
23
24
namespace {
25
26
template <typename ELFT> BuildIDRef getBuildID(const ELFFile<ELFT> &Obj) {
27
auto PhdrsOrErr = Obj.program_headers();
28
if (!PhdrsOrErr) {
29
consumeError(PhdrsOrErr.takeError());
30
return {};
31
}
32
for (const auto &P : *PhdrsOrErr) {
33
if (P.p_type != ELF::PT_NOTE)
34
continue;
35
Error Err = Error::success();
36
for (auto N : Obj.notes(P, Err))
37
if (N.getType() == ELF::NT_GNU_BUILD_ID &&
38
N.getName() == ELF::ELF_NOTE_GNU)
39
return N.getDesc(P.p_align);
40
consumeError(std::move(Err));
41
}
42
return {};
43
}
44
45
} // namespace
46
47
BuildID llvm::object::parseBuildID(StringRef Str) {
48
std::string Bytes;
49
if (!tryGetFromHex(Str, Bytes))
50
return {};
51
ArrayRef<uint8_t> BuildID(reinterpret_cast<const uint8_t *>(Bytes.data()),
52
Bytes.size());
53
return SmallVector<uint8_t>(BuildID.begin(), BuildID.end());
54
}
55
56
BuildIDRef llvm::object::getBuildID(const ObjectFile *Obj) {
57
if (auto *O = dyn_cast<ELFObjectFile<ELF32LE>>(Obj))
58
return ::getBuildID(O->getELFFile());
59
if (auto *O = dyn_cast<ELFObjectFile<ELF32BE>>(Obj))
60
return ::getBuildID(O->getELFFile());
61
if (auto *O = dyn_cast<ELFObjectFile<ELF64LE>>(Obj))
62
return ::getBuildID(O->getELFFile());
63
if (auto *O = dyn_cast<ELFObjectFile<ELF64BE>>(Obj))
64
return ::getBuildID(O->getELFFile());
65
return std::nullopt;
66
}
67
68
std::optional<std::string> BuildIDFetcher::fetch(BuildIDRef BuildID) const {
69
auto GetDebugPath = [&](StringRef Directory) {
70
SmallString<128> Path{Directory};
71
sys::path::append(Path, ".build-id",
72
llvm::toHex(BuildID[0], /*LowerCase=*/true),
73
llvm::toHex(BuildID.slice(1), /*LowerCase=*/true));
74
Path += ".debug";
75
return Path;
76
};
77
if (DebugFileDirectories.empty()) {
78
SmallString<128> Path = GetDebugPath(
79
#if defined(__NetBSD__)
80
// Try /usr/libdata/debug/.build-id/../...
81
"/usr/libdata/debug"
82
#else
83
// Try /usr/lib/debug/.build-id/../...
84
"/usr/lib/debug"
85
#endif
86
);
87
if (llvm::sys::fs::exists(Path))
88
return std::string(Path);
89
} else {
90
for (const auto &Directory : DebugFileDirectories) {
91
// Try <debug-file-directory>/.build-id/../...
92
SmallString<128> Path = GetDebugPath(Directory);
93
if (llvm::sys::fs::exists(Path))
94
return std::string(Path);
95
}
96
}
97
return std::nullopt;
98
}
99
100