Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/Orc/Debugging/DebugInfoSupport.cpp
35294 views
1
//===--- DebugInfoSupport.cpp -- Utils for debug info support ---*- C++ -*-===//
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
// Utilities to preserve and parse debug info from LinkGraphs.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "llvm/ExecutionEngine/Orc/Debugging/DebugInfoSupport.h"
14
15
#include "llvm/Support/SmallVectorMemoryBuffer.h"
16
17
#define DEBUG_TYPE "orc"
18
19
using namespace llvm;
20
using namespace llvm::orc;
21
using namespace llvm::jitlink;
22
23
namespace {
24
static DenseSet<StringRef> DWARFSectionNames = {
25
#define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME, OPTION) \
26
StringRef(ELF_NAME),
27
#include "llvm/BinaryFormat/Dwarf.def"
28
#undef HANDLE_DWARF_SECTION
29
};
30
31
// We might be able to drop relocations to symbols that do end up
32
// being pruned by the linker, but for now we just preserve all
33
static void preserveDWARFSection(LinkGraph &G, Section &Sec) {
34
DenseMap<Block *, Symbol *> Preserved;
35
for (auto Sym : Sec.symbols()) {
36
if (Sym->isLive())
37
Preserved[&Sym->getBlock()] = Sym;
38
else if (!Preserved.count(&Sym->getBlock()))
39
Preserved[&Sym->getBlock()] = Sym;
40
}
41
for (auto Block : Sec.blocks()) {
42
auto &PSym = Preserved[Block];
43
if (!PSym)
44
PSym = &G.addAnonymousSymbol(*Block, 0, 0, false, true);
45
else if (!PSym->isLive())
46
PSym->setLive(true);
47
}
48
}
49
50
static SmallVector<char, 0> getSectionData(Section &Sec) {
51
SmallVector<char, 0> SecData;
52
SmallVector<Block *, 8> SecBlocks(Sec.blocks().begin(), Sec.blocks().end());
53
std::sort(SecBlocks.begin(), SecBlocks.end(), [](Block *LHS, Block *RHS) {
54
return LHS->getAddress() < RHS->getAddress();
55
});
56
// Convert back to what object file would have, one blob of section content
57
// Assumes all zerofill
58
// TODO handle alignment?
59
// TODO handle alignment offset?
60
for (auto *Block : SecBlocks) {
61
if (Block->isZeroFill())
62
SecData.resize(SecData.size() + Block->getSize(), 0);
63
else
64
SecData.append(Block->getContent().begin(), Block->getContent().end());
65
}
66
return SecData;
67
}
68
69
static void dumpDWARFContext(DWARFContext &DC) {
70
auto options = llvm::DIDumpOptions();
71
options.DumpType &= ~DIDT_UUID;
72
options.DumpType &= ~(1 << DIDT_ID_DebugFrame);
73
LLVM_DEBUG(DC.dump(dbgs(), options));
74
}
75
76
} // namespace
77
78
Error llvm::orc::preserveDebugSections(LinkGraph &G) {
79
if (!G.getTargetTriple().isOSBinFormatELF()) {
80
return make_error<StringError>(
81
"preserveDebugSections only supports ELF LinkGraphs!",
82
inconvertibleErrorCode());
83
}
84
for (auto &Sec : G.sections()) {
85
if (DWARFSectionNames.count(Sec.getName())) {
86
LLVM_DEBUG(dbgs() << "Preserving DWARF section " << Sec.getName()
87
<< "\n");
88
preserveDWARFSection(G, Sec);
89
}
90
}
91
return Error::success();
92
}
93
94
Expected<std::pair<std::unique_ptr<DWARFContext>,
95
StringMap<std::unique_ptr<MemoryBuffer>>>>
96
llvm::orc::createDWARFContext(LinkGraph &G) {
97
if (!G.getTargetTriple().isOSBinFormatELF()) {
98
return make_error<StringError>(
99
"createDWARFContext only supports ELF LinkGraphs!",
100
inconvertibleErrorCode());
101
}
102
StringMap<std::unique_ptr<MemoryBuffer>> DWARFSectionData;
103
for (auto &Sec : G.sections()) {
104
if (DWARFSectionNames.count(Sec.getName())) {
105
auto SecData = getSectionData(Sec);
106
auto Name = Sec.getName();
107
// DWARFContext expects the section name to not start with a dot
108
Name.consume_front(".");
109
LLVM_DEBUG(dbgs() << "Creating DWARFContext section " << Name
110
<< " with size " << SecData.size() << "\n");
111
DWARFSectionData[Name] =
112
std::make_unique<SmallVectorMemoryBuffer>(std::move(SecData));
113
}
114
}
115
auto Ctx =
116
DWARFContext::create(DWARFSectionData, G.getPointerSize(),
117
G.getEndianness() == llvm::endianness::little);
118
dumpDWARFContext(*Ctx);
119
return std::make_pair(std::move(Ctx), std::move(DWARFSectionData));
120
}
121
122