Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/CompactUnwindSupport.cpp
213799 views
1
//=------- CompactUnwindSupport.cpp - Compact Unwind format support -------===//
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
// Compact Unwind support.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "CompactUnwindSupport.h"
14
15
#include "llvm/ADT/Sequence.h"
16
17
#define DEBUG_TYPE "jitlink"
18
19
namespace llvm {
20
namespace jitlink {
21
22
Error splitCompactUnwindBlocks(LinkGraph &G, Section &CompactUnwindSection,
23
size_t RecordSize) {
24
25
std::vector<Block *> OriginalBlocks(CompactUnwindSection.blocks().begin(),
26
CompactUnwindSection.blocks().end());
27
LLVM_DEBUG({
28
dbgs() << "In " << G.getName() << " splitting compact unwind section "
29
<< CompactUnwindSection.getName() << " containing "
30
<< OriginalBlocks.size() << " initial blocks...\n";
31
});
32
33
while (!OriginalBlocks.empty()) {
34
auto *B = OriginalBlocks.back();
35
OriginalBlocks.pop_back();
36
37
if (B->getSize() == 0) {
38
LLVM_DEBUG({
39
dbgs() << " Skipping empty block at "
40
<< formatv("{0:x16}", B->getAddress()) << "\n";
41
});
42
continue;
43
}
44
45
unsigned NumBlocks = B->getSize() / RecordSize;
46
47
LLVM_DEBUG({
48
dbgs() << " Splitting block at " << formatv("{0:x16}", B->getAddress())
49
<< " into " << NumBlocks << " compact unwind record(s)\n";
50
});
51
52
if (B->getSize() % RecordSize)
53
return make_error<JITLinkError>(
54
"Error splitting compact unwind record in " + G.getName() +
55
": block at " + formatv("{0:x}", B->getAddress()) + " has size " +
56
formatv("{0:x}", B->getSize()) +
57
" (not a multiple of CU record size of " +
58
formatv("{0:x}", RecordSize) + ")");
59
60
auto Blocks =
61
G.splitBlock(*B, map_range(seq(1U, NumBlocks), [=](Edge::OffsetT Idx) {
62
return Idx * RecordSize;
63
}));
64
65
for (auto *CURec : Blocks) {
66
bool AddedKeepAlive = false;
67
68
for (auto &E : CURec->edges()) {
69
if (E.getOffset() == 0) {
70
LLVM_DEBUG({
71
dbgs() << " Updating compact unwind record at "
72
<< CURec->getAddress() << " to point to "
73
<< (E.getTarget().hasName() ? *E.getTarget().getName()
74
: StringRef())
75
<< " (at " << E.getTarget().getAddress() << ")\n";
76
});
77
78
if (E.getTarget().isExternal())
79
return make_error<JITLinkError>(
80
"Error adding keep-alive edge for compact unwind record at " +
81
formatv("{0:x}", CURec->getAddress()) + ": target " +
82
*E.getTarget().getName() + " is an external symbol");
83
auto &TgtBlock = E.getTarget().getBlock();
84
auto &CURecSym =
85
G.addAnonymousSymbol(*CURec, 0, RecordSize, false, false);
86
TgtBlock.addEdge(Edge::KeepAlive, 0, CURecSym, 0);
87
AddedKeepAlive = true;
88
}
89
}
90
91
if (!AddedKeepAlive)
92
return make_error<JITLinkError>(
93
"Error adding keep-alive edge for compact unwind record at " +
94
formatv("{0:x}", CURec->getAddress()) +
95
": no outgoing target edge at offset 0");
96
}
97
}
98
99
return Error::success();
100
}
101
102
} // end namespace jitlink
103
} // end namespace llvm
104
105