LLVM 22.0.0git
CompactUnwindSupport.cpp
Go to the documentation of this file.
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
14
15#include "llvm/ADT/Sequence.h"
16
17#define DEBUG_TYPE "jitlink"
18
19namespace llvm {
20namespace jitlink {
21
23 size_t RecordSize) {
24
25 std::vector<Block *> OriginalBlocks(CompactUnwindSection.blocks().begin(),
26 CompactUnwindSection.blocks().end());
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) {
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
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) {
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
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
DenseMap< Block *, BlockRelaxAux > Blocks
Definition: ELF_riscv.cpp:507
#define G(x, y, z)
Definition: MD5.cpp:56
Provides some synthesis utilities to produce sequences of values.
#define LLVM_DEBUG(...)
Definition: Debug.h:119
Lightweight error class with error context and mandatory checking.
Definition: Error.h:159
static ErrorSuccess success()
Create a success value.
Definition: Error.h:336
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:154
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto map_range(ContainerTy &&C, FuncTy F)
Definition: STLExtras.h:386
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition: Sequence.h:305